본문 바로가기
개발

[CS50] - C

by _Jun 2022. 4. 8.

 #include <stdio.h> 

#include <stdio.h>

int main(void) {
	printf("hello, world\n");
}

#include <stdio.h> : 작성하는 c 프로그램이 stdio.h라는 파일(라이브러리) 안에 미리 작성된 함수들에 접근 가능하도록 하는 코드

 


 

 Compile 

Compile: 소스 코드를 오브젝트 코드(0과 1로 이루어진 기계어)로 변환하는 과정

Terminal에서 clang hello.c -o 실행파일명 명령어로 hello.c 파일을 compile한다.

  • clang hello.c
  • clang hello.c -o hello

Compile 결과로 실행파일이 생기는데, ./실행파일명 terminal 입력해서 실행할 수 있다.

ls했을 컴파일된 코드에는 * 붙어있다

 

stdio.h 말고 다른 파일을 추가한 경우(eg. cs50.h), compile clang hello.c -o 실행파일명 -lcs50 라고 해야 한다.

make c파일명 명령어만 치면 위에 명령어와 동일한 동작을 수행한다.

// test.c 파일이 있는 경우
make test

make 명령어가 어떤 option 사용해야 할지, 파일명은 무엇으로 할지, 어떤 라이브러리나 코드를 연결했는지 등 알아서 찾아준다.

* make 는 compiler가 아니고, clang compiler를 호출해서 compile과정을 수행하게 하는 명령어다.

 

컴파일의 4 단계

  1. 전처리(Precompile) : 컴파일 전에 전처리기에 의해 수행되는 과정.  전처리기가 .c 파일 내에서 #으로 시작하는 C 소스 코드를 보면 컴파일 전에 다른 행동을 수행하게 된다.   (e.g. #include: 전처리기에게 다른 파일의 내용을 포함하도록 한다.)
  2. 컴파일(Compile) : 전처리 소스 코드를 컴파일러가 어셈불리어로 컴파일한다.
  3. 어셈블(Assemble) : 어셈블러라는 프로그램을 통해 어셈블리어를 오브젝트 코드(0 1 코드) 변환하는 작업.
  4. 링크(Link) : C 프로그램이 여러 라이브러리(e.g. math.h, cs50.h) 포함해서 여러 개의 파일로 이루어져 있는 경우 하나의 오브젝트 파일로 합쳐져야 한다. 링커라는 프로그램이 여러 개의 다른 오브젝트 파일을 하나의 오브젝트 파일로 합쳐준다.

컴파일 단계

 


 

 조건문 & 반복문

1. 조건문

// if else
if (x < y) {
    printf("x is less than y\n");
} else if (x > y) {
    printf("x is greater than y\n");
} else {
    printf("x is equal to y\n");
}

// switch
switch (x) {
    case 1:
        printf("A\n");
        break;
    case 2:
        printf("B\n");
        break;
    default:
        printf("C\n");
}

 

2. 반복문

// while
int i = 0;
while (i < 10) {
    printf("hello, world\n");
    i++;
}

// for
for (int i = 0; i < 10; i++) {
    printf("hello, world\n");
}

// do-while
int j = 0;
do {
    printf("hello, world\n");
    j++;
} while (j < 0);

 


 

 Data type & format specifier(형식 지정자) 

1. Data type

C 정적 타입 언어(Statically typed language)라서 변수에 적절한 타입을 지정해주어야 한다.

- 정수형: int(4bytes), long(8bytes) 

- 불리언: bool(1byte)

- 문자 하나: char(1byte)

- 소수형: float(4bytes), double(8bytes)

 

sizeof function을 통해 자료형의 크기를 알 수 있다.

int main(void) {
    printf("Size of int: %d\n", sizeof(int));
    printf("Size of long: %li\n", sizeof(long));
    printf("Size of bool: %li\n", sizeof(bool));
    printf("Size of char: %li\n", sizeof(char));
    printf("Size of float: %li\n", sizeof(float));
    printf("Size of double: %li\n", sizeof(double));
}

/*
Size of int: 4
Size of long: 8
Size of bool: 1
Size of char: 1 
Size of float: 4
Size of double: 8
*/

 

 

* 변수 앞에 (다른 data type)을 붙이면 형 변환을 할 수 있다.

char c1 = 'A';
printf("%c", c1); // A
printf("%i", (int) c1); // 65

int ascii = (int) c1;
printf("%i", ascii); // 65

 

2. Format specifier

int - %i

long - %li

char - %c

string - %s

float - %f

double - %f

 

* float double 사용할 , %f에서 f 앞에 '.원하는 소수점 자리수' 넣어서 소수부분의 길이를 조절할 수 있다.

float price;
printf("How much does it cost? ");
scanf("%f", &price);
printf("Your total is $%.2f.\n", price*1.0625);

 


 

 Function 

[함수의 출력 타입] [함수명] ([함수의 입력 타입]) {...}

void print_number(int n) {
    printf("%i", n);
}

 


 

 Array 

같은 data type의 데이터를 메모리상에 연달아 저장하기 위해 array를 사용한다.

[Array 안에 들어갈 데이터의 타입] [Array 변수명][[Array 길이]]

int scores[10];
char alphabets[26];

alphabets[0] = 'A';
alphabets[1] = 'B';
alphabets[2] = 'C';
alphabets[3] = 'D';
alphabets[4] = 'E';
alphabets[5] = 'F';
alphabets[6] = 'G';
alphabets[7] = 'H';
...
alphabets[23] = 'X';
alphabets[24] = 'Y';
alphabets[25] = 'Z';

 

[Array 안에 들어갈 데이터의 타입] [Array 변수명][[Array 길이]] = { Array에 들어갈 데이터 }로 배열에 값을 바로 추가할 수도 있다. (배열을 정적으로 초기화)

char alphabets[26] = {'A', 'B', 'C', 'D', 'E', ... , 'X', 'Y', 'Z'};
int numbers[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

 


 

 String 문자열 

C언어에서 문자열은 char의 배열이다. 

문자열의 마지막 인덱스는 '\0' (null 종단 문자)로 끝난다. '\0'는 1byte 내의 모든 bit가 0이다.

 

string(char 배열)은 char(1byte), int(4bytes) 등의 데이터처럼 크기가 정해져 있지 않다. 즉, 배열 안에 들어있는 char의 수에 따라 크기가 달라지게 된다. array의 변수명은 array의 시작부분에 대한 정보를 알려준다(여기서는 0번째 index). 하지만 정해진 크기가 없는 경우에 언제 string이 끝나는지 알 수 없기 때문에, array의 마지막에 '\0'을 사용해서 string의 끝을 나타낸다. 

 

따라서 string은 메모리 상에서 글자 수 + 1 만큼의 바이트를 차지한다. 

int main(void) {
    char str[6] = "array";
}

 

strlen : string.h 라이브러리에 포함되어 있는 문자열의 길이를 알려주는 함수 

 

toupper : ctype.h  라이브러리에 포함되어 있는 대문자로 변환해주는 함수

 

 


 

 main 함수의 parameter 

int argc :

main 함수가 받게 될 input의 개수(argv array의 길이)

 

char* argv[] :

main 함수에 실질적으로 전달되는 input(char type 포인터 array).

Terminal 창에서 입력한 command line argument(명령행 인자)을 공백을 기준으로 나누어 argv에 전달한다. 

argv[0]은 기본적으로 프로그램의 경로

 

// cma.c

#include <stdio.h>

int main(int argc, char* argv[]) {
    if (argc >=2) {
        printf("hello, %s\n", argv[1]);
    } else {
        printf("hello, world\n");
    }

    printf("%s\n", argv[0]); // 프로그램의 경로 ./cmd
}
$ make cma
$ ./cma
hello, world
./cma
$ ./cma NAME
hello, NAME
./cma
$

 


 

 main 함수의 return value 

C언어의 main 함수는 int 반환값을 갖는다. 

오류가 없는 경우 main 함수의 반환값은 0이다.

오류가 있는 경우 그 오류에 상응하는 0이 아닌 int 값을 반환한다. (어떤 값이라도 0이 아닌 값을 반환하면 오류가 있는 것)

#include <stdio.h>

int main (int argc, char* argv[]) {
    if (argc != 2) {
        printf("missing command-line argument\n");
        return 1; // exit program
    }
    printf("hello, %s\n", argv[1]);
    return 0;
}

 


 

 Custom data type 

typedef struct 로 새로운 데이터 타입을 구조체로 정의할 수 있다.

typedef struct {

    구조체의 멤버들

} [구조체 별칭];

typedef struct {
	int age;
    char name[10];
} person;

int main(void) {
    person a = {20, "NAME"};
    printf("I'm %s, and %i years old\n", a.name, a.age); // I'm NAME, and 20 years old
}

 

typedef char *string;

char *: 이 값의 형태가 char의 주소가 될 거라는 의미

string: 이 자료형의 이름

'개발' 카테고리의 다른 글

ASCII code와 Unicode  (0) 2022.04.05
DOM이란  (0) 2022.03.01
[JS] 데이터 타입(Data type) - 복사, 불변성과 가변성  (0) 2022.01.12
[JS] 메모리와 데이터  (0) 2022.01.10
[JS] Event Delegation(이벤트 위임)  (0) 2022.01.06

댓글