본문 바로가기
SW사관학교 정글/C언어와 친구들

[C언어와 친구들] C언어를 알아볼까 ? 하잇 ~!

by 대범하게 2022. 10. 21.
반응형

1. include와 헤더파일

- 헤더파일이란? C언어의 문법을 가지고 있는 프로그램.

- 헤더파일이 코드에 추가되어 있지 않다면, 컴퓨터는 아무것도 하지 못한다. 

 

1-1) #include <stdio.h>

이 한 줄의 문장은 'stdio.h'안에 정의되어 있는 많은 함수들을 내 코드안에 포함시켜서 프로그램으로 만들겠다.는 의미

- stdio: standard input output의 약자 (studio가 아니다 🤗)

- h: 파일의 확장자, header를 나타냄

 

1-2) #include <stdilb.h>

- 문자열 변환, 의사 난수 생성, 동적 메모리 관리 등의 함수들을 포함

- 동적 메모리 할당 함수인 mallo, calloc 함수도 이 헤더에 포함되어 있으며, 시스템 명령어나 프로세스 제어함수도 포함

#include <stdio.h> // stdio.h is inputed
#include <stdilb.h> // stdilb.h is inputed

 

2. main 함수

- C언어는 프로그램이 시작되면 무조건 main부터 찾기 때문에 main 함수 안에 코드를 짜야 명령어가 실행된다.

- main 앞에 쓰는 int의 의미는 정수 '-21억' ~ '+21억'을 의미하는데, 이는 main의 반환값을 의미한다.

- 따라서, 반환값에 따라 반환을 해야하는 값이 다른데 반환값을 정하지 않으면 무조건 0을 반환한다. 이것을 바꾸려면 'return 반환값'을 쓰면 된다. 

#include <stdio.h>
#include <stdlib.h>

int main(){
    return 0;
}

 

3. 변수(Variable)

- 바뀔 수 있는 어떤 값을 보관하는 곳 

- 변수란 말 그대로 '변하는 수'를 뜻한다.

int a; // a는 정수형 변수명, 값은 미정
float f = 0.12345; // f는 실수형 변수고, 값은 0.12345
char c = 'a'; // c는 문자형 변수고, 값은 a
char c = 65; // c는 문자형 변수고, 값은 65인데 이는 ASCII 코드를 가리키며 따라서 값이 A이다.
char s[6] = 'korea'; // s는 문자열이고, 값은 {k, o, r, e, a, null}이다.

1) int는 정수 (-21억 ~ 21억)

2) unsigned int는 자연수 (1~42억)

3) float는 실수 (-21억 ~ 21억, 소수점 6자리까지만 가능)

4) char는 문자 한 개(ASCII, 문자의 번호를 얘기함)

5) string은 문자열(문자 여러개)

6) double(실수와 비슷한데, 한계가 소수점 14자리까지. 하지만 저장공간이 큼)

7) long(double과 비슷하게 더 큰 수를 쓸 수 있지만, 저장공간이 큼. long 다음 int나 float 같은 형태를 쓰면 21억보다 더 큰 값을 저장 가능)

8) FILE(연결리스트를 만드는데 사용하는 형태)

 

(여담이지만, c언어 처음 공부할 때 변수의 값의 범위(?)를 간과하고 공부했던 기억이 있는데 어셈블리어까지 공부하다 보니 이것만큼 또 중요한게 없는거 같기도 하고 .. 그렇다.)

 

4. printf

- 화면에 수나 문자를 출력하는 함수

- printf() 함수의 f는 formatted의 약자이며, 서식화된 출력을 지원한다는 의미이다.

printf("hello, world!");
printf("123456");	// "" 쌍따옴표에 감싸져있기 때문에 문자로 취급한다.

 

5. 변환문자와 기호문자

1) %d : int(정수)

2) %f : float(실수; 0.1이여도 0.100000처럼 6자리로 강제로 늘린다.)

3) %g : float(실수; %f와 달리 0.1로 출력)

4) %c : char(문자 한 개)  cf. 최대 1바이트를 차지하는 char형 변수에 한글을 치면 오류가 난다.

5) %s : string(문자열)

6) %lf : long float

printf("%d", 134); // output -> 134
printf("%f", 0.1); // output -> 0.100000
printf("%g", 0.1); // output -> 0.1
printf("%c", 'a'); // output -> a 
printf("%s", "hello"); // output -> hello, 이건 딱히 필요 없음. 그냥 printf("hello");하면 됨.

1) \n : 줄바꿈

2) \t : tab

printf("hello\n"); // output -> hello(enter key)
printf("hello \t hello"); // output -> hello hello

 

5. scanf

- 화면(키보드)으로부터 결과를 받아들이는 입력함수. (파이썬은 input에 해당). 

- scanf 역시 printf처럼 각 변수의 타입에 따라 입력받는 포맷(%d, %f, %c 등)을 달리 해야한다. 

- 따옴표 안에 변환 문자를 넣고, 뒤에 입력할 변수를 쓴다. 이 때 변수 앞쪽에 &을 붙인다. => scanf("변환문자", &변수);

- scanf로 여러 개의 변수를 입력받을 수 있는데, 이럴 때는 변환 문자 여러 개를 사용하면 된다. (space/ , /. / - / = ) 

 

* 특이사항: scanf로 snippet형 변수를 입력받으려면 %lf로 받아야한다. 

 

버퍼 오버플로우: 허용된 메모리 이상에 데이터를 집어넣어 발생하는 오류, 보안상 매우 취약.

 

6. cast 연산자

- 변수의 형태를 임시적으로 변환하는 함수

- 위에서 언급했듯이 "123456"은 컴퓨터에서 문자로 취급한다.

아래 예제에서 print("%c", a);를 하게 되면, 변수 선언에서 따옴표를 안 해줬기 때문에 ASCII 코드로 인식하기 되어 결과 값 9로 출력되지 않는다. 따라서, cast 연산자를 활용하여 변환해준다.

int a = 9;
printf("%c", (char)a);
// result: 9

=> cast 연산자는 변수 앞에 괄호를 놓고, 그 괄호 안에 내가 원하는 형태를 쓰면 된다. 

 

7. 조건문 (BOJ 9498: 시험성적, 2753: 윤년)

- 조건식 

1) a == b : 'a와 b는 같다', a = b라고 하면 조건식이 아니라 변수 a의 값을 변수 b의 값으로 바꾼다는 뜻

2) a != b : 'a와 b는 다르다'

3) a > b, a < b, a >= b, a <= b

int a = 1, b = 10
 
a == b // 0 (false)
a != b // 1 (true)
a > b // 0 (false)
a < b // 1 (true)
a >= b // 0 (false)
a <= b // 1 (true)

 

- 조건식 2개 이상을 연결시켜주는 연산자 => 논리 연산자

1) 조건식 && 조건식 : 연산자 'and' 의미, 조건식 여러 개 중에서 하나라도 거짓이면 0을 반환, 모두 다 참이여야 1을 반환

2) 조건식 || 조건식: 연산자 'or' 의미, 조건식 여러 개 중에서 하나라도 참이면 1을 반환, 모두 거짓이어야지 0을 반환

3) !조건식: 연산자 'not'을 의미, 만약 조건식이 참이면 거짓으로 바뀌고, 거짓이면 참으로 바뀌는 연산자

int a = 0, b = 1;
 
a == b && a <= b // {0, 1} => 0
a == b || a <= b // (0, 1) => 1
!a == b // 0 => 1
// 2753: 윤년
// &&(and) 연산자, ||(or) 연산자
#include <stdio.h>

int main(){
    int year;
    scanf("%d", &year);
    //if (year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0){ 이런식으로는 컴파일안됨
    if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0){
        printf("1");
    }
    else {
        printf("0");
    }
    return 0;
}
// 9498: 시험성적
// else if가 여러 개 반복되는 경우, 순서대로 위쪽 if 문 조건을 만족하지 않는 경우에는 다음 조건을 확인한다.
// 따라서, else if문의 조건부에는 [윗 조건의 값보다 작다]를 포함시키지 않아도 됨.
#include <stdio.h>
int main(){
    int score;
    scanf("%d", &score);
    if (score >= 90){
        printf("A\n"); 
    }
    else if (score >= 80){
        printf("B\n");
    }
    else if (score >= 70){
        printf("C\n");
    }
    else if (score >= 60){
        printf("D\n");
    }
    else {
        printf("F\n");
    }
    return 0;
}
// 1085: 직사각형에서 탈출
#include <stdio.h>

int main(){
    int x, y, w, h;
    scanf("%d %d %d %d", &x, &y, &w, &h);
    int min = x;
    if (min > w - x)
        min = w - x;
    if (min > y)
        min = y;
    if (min > h - y)
        min = h - y;
    printf("%d\n", min);
    return 0;
}

 

8. 사칙연산(BOJ: 10689: 사칙연산, 2588: 곱셈)

// 10869: 사칙연산 
// 두 자연수 A와 B가 주어진다.
// 이때, A+B, A-B, A*B, A/B(몫), A%B(나머지)를 출력하는 프로그램을 작성하시오. 
// 입력값이 1부터 10000(1만)까지이므로 최대 결과값 100,000,000(1억)임.
// int형 범위가 -21억~21억이라 충분히 커버됨.
#include <stdio.h>
int main(){
    int A;
    int B;
    scanf("%d %d", &A, &B);
    printf("%d\n", A+B); 
    printf("%d\n", A-B); 
    printf("%d\n", A*B); 
    printf("%d\n", A/B); 
    printf("%d\n", A%B); 
}
// 2588: 곱셈
// a / b: a를 b로 나눈 몫 (385 / 100 = 3)
// a % b: a를 b로 나눈 나머지 (385 % 10 = 5)
#include <stdio.h>
int main(){
    int a, b;
    scanf("%d %d", &a, &b);
    
    int c = a * (b % 10);
    int d = a * (b / 10 % 10);
    int e = a * (b / 100);

    printf("%d\n", c); 
    printf("%d\n", d); 
    printf("%d\n", e); 
    printf("%d\n", a*b); 
    
    return 0;
}

 

9. 반복문 -  for문 (BOJ: 2739: 구구단, 2438: 별 찍기 -1, 10871: X보다 작은 수)

for문 구조: 초기식/조건식/증감식이 나오고 이후 명령을 순차적으로 실행

1) 초기식: i = 0;

  초기 조건을 설정해준다. i=0이므로 i는 0에서부터 시작한다. 이때 i를 제어변수라고 한다.

2) 조건식: i < 100;

  i가 100보다 작을 때까지 계속해서 반복문을 시행한다는 조건을 설정한다. 

만약 이런 조건이 없다면 끊이지 않고 반복하기 때문에 CPU 사용률을 100%로 끌어올려 전력을 과도하게 낭비한다. 그니깐 맥 아니면 비행기 뜬다는 소리 ~

3) 증감식: i++

  2번 조건식을 만족하면 1번에서 출발해서 계속 1씩 더해주는 증감식을 설정한다. 

for (/* 초기식 */; /* 조건식 */; /* 증감식 */) {
  // 명령1;
  // 명령2;
  // ....
}

for(int i=0; i < 100; i++){
	// blah blah blah
}

for(int i = 100; i >= 0; i--){
    // Blah Blah Blah
}
// 2739: 구구단
#include <stdio.h>
int main(){
    int N;
    scanf("%d", &N);
    for(int i=1; i < 10; i++){ 
        printf("%d * %d = %d\n", N, i, N*i);
    }
    return 0;
}
// 2438: 별 찍기 -1
#include <stdio.h>
int main(){
    int N;
    scanf("%d", &N);
    for(int i=0; i < N; i++){
        for(int j=0; j <= i; j++){
            printf("*");
        }
        printf("\n");
    }
    return 0;
}
// 10871: X보다 작은 수
#include <stdio.h>
int main(){
    int N, X;
    scanf("%d %d", &N, &X);
    for(int i=0; i < N; i++){
        int a;
        scanf("%d", &a);
        if (a < X){
            printf("%d ", a);
        }
    }
    return 0;
}

 

10. while문 

int i = 0;
while(i < 100){
    // Blah Blah Blah
    i++;
}

 

11. do-while문

do-while문은 while문과 비슷하나 while문이 명령을 시행하기 전에 조건식의 참, 거짓을 먼저 판별하는 반면, do-while문에서는 먼저 명령을 실행하고 나서 조건식을 검사한다. 만약 조건식이 거짓이라도 최소한 한 번은 실행된다는 점이 다르다. 

int i = 0;
while (i < 100){
    i++;
}
 
i = 0;
 
do {
    i++;
}while (i < 100);

 

배열, 포인터 ... 기다려라... 

반응형