C (프로그래밍 언어) 편집하기


편집하면 당신의 IP 주소가 공개적으로 기록됩니다. 계정을 만들고 로그인하면 편집 시 사용자 이름만 보이며, 위키 이용에 여러 가지 편의가 주어집니다.

편집을 취소할 수 있습니다. 이 편집을 되돌리려면 아래의 바뀐 내용을 확인한 후 게시해주세요.

최신판 당신의 편집
46번째 줄: 46번째 줄:
ANSI C에비해 아래와 같은 기능이 추가되었다.
ANSI C에비해 아래와 같은 기능이 추가되었다.
====inline function 추가====
====inline function 추가====
<syntaxhighlight lang="c">  
<source lang="c">  
inline int func(int n){
inline int func(int n){
     return n + 2;
     return n + 2;
53번째 줄: 53번째 줄:
인라인 함수는 C++에서는 일반적으로 사용하는 문법적으로 문법적으로는 함수의 형태를 띠고 있지만, 컴파일할 때 콜스텍을 이용하여 호출하는 함수와 달리 인라인 함수의 내용을 해당 함수가 호출된 위치에 치환하는 형태로 동작한다.
인라인 함수는 C++에서는 일반적으로 사용하는 문법적으로 문법적으로는 함수의 형태를 띠고 있지만, 컴파일할 때 콜스텍을 이용하여 호출하는 함수와 달리 인라인 함수의 내용을 해당 함수가 호출된 위치에 치환하는 형태로 동작한다.
ANSI C에서는 이러한 기능을 제공하지 않아. 아래와 같은 매크로 함수를 사용하여 해당 기능을 사용했었다.
ANSI C에서는 이러한 기능을 제공하지 않아. 아래와 같은 매크로 함수를 사용하여 해당 기능을 사용했었다.
<syntaxhighlight lang="c">
<source lang="c">
#define func(n) ((n) + 2)
#define func(n) ((n) + 2)
</syntaxhighlight>
</syntaxhighlight>
60번째 줄: 60번째 줄:
====변수의 선언이 블록의 처음에 제한되지 않음====
====변수의 선언이 블록의 처음에 제한되지 않음====
ANSI C의 경우 모든 변수는 반드시 블록의 처음부분 (다른 함수가 호출되기 이전)에 선언하지 않으면 컴파일 에러가 발생하였다. C99에서는 이러한 제한을 없애고, 블록의 어디에서든 변수를 선언하여 사용할 수 있도록 하였다.
ANSI C의 경우 모든 변수는 반드시 블록의 처음부분 (다른 함수가 호출되기 이전)에 선언하지 않으면 컴파일 에러가 발생하였다. C99에서는 이러한 제한을 없애고, 블록의 어디에서든 변수를 선언하여 사용할 수 있도록 하였다.
<syntaxhighlight lang="c">
<source lang="c">
int foo()
int foo()
{
{
70번째 줄: 70번째 줄:
====복소수를 나타내기 위한 complex 자료형 등 새로운 자료형 도입====
====복소수를 나타내기 위한 complex 자료형 등 새로운 자료형 도입====
아래와 같은 형태로 복소수의 표현과 연산이 가능하다.
아래와 같은 형태로 복소수의 표현과 연산이 가능하다.
<syntaxhighlight lang="c">
<source lang="c">
#include <complex.h>   
#include <complex.h>   
int foo()  
int foo()  
88번째 줄: 88번째 줄:
ANSI C에서는 배열의 선언시 배열 길이를 반드시 상수로만 사용할 수 있었다.
ANSI C에서는 배열의 선언시 배열 길이를 반드시 상수로만 사용할 수 있었다.
C99에서는 이러한 제한이 사라져 가변길이 배열의 선언이 가능하다.
C99에서는 이러한 제한이 사라져 가변길이 배열의 선언이 가능하다.
<syntaxhighlight lang="c">
<source lang="c">
  int arr1[123]; //ansi C에서 정상동작
  int arr1[123]; //ansi C에서 정상동작
  int length = 10;
  int length = 10;
101번째 줄: 101번째 줄:
====지정된 이니셜라이저 지원====
====지정된 이니셜라이저 지원====
배열의 초기화가 아래와 같이 이루어질 수 있다.
배열의 초기화가 아래와 같이 이루어질 수 있다.
<syntaxhighlight lang="c">
<source lang="c">
  int a[6] = { [4] = 29, [2] = 15 };  
  int a[6] = { [4] = 29, [2] = 15 };  
  int b[6] = { 0,0,15,0,29,0 };
  int b[6] = { 0,0,15,0,29,0 };
107번째 줄: 107번째 줄:
====가변인수 매크로====
====가변인수 매크로====
define 매크로 함수에 가변인자가 들어갈 수 있게 되었다.
define 매크로 함수에 가변인자가 들어갈 수 있게 되었다.
<syntaxhighlight lang="c">
<source lang="c">
  #define FN(a,...) printf(a,_VA_ARGS_);
  #define FN(a,...) printf(a,_VA_ARGS_);
</syntaxhighlight>
</syntaxhighlight>
====컴파운드리터럴====
====컴파운드리터럴====
복합상수의 지정이 가능해졌다.
복합상수의 지정이 가능해졌다.
<syntaxhighlight lang="c">
<source lang="c">
  int *p = (int [3]) {1,2,3};
  int *p = (int [3]) {1,2,3};
</syntaxhighlight>
</syntaxhighlight>
127번째 줄: 127번째 줄:
* 저장 가능한 수의 범위는 2를 자료형의 비트 수로 제곱하면 나온다. short의 비트는 16비트 2<sup>16</sup>=65536 양수 음수로 나누면 -32768 ~ 32767 이 범위에 들어가는 숫자만을 저장할 수가 있다. short 앞에 unsigned를 입력하면 0에서 65535에 해당하는 숫자를 저장할 수 있는 자료형이 선언된다.
* 저장 가능한 수의 범위는 2를 자료형의 비트 수로 제곱하면 나온다. short의 비트는 16비트 2<sup>16</sup>=65536 양수 음수로 나누면 -32768 ~ 32767 이 범위에 들어가는 숫자만을 저장할 수가 있다. short 앞에 unsigned를 입력하면 0에서 65535에 해당하는 숫자를 저장할 수 있는 자료형이 선언된다.
* char: 하나의 문자를 저장한다. 비트 수는 8비트로 1바이트{{취소선|그러면 글자 여러 개는 어떻게 저장하는데?}} {{취소선|다 방법이 있음 아래에서 보셈}}
* char: 하나의 문자를 저장한다. 비트 수는 8비트로 1바이트{{취소선|그러면 글자 여러 개는 어떻게 저장하는데?}} {{취소선|다 방법이 있음 아래에서 보셈}}
<syntaxhighlight lang="c">
<source lang="c">
char c = 'a';
char c = 'a';
</syntaxhighlight>
</syntaxhighlight>
* short : 작은 정수를 저장한다. 비트 수는 16비트로 2바이트
* short : 작은 정수를 저장한다. 비트 수는 16비트로 2바이트
<syntaxhighlight lang="c">
<source lang="c">
short x = 3;
short x = 3;
</syntaxhighlight>
</syntaxhighlight>
* int : 정수를 저장한다. 비트 수는 32비트로 4바이트 <ref>int 자료형은 short, long, long long과는 다르게 CPU에서 한번에 처리할 수 있는 단위인 워드의 크기에 따라 달라지는데 16비트 CPU면 16비트 32비트 CPU면 32비트</ref><ref>{{취소선|그럼 64비트면 64비트임? 아마 32비트를 확장시킨 x86_64기 때문에 32비트를 유지하는가보다.}}</ref>
* int : 정수를 저장한다. 비트 수는 32비트로 4바이트 <ref>int 자료형은 short, long, long long과는 다르게 CPU에서 한번에 처리할 수 있는 단위인 워드의 크기에 따라 달라지는데 16비트 CPU면 16비트 32비트 CPU면 32비트</ref><ref>{{취소선|그럼 64비트면 64비트임? 아마 32비트를 확장시킨 x86_64기 때문에 32비트를 유지하는가보다.}}</ref>
<syntaxhighlight lang="c">
<source lang="c">
int x = 4;
int x = 4;
</syntaxhighlight>
</syntaxhighlight>
* long : 정수를 저장한다. 비트 수는 32비트로 4바이트 CPU마다 int와 long의 크기가 다르기도 하지만 대부분 같다.
* long : 정수를 저장한다. 비트 수는 32비트로 4바이트 CPU마다 int와 long의 크기가 다르기도 하지만 대부분 같다.
<syntaxhighlight lang="c">
<source lang="c">
long x = 9;
long x = 9;
</syntaxhighlight>
</syntaxhighlight>
* long long : 큰 정수를 저장한다. 비트 수는 64비트로 8바이트
* long long : 큰 정수를 저장한다. 비트 수는 64비트로 8바이트
<syntaxhighlight lang="c">
<source lang="c">
long long x = 9;
long long x = 9;
</syntaxhighlight>
</syntaxhighlight>
* float : 작은 실수를 저장한다. 비트 수는 32비트
* float : 작은 실수를 저장한다. 비트 수는 32비트
<syntaxhighlight lang="c">
<source lang="c">
float x = 3.141592;
float x = 3.141592;
</syntaxhighlight>
</syntaxhighlight>
* double :  큰 실수를 저장한다. 비트 수는 64비트
* double :  큰 실수를 저장한다. 비트 수는 64비트
<syntaxhighlight lang="c">
<source lang="c">
double x = 3.141592597;
double x = 3.141592597;
</syntaxhighlight>
</syntaxhighlight>
157번째 줄: 157번째 줄:
아래는 배열을 이용해 여러 개의 값을 한번에 저장하는 방법이다.
아래는 배열을 이용해 여러 개의 값을 한번에 저장하는 방법이다.
* char x[] : 문자열을 저장한다. 대괄호 안에 숫자를 넣어서 들어갈 수 있는 문자 개수를 정해주기도 한다. 4를 입력하면 3개를 저장할 수 있다.
* char x[] : 문자열을 저장한다. 대괄호 안에 숫자를 넣어서 들어갈 수 있는 문자 개수를 정해주기도 한다. 4를 입력하면 3개를 저장할 수 있다.
<syntaxhighlight lang="c">
<source lang="c">
char x[] =  "Hello";
char x[] =  "Hello";
</syntaxhighlight>
</syntaxhighlight>
165번째 줄: 165번째 줄:
*반복적으로 쓰이는 코드를 짧은 키워드로 불러 쓸 수 있도록 하는 기능{{취소선|제대로된 정의와는 일억오천만광년정도 떨어져 있다.}}
*반복적으로 쓰이는 코드를 짧은 키워드로 불러 쓸 수 있도록 하는 기능{{취소선|제대로된 정의와는 일억오천만광년정도 떨어져 있다.}}
* {{취소선|인자를 가지고 특정 어드레스 주소로 이동할 수 있도록 하는 기능. 스택 추가는 덤.}}
* {{취소선|인자를 가지고 특정 어드레스 주소로 이동할 수 있도록 하는 기능. 스택 추가는 덤.}}
<syntaxhighlight lang="c">
<source lang="c">
//----------------------여기서부터
//----------------------여기서부터
void func(int a)
void func(int a)
185번째 줄: 185번째 줄:
   a : 3
   a : 3


<syntaxhighlight lang="c">
<source lang="c">
void func(int a)
void func(int a)
{
{
195번째 줄: 195번째 줄:
void func(int b, char ch)처럼 쓰면 정수형 변수 b, 문자 정수형 변수 ch를 정해줄 수 있다.
void func(int b, char ch)처럼 쓰면 정수형 변수 b, 문자 정수형 변수 ch를 정해줄 수 있다.


<syntaxhighlight lang="c">
<source lang="c">
void //func(int a)
void //func(int a)
</syntaxhighlight>
</syntaxhighlight>
217번째 줄: 217번째 줄:
*소괄호 안의 값을 확인하여 0이면 그냥 지나가고 0이 아니면, 블록 안의 코드를 실행하는 문법. {{취소선|조건을 검사하는 기능같은거 없다.}}
*소괄호 안의 값을 확인하여 0이면 그냥 지나가고 0이 아니면, 블록 안의 코드를 실행하는 문법. {{취소선|조건을 검사하는 기능같은거 없다.}}
*평범한 사용법
*평범한 사용법
<syntaxhighlight lang="c">
<source lang="c">
if(0)
if(0)
{
{
228번째 줄: 228번째 줄:
</syntaxhighlight>
</syntaxhighlight>
*비범한 사용법
*비범한 사용법
<syntaxhighlight lang="c">
<source lang="c">
int a = 10;
int a = 10;
if(a - 10)
if(a - 10)
238번째 줄: 238번째 줄:
** C에서 1 == 1 -> 1이고, 1 == 2 -> 0 이다.
** C에서 1 == 1 -> 1이고, 1 == 2 -> 0 이다.
** 1 < 2 -> 1이고, 1 > 2 -> 0이다.  {{취소선|어떻게 되먹은 산수지...?}} <ref>산수라기 보다는, 논리에 가깝다. 진실일때 1을 출력하고, 거짓일때 0을 출력한다고 가정하자, 1==2는 "1과 2가 같다"라는 말이므로 거짓이 된다. 그러므로 0을 출력한다. 반대로, 1==1은 1은 1이다라는 진실이므로 1을 출력한다. 그리고 1보다는 2가 크므로 진실, 1을 출력하고, 1이 2보다 큰것은 거짓이므로 0을 출력한다.</ref>
** 1 < 2 -> 1이고, 1 > 2 -> 0이다.  {{취소선|어떻게 되먹은 산수지...?}} <ref>산수라기 보다는, 논리에 가깝다. 진실일때 1을 출력하고, 거짓일때 0을 출력한다고 가정하자, 1==2는 "1과 2가 같다"라는 말이므로 거짓이 된다. 그러므로 0을 출력한다. 반대로, 1==1은 1은 1이다라는 진실이므로 1을 출력한다. 그리고 1보다는 2가 크므로 진실, 1을 출력하고, 1이 2보다 큰것은 거짓이므로 0을 출력한다.</ref>
<syntaxhighlight lang="c">
<source lang="c">
int a = 10;
int a = 10;
if(a < 11)
if(a < 11)
248번째 줄: 248번째 줄:
여러 선택지에 따라 다른 동작을 수행하는 문법이다. 조건이 여러 개 붙어 있을 때 유용하다. 선택지로 int나 char형의 변수를 받을 수 있다. 다음은 switch문의 예시이다.
여러 선택지에 따라 다른 동작을 수행하는 문법이다. 조건이 여러 개 붙어 있을 때 유용하다. 선택지로 int나 char형의 변수를 받을 수 있다. 다음은 switch문의 예시이다.
* 정수형 선택지
* 정수형 선택지
<syntaxhighlight lang="c">
<source lang="c">
#include <stdio.h>
#include <stdio.h>
int main(void){
int main(void){
268번째 줄: 268번째 줄:


====while====
====while====
<syntaxhighlight lang="c">
<source lang="c">
while(조건식)
while(조건식)
</syntaxhighlight>
</syntaxhighlight>
*조건식이 참(또는 값이 1)이면 반복한다.
*조건식이 참(또는 값이 1)이면 반복한다.
*무한 반복
*무한 반복
<syntaxhighlight lang="c">
<source lang="c">
while(1)printf("당신의 CMD는 반달당했습니다?\n");
while(1)printf("당신의 CMD는 반달당했습니다?\n");
</syntaxhighlight>
</syntaxhighlight>
279번째 줄: 279번째 줄:


====for====
====for====
<syntaxhighlight lang="c">
<source lang="c">
for(초기식;조건식;증가식)
for(초기식;조건식;증가식)
</syntaxhighlight>
</syntaxhighlight>
*조건문 안에서 사용할 변수 정의, 반복 조건, 반복할 때만 실행할 코드까지 정의하기에 알맞다.
*조건문 안에서 사용할 변수 정의, 반복 조건, 반복할 때만 실행할 코드까지 정의하기에 알맞다.
*단순 반복
*단순 반복
<syntaxhighlight lang="c">
<source lang="c">
int sum = 0;
int sum = 0;
for(int i = 1;i<=1000;i++)sum += i; // sum = sum + i
for(int i = 1;i<=1000;i++)sum += i; // sum = sum + i
299번째 줄: 299번째 줄:
C언어에서는 typedef 키워드로 사용자 변수 타입을 정의할 수 있다. 즉 typedef int bool; 을 이용해 int와 같은 성질을 갖는 자료형을 bool 자료형의 이름으로 사용 가능하다. 또한 여러 자료형과 변수를 한 단위로 묶기 위한 구조체와 공용체, 상수의 집합을 보다 알아보기 쉽게 정의할 수 있는 열거형 또한 사용자 정의 자료형으로 취급한다.
C언어에서는 typedef 키워드로 사용자 변수 타입을 정의할 수 있다. 즉 typedef int bool; 을 이용해 int와 같은 성질을 갖는 자료형을 bool 자료형의 이름으로 사용 가능하다. 또한 여러 자료형과 변수를 한 단위로 묶기 위한 구조체와 공용체, 상수의 집합을 보다 알아보기 쉽게 정의할 수 있는 열거형 또한 사용자 정의 자료형으로 취급한다.
*구조체
*구조체
<syntaxhighlight lang="c">
<source lang="c">
struct xxx_t {
struct xxx_t {
   int index;
   int index;
317번째 줄: 317번째 줄:
*공용체
*공용체
공용체와 구조체의 가장 큰 차이점은, 구조체는 각 속성들의 메모리 영역이 독립적으로 나뉘어 있고 공용체는 모두 같은 공간을 공유한다는 점이다.
공용체와 구조체의 가장 큰 차이점은, 구조체는 각 속성들의 메모리 영역이 독립적으로 나뉘어 있고 공용체는 모두 같은 공간을 공유한다는 점이다.
<syntaxhighlight lang="c">
<source lang="c">
  union my_union{
  union my_union{
   int age;
   int age;
334번째 줄: 334번째 줄:
*열거형
*열거형
열거형은 위의 두 자료형과는 조금 다르며 정수 상수의 집합을 선언해 다음과 같이 프로그래밍 과정을 좀 더 쉽게 하기 위해 주로 사용된다. 예를 들면 다음과 같다.
열거형은 위의 두 자료형과는 조금 다르며 정수 상수의 집합을 선언해 다음과 같이 프로그래밍 과정을 좀 더 쉽게 하기 위해 주로 사용된다. 예를 들면 다음과 같다.
<syntaxhighlight lang="c">
<source lang="c">
  int main(){
  int main(){
   int day = 3;
   int day = 3;
347번째 줄: 347번째 줄:
</syntaxhighlight>
</syntaxhighlight>
위와 같은 코드를 아래와 같이 바꿀 수 있다.
위와 같은 코드를 아래와 같이 바꿀 수 있다.
<syntaxhighlight lang="c">
<source lang="c">
   enum daykind { sunday = 0, monday, tuesday, wednesday, thursday, friday, saturday};
   enum daykind { sunday = 0, monday, tuesday, wednesday, thursday, friday, saturday};
   int main(){
   int main(){
366번째 줄: 366번째 줄:
C언어를 배우면서, 조건문, 루프문등 기초적인 문법에 대해서 학습할때까지는 큰 장벽을 못 느끼다가, 포인터로 넘어오면서 C언어를 포기하는 경우가 많다. 그 이유는 앞에서의 문법들은 사실 사람의 말을 배우듯이 따라가면 되는 것이고, 또한 논리적인 추론능력만 충분하다면 컴퓨터를 처음 하는 사람들도 쉽게 배울 수 있다. 하지만, 포인터가 시작되면 거창하게 얘기하면 컴퓨터의 구조, 좁게 보면 메모리의 구조에 대한 이해와 C언어가 메모리를 어떻게 다루는가, 메모리 계층 구조가 어떻게 되는가에 대한 이해가 없다면 포인터의 개념을 이해하고 활용하는 데에 상당한 어려움을 겪게 될 것이다. 다음은 포인터를 사용한 간단한 예시이다.
C언어를 배우면서, 조건문, 루프문등 기초적인 문법에 대해서 학습할때까지는 큰 장벽을 못 느끼다가, 포인터로 넘어오면서 C언어를 포기하는 경우가 많다. 그 이유는 앞에서의 문법들은 사실 사람의 말을 배우듯이 따라가면 되는 것이고, 또한 논리적인 추론능력만 충분하다면 컴퓨터를 처음 하는 사람들도 쉽게 배울 수 있다. 하지만, 포인터가 시작되면 거창하게 얘기하면 컴퓨터의 구조, 좁게 보면 메모리의 구조에 대한 이해와 C언어가 메모리를 어떻게 다루는가, 메모리 계층 구조가 어떻게 되는가에 대한 이해가 없다면 포인터의 개념을 이해하고 활용하는 데에 상당한 어려움을 겪게 될 것이다. 다음은 포인터를 사용한 간단한 예시이다.


<syntaxhighlight lang="c">
<source lang="c">
#include <stdio.h>
#include <stdio.h>


383번째 줄: 383번째 줄:
이제 포인터에 대한 기본적인 내용을 익혔으니 그 응용으로 넘어가 보자.
이제 포인터에 대한 기본적인 내용을 익혔으니 그 응용으로 넘어가 보자.
*array를 이용한 string
*array를 이용한 string
<syntaxhighlight lang="c">
<source lang="c">
#include <stdio.h>
#include <stdio.h>


397번째 줄: 397번째 줄:
</syntaxhighlight>
</syntaxhighlight>
*pointer를 이용한 string
*pointer를 이용한 string
<syntaxhighlight lang="c">
<source lang="c">
#include <stdio.h>
#include <stdio.h>


422번째 줄: 422번째 줄:
====메모리의 동적 할당====
====메모리의 동적 할당====
메모리에는 CODE, DATA, BSS, HEAP, STACK이 있고, 이 중 CODE, DATA, BSS는 컴파일 과정에서 결정되고 HEAP, STACK은 실행 중에 결정되는 메모리라고 윗 문단에서 언급했다. 그런데 HEAP과 STACK 중에서도 사실 우리는 STACK만을 써왔다. HEAP 메모리에 접근하는 방법은 바로 이 문단에서 다룰 메모리의 동적 할당 뿐이기 때문이다. 그러면 메모리의 동적 할당 방법을 예시로 알아보자.
메모리에는 CODE, DATA, BSS, HEAP, STACK이 있고, 이 중 CODE, DATA, BSS는 컴파일 과정에서 결정되고 HEAP, STACK은 실행 중에 결정되는 메모리라고 윗 문단에서 언급했다. 그런데 HEAP과 STACK 중에서도 사실 우리는 STACK만을 써왔다. HEAP 메모리에 접근하는 방법은 바로 이 문단에서 다룰 메모리의 동적 할당 뿐이기 때문이다. 그러면 메모리의 동적 할당 방법을 예시로 알아보자.
<syntaxhighlight lang="c">
<source lang="c">
#include <stdio.h>
#include <stdio.h>
int main()
int main()
440번째 줄: 440번째 줄:
====다중 포인터====
====다중 포인터====
다중 포인터는 포인터 변수의 주소를 가지고 있는 포인터이다. 다음은 다중 포인터의 사용 예시이다.
다중 포인터는 포인터 변수의 주소를 가지고 있는 포인터이다. 다음은 다중 포인터의 사용 예시이다.
<syntaxhighlight lang="c">
<source lang="c">
#include <stdio.h>
#include <stdio.h>
int main(void)
int main(void)
리브레 위키에서의 모든 기여는 크리에이티브 커먼즈 저작자표시-동일조건변경허락 3.0 라이선스로 배포됩니다(자세한 내용에 대해서는 리브레 위키:저작권 문서를 읽어주세요). 만약 여기에 동의하지 않는다면 문서를 저장하지 말아 주세요.
글이 직접 작성되었거나 호환되는 라이선스인지 확인해주세요. 리그베다 위키, 나무위키, 오리위키, 구스위키, 디시위키 및 CCL 미적용 사이트 등에서 글을 가져오실 때는 본인이 문서의 유일한 기여자여야 하고, 만약 본인이 문서의 유일한 기여자라는 증거가 없다면 그 문서는 불시에 삭제될 수 있습니다.
취소 편집 도움말 (새 창에서 열림)

| () [] [[]] {{}} {{{}}} · <!-- --> · [[분류:]] · [[파일:]] · [[미디어:]] · #넘겨주기 [[]] · {{ㅊ|}} · <onlyinclude></onlyinclude> · <includeonly></includeonly> · <noinclude></noinclude> · <br /> · <ref></ref> · {{각주}} · {|class="wikitable" · |- · rowspan=""| · colspan=""| · |}