c, cpp

C언어의 기본 문법

blackbearwow 2024. 6. 19. 22:21

0. 컴파일

windows에서 visual studio를 사용한다면 해당 ide가 버튼 하나로 컴파일을 자동으로 해준다.

gcc 또는 g++로 cli로 컴파일 하는 방법은

gcc -o (실행파일 이름) (소스파일)
gcc -o test1.exe test1.cpp #windows의 경우
gcc -o test1.out test1.cpp #linux의 경우

여러 소스파일 컴파일 방법

gcc -o (실행파일 이름) (소스파일1) (소스파일2) (소스파일3)
gcc -o test1.exe test1.cpp num.cpp func.cpp

1. 주석

/* 여러  
행
주석 */
// 단일 행 주석

2. 반복문

반복문의 탈출: break

반복문의 생략: continue

2.1. while

while(값)
{
}

값이 0이면 while안에 명령들을 실행하지 않고, 0이 아닌 다른 값이면 명령을 실행한다.

// 예시
int main() {
    int num=3;
    while(num)
    {
        printf("%d ", num);
        num--;
    }
    return 0;
}
// 출력: 3 2 1

2.2. do while

do {

} while(값);

while문과 다른점은, 무조건 한번은 명령을 실행한다는 점이다.

명령이 반복되는데 최소한 한번은 실행되어야 하는 명령이라면, 사용하면 좋다.

// 예제
int main() {
    int total=0, num=0;
    do
    {
        printf("정수 입력(0 to quit): ");
        scanf("%d", &num);
        total += num;
    } while (num!=0);
    printf("합계: %d \n", total);
    return 0;
}

2.3. for

for(초기식; 조건식; 증감식)
{
//반복의 대상이 되는 명령들
}

while문을 한줄로 간단하게 사용하기 위해 for문이 등장했다.

//예제
int main() {
    for(int i=10; i > 0; i--){
        printf("%d \n", i);
    }
    printf("fire \n");
    return 0;
}

위 예제에서 조건식이나 증감식을 제거하면 무한 루프에 빠진다.

3. 조건문

3.1. if

if(값)
{
//여러 명령들
}

if(값)
	//하나의 명령

하나의 명령이라면 괄호를 생략해도 되고 여러 명령이라면 괄호가 있어야 한다.

// 예제
if(num1>num2)
{
	printf("num1이 num2보다 큽니다. \n");
    printf("%d > %d \n", num1, num2);
}

if(num1>num2)
	printf("num1이 num2보다 큽니다. \n");

3.2. if else

if(값)
{
}
else
{
}
// 예제
if(num1>num2)
{
	printf("num1이 num2보다 큽니다. \n");
    printf("%d > %d \n", num1, num2);
}
else
{
	printf("num1이 num2보다 크지 않습니다. \n");
    printf("%d <= %d \n", num1, num2);
}

3.3. if else if else

if(조건1)
{
}
else if(조건2)
{
}
else if(조건3)
{
}
else
{
}

3.4. 삼항 연산자

(조건)?(참일때 반환값):(거짓일 때 반환값)
// 예제
int abs = num>0 ? num : num*(-1);

3.5. switch

// 예제
int main() {
    int num;
    printf("1이상 5이하의 정수 입력: ");
    scanf("%d", num);

    switch(num)
    {
    case 1:
        printf("1 \n");
        break;
    case 2:
        printf("2 \n");
        break;
    case 3:
        printf("3 \n");
        break;
    case 4:
        printf("4 \n");
        break;
    case 5:
        printf("5 \n");
        break;
    default:
        printf("i don't know! \n");
    }
    return 0;
}

4. 함수

int main(void)
{
}

(반환형태) (함수이름) ((입력형태))
{
	함수의 몸체
}

4.1. 지역변수, 전역변수, static변수

지역변수는 중괄호 내에 선언되는 변수다. 지역변수는 해당지역을 벗어나면 자동으로 소멸된다. 함수, for문, if문 내에서 선언되는 변수는 모두 지역변수이다. 

전역변수는 어디서든 접근 가능한 변수로 중괄호 내에서 선언되지 않는다. 

static변수는 선언된 함수 내에서만 접근 가능하다. 딱 1회 초기화되고 프로그램 종료 시까지 메모리 공간에 존재한다. 전역변수보다 안정적이기 때문에 전역변수를 static변수로 대체할 수 있다면 static변수로 대체해야 한다.

5. 배열과 포인터

5.1. 배열

선언 방법

int arr1[7]; // 길이가 7인 int형 1차월 배열 arr1
float arr2[10]; // 길이가 10인 float형 1차월 배열 arr2
double arr3[12]; // 길이가 12인 double형 1차월 배열 arr3

선언과 동시에 초기화

int arr1[5] = {1,2,3,4,5};
int arr2[] = {1,2,3,4,5,6,7};
int arr3[5] = {1,2}; //나머지는 0으로 채워짐
int arr4[10] = {}; //모두 0으로 채워짐

5.2. 포인터

포인터는 주소 값을 저장하기 위해 만들어졌다.

int num=7;
int *pnum;
pnum = &num;

*연산자는 해당 포인터가 가리키는 메모리 공간에 접근할 때 사용하는 연산자이다. &연산자는 해당 변수의 주소값을 반환하는 연산자이다.

5.3. 함수 포인터

함수의 주소 값을 저장할 수 있는 포인터 변수이다.

int (*fptr) (int)

fptr은 포인터

반환형이 int인 함수 포인터

매개변수 선언이 int 하나인 포인터

라는 의미를 담고 있는 것이다. 반환형과 매개변수 선언이 같은 함수만 함수 포인터로 사용할 수 있다.

6. 구조체와 공용체

6.1. 구조체 (struct)

struct point
{
    int xpos;
    int ypos;
};

typedef struct person
{
    char name[20];
    char phoneNum[20];
    int age;
} Person;

6.2. 공용체 (union)

typedef union ubox
{
    int mem1;
    int mem2;
    double mem3;
} UBox;

7. 열거형(Enumerated Type)

열거형은 이름있는 상수의 정의를 통한 의미의 부여에 있다.

typedef enum syllable
{
    Do=1, Re=2, Mi=3, Fa=4, So=5, La=6, Ti=7
} Syllable;

int main(void)
{
    Syllable tone;
    for(tone=Do; tone<=Ti; tone+=1)
    	Sound(tone);
    return 0;
}

8. 메모리 동적 할당과 해제

#include <stdlib.h>
void *malloc(size_t size);
void free(void* ptr);
int* ptr = (int*)malloc(sizeof(int)*7);

free(ptr);

9. 파일 분할

하나의 파일에 모든 기능을 담는 것은 적절하지 않다. 적절히 모듈화하여 분리해야 한다.

외부에서 정의된 변수나 함수는 extern키워드를 사용한다. 

이때 구체적으로 어느 파일에 선언 및 정의되어있는지 까지는 알리지 않아도 된다.

다른 파일에서 접근을 못하게 하고 싶다면 static을 변수나 함수에 붙이면 된다.

// num.c
int num=0;
// func.c
extern int num;
void Increment(void){
    num++;
}
int GetNum(void){
    return num;
}
// main.c
extern void Increment(void);
extern int GetNum(void);
int main(void){
    printf( . . . . );
    Increment();
    . . . .
}