- basic
printf
scanf
\" \'
\n \b \t
/*
정수 : %d decimal
%x hexa decimal
%o octal
실수 : %lf long float
문자 : %c character
문자열 : %s string
*/
// lvalue: 변수
// rvalue: 변수, 상수
- operator
/*
산술연산자:
+
-
*
/
% -> 나머지 연산은 정수 연산에만
*/
c file -> main 함수를 맨 앞쪽으로 두는 습관을 가져라.
-> main 함수에서 쓰이는 함수는 앞쪽에 정의하라.
전역변수 -> 남발하지 말자
-> 싱글톤 사용하자
- operator
/*
관계연산자 :
> >=
< <=
== !=
참: 1, 1.0, 0.1, -1, 2, ...
거짓: 0, 0.0
*/
/*
논리연산자 :
&& || !
*/
Q. 대문자 전체를 while문을 이용하여 출력해보세요.
#1
void get_capital_letter()
{
int i = 'A';
while (i <= 'Z')
{
printf("%c", i);
i++;
}
}
#2
void get_capital_letter()
{
int i = 0;
while (i < 26)
{
printf("%c", i + 'A');
i++;
}
}
c언어는 반환을 한 개밖에 하지 못함 -> 포인터 사용
/*
연산자 우선순위
1. 산술 연산자 ( * , / , % ) -> ( + , - )
2. 관계 연산자
3. 논리 연산자
4. 대입 연산자
*/
Q. 2개의 정수 중에서 큰 값을 찾는 함수를 만드세요.
#1
int max_2(int a, int b)
{
if (a > b)
return a;
return b;
}
#2
int max_2(int a, int b)
{
if (a > b)
b = a;
return b;
}
Q. 4개의 정수 중에서 큰 값을 찾는 함수를 만드세요.
#1
int max_4(int a, int b, int c, int d)
{
if (a > b)
b = a;
if (b > c)
c = b;
if (c > d)
d = c;
return d;
}
#2
int max_4(int a, int b, int c, int d)
{
if (d < a)
d = a;
if (d < b)
d = b;
if (d > c)
d = c;
return d;
}
#3
int max_4(int a, int b, int c, int d)
{
int max = a;
if (max < b)
max = b;
if (max < c)
max = c;
if (max < d)
max = d;
return max;
}
#4 (reuse)
int max_4(int a, int b, int c, int d)
{
return max_2(a, max_2(b, max_2(c, d)));
}
#5 (reuse)
int max_4(int a, int b, int c, int d)
{
return max_2(max_2(a, b), max_2(c, d));
}
Q. 1 부터 n 까지의 합을 구하는 함수를 만드세요.
int getSum(int n)
{
int sum = 0;
int i = 1;
while (i <= n)
{
sum += i;
i++;
}
return sum;
}
c 에서 함수명 관용적으로 snake case 사용
-> ex) say_hello()
- array
/*
변수 선언 = 자료형 + 변수명
-> 자료형 = 변수 선언 - 변수명
*/
// 배열 = 포인터 = 주소
void show_array(int arr[], int size);
void show_array2(int arr[]);
int main()
{
int ages[3] = {10, 20, 30};
printf("%d\n", ages); // 메모리 주소 출력
printf("%d\n", sizeof(ages)); // 4 byte x 3
printf("%d\n", sizeof(ages) / 4);
printf("%d\n", sizeof(ages) / sizeof(int));
printf("%d\n", sizeof(ages) / sizeof(ages[0]));
int size = sizeof(ages) / sizeof(ages[0]);
show_array(ages, size);
show_array2(ages);
return 0;
}
void show_array(int arr[], int size)
{
int i = 0;
while (i < size)
{
printf("%d ", arr[i]);
i++;
}
printf("\n");
}
void show_array2(int arr[])
{
/*
아래의 size는 원하는 결과가 아님.
c 언어에는 배열의 크기를 구할 수 있는 함수는 없음.
변수 선언된 곳에서 sizeof '연산자'를 사용하여 매개변수로 전달
*/
int size = sizeof(arr) / sizeof(arr[0]);
int i = 0;
while (i < size)
{
printf("%d ", arr[i]);
i++;
}
printf("\n");
}
Q. 0 ~ 99 사이의 양수 10개를 배열에 저장하는 함수를 만드세요.
void make_randoms(int *p, int size)
{
int i = 0;
while (i < size)
{
p[i] = rand() % 100;
i++;
}
}
Q. 1차원 배열에서 홀수만 출력하는 함수를 만드세요.
void show_odd(int *p, int size)
{
int i = 0;
while (i < size)
{
if (p[i] % 2)
printf("%d ", p[i]);
i++;
}
}
- pointer
#include <stdio.h>
// * : 곱셈(*), 곱셈복합(*=), 주석(/* */), 변수 선언(int*), 값 접근(*p)
int main()
{
int a = 7;
printf("%d\n", a); // 7
printf("%x\n", &a); // 61ff18
printf("%p\n", &a); // 0061FF18
int *p = &a;
printf("%p\n", p); // 0061FF18
printf("%d\n", *p); // 7
*p = 99;
printf("%d\n", a); // 99
return 0;
}
Q. 2개 변수의 값을 교환하는 함수를 만드세요.
void swap(int *p, int *q)
{
int tmp = *p;
*p = *q;
*q = tmp;
}
- pointer
int main()
{
int digits[4] = {2, 4, 6, 9};
int *p = digits;
printf("%d\n", digits);
printf("%d\n", p);
printf("%d\n", p + 1); // 포인터가 가리키는 자료형의 크기만큼 증가
printf("%d\n", digits[0]);
printf("%d\n", p[0]);
printf("%d\n", *p);
return 0;
}
show_array 함수
#1
void show_array(int *p, int size)
{
int i = 0;
while (i < size)
{
printf("%d ", p[i]);
i++;
}
printf("\n");
}
#2
void show_array(int *p, int size)
{
int *end = p + size;
while (p < end)
{
printf("%d ", *p++);
}
printf("\n");
}
find_max 함수
#1
int find_max(int *p, int size)
{
int i = 0, max = p[0];
while (i < size)
{
if (max < p[i])
max = p[i];
i++;
}
return max;
}
#2
int find_max(int *p, int size)
{
int max = *p;
int *end = p + size;
while (p < end)
{
if (max < *p)
max = *p;
p++;
}
return max;
}
- sentinel
// sentinel = '보초' 라는 뜻
// sentinel 로 가장 좋은 것은 0
int main()
{
// 최대 255자
// char s[256] = {'h', 'e', 'l', 'l', 'o'};
char s[256] = "hello";
/*
문자열 맨 마지막에는 sentinel 존재
sentinel = \0 = NULL = ascii 0
*/
// 보안에 안좋은 코드
printf("%s\n", s); // hello
s[1] = '\0';
printf("%s\n", s); // h
return 0;
}
show_sentinel 함수
void show_sentinel(int *p)
{
while (*p)
printf("%d ", *p++);
printf("\n");
}
- string
#include <stdio.h>
#include <string.h>
int main()
{
char s[256] = "mountain";
char buffer[256];
// 문자열 길이
printf("length : %d\n", strlen(s)); // length : 8
// 문자열 복사
strcpy(buffer, s);
puts(buffer); // mountain
// 문자열 덧셈
strcat(buffer, s);
puts(buffer); // mountainmountain
// 문자열 관계
printf("compare : %d\n", strcmp(s, buffer)); // compare : -1
printf("compare : %d\n", strcmp(s, s)); // compare : 0
printf("compare : %d\n", strcmp(buffer, s)); // compare : 1
// 특정 문자 찾기
printf("find : %d\n", strchr(s, 'a')); // find : 6422053 -> 주소
printf("find : %d\n", *strchr(s, 'a')); // find : 97 -> 'a' 의 ascii code
printf("n_th : %d\n", strchr(s, 'a') - s); // n_th : 5 -> 'a'의 인덱스 위치
// 특정 문자열 찾기
printf("find : %s\n", strstr(buffer, s)); // find : mountainmountain
printf("find : %d\n", strstr(buffer, s)); // find : 6421792
printf("find : %d\n", strstr(buffer, "sea")); // find : 0 -> 실패하면 0(null pointer) 반환
return 0;
}
my_len 함수
#1
int my_len(const char *s)
{
int i = 0;
while (s[i++])
;
return i - 1;
}
#2
int my_len(const char *s)
{
const char *p = s;
while (*p++)
;
return p - s - 1;
}
my_copy 함수
#1
char *my_cpy(char *dst, const char *src)
{
int i = 0;
while (src[i])
{
dst[i] = src[i];
i++;
}
dst[i] = '\0';
return dst;
}
#2
char *my_cpy(char *dst, const char *src)
{
char *base = dst;
while (*src)
{
*dst++ = *src++;
}
*dst = '\0';
return base;
}
#3
char *my_cpy(char *dst, const char *src)
{
char *base = dst;
while (*dst++ = *src++)
;
return base;
}
/*
반복문에서
continue : 해당 블록에서 아래 코드를 실행하지 않고, 다시 블록 실행
-> 증감 연산자 위에 쓰면 무한루프가 발생할 수 있음
break : 반복문 종료
*/
Q. 2중 for문을 사용하여 다음을 각각 출력하세요.
* ** *** **** ------------ **** *** ** * ------------ **** *** ** * ------------ * ** *** ****
풀이방법은 다양하지만 다음과 같이 생각하면 편하다.
// 0123 3210
// 0 * *
// 1 ** **
// 2 *** ***
// 3 **** ****
// 3 **** ****
// 2 *** ***
// 1 ** **
// 0 * *
void show_star()
{
for (int i = 0; i <= 3; i++)
{
for (int j = 0; j <= 3; j++)
{
if (i >= j)
printf("*");
else
printf(" ");
}
printf("\n");
}
for (int i = 3; i >= 0; i--)
{
for (int j = 0; j <= 3; j++)
{
if (i >= j)
printf("*");
else
printf(" ");
}
printf("\n");
}
for (int i = 3; i >= 0; i--)
{
for (int j = 3; j >= 0; j--)
{
if (i >= j)
printf("*");
else
printf(" ");
}
printf("\n");
}
for (int i = 0; i <= 3; i++)
{
for (int j = 3; j >= 0; j--)
{
if (i >= j)
printf("*");
else
printf(" ");
}
printf("\n");
}
}
- 2d_array
#include <stdio.h>
void show_2d_array(int a[][5]);
int sum_2d_array(int a[][5]);
int main()
{
// 배열: 같은 자료형을 가진 값들 끼리 묶은 것
int a[3][5] = {
{1, 2, 3, 4, 5},
{6, 7, 8, 9, 10},
{11, 12, 13, 14, 15}}; // 3개 배열
int(*b)[5] = a;
a[0][0] = 99;
b[2][4] = -1;
printf("%d\n", a); // 주소 6422240
printf("%d\n", a[0]); // 주소 6422240
printf("%d\n", a[0][0]); // 99
printf("%d\n", &a[0][0]); // 주소 6422240
printf("%d\n", &a[0][1]); // 주소 6422244
printf("%d\n", &a[1][0]); // 주소 6422260
show_2d_array(a);
printf("sum : %d\n", sum_2d_array(a));
printf("sum : %d\n", sum_2d_array(*&a));
printf("sum : %d\n", sum_2d_array(&a[0]));
int n = 3;
int *p = &n;
int **q = &p;
int ***r = &q;
printf("%d\n", *p);
printf("%d\n", **q);
printf("%d\n", ***r);
return 0;
}
void show_2d_array(int a[][5])
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 5; j++)
{
printf("%d ", a[i][j]);
}
printf("\n");
}
}
int sum_2d_array(int a[][5])
{
int s = 0;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 5; j++)
{
s += a[i][j];
}
}
return s;
}
- file
#include <stdio.h>
void print_file_1();
int main()
{
print_file_1();
return 0;
}
// 텍스트: txt, csv, json, c, cpp, py, ...
// binary: exe, hwp, xls, ppt, jpg, ...
void print_file_1()
{
FILE *fp = fopen("poem.txt", "r");
// printf("%d\n", fp);
int ch;
// for (int i = 0; i < 1000; i++)
// {
// int ch = fgetc(fp);
// putchar(ch);
// }
// 퀴즈
// fgetc 함수를 사용해서 파일 전체를 출력하세요.
while (1)
{
ch = fgetc(fp);
if (ch == -1)
break;
putchar(ch);
}
fclose(fp);
}
- 2d_array
#include <stdio.h>
void show_array(int *p, int size);
int main()
{
int grid[3][4] = {
{0, 1, 2, 3},
{4, 5, 6, 7},
{8, 9, 10, 11}};
// 퀴즈
// 2차원 배열에서 n번째 요소를 출력하는 함수를 만드세요.
show_array(grid[0], 4);
show_array(grid[1], 4);
show_array(grid[2], 4);
show_array(&grid[2][0], 4);
// 퀴즈
// 2차원 배열을 출력하는 함수를 만드세요.
// 2차원 형식을 유지하지 말고, 한 줄로 출력해주세요.
show_array(grid[0], 12);
return 0;
}
void show_array(int *p, int size)
{
for (int i = 0; i < size; i++)
{
printf("%d ", p[i]);
}
printf("\n");
}
- file
#include <stdio.h>
#include <string.h>
void print_file_1();
void print_file_2();
void write_file_1();
void write_file_2();
void csv_file();
int main()
{
// print_file_1();
// print_file_2();
// write_file_1();
// write_file_2();
csv_file();
return 0;
}
// 텍스트: txt, csv, json, c, cpp, py, ...
// binary: exe, hwp, xls, ppt, jpg, ...
// 퀴즈
// fgetc 함수를 사용해서 파일 전체를 출력하세요.
void print_file_1()
{
FILE *fp = fopen("poem.txt", "r");
int ch;
while (1)
{
ch = fgetc(fp);
if (ch == -1)
break;
putchar(ch);
}
fclose(fp);
}
// 퀴즈
// fgets 함수를 사용해서 파일 전체를 출력하세요.
void print_file_2()
{
FILE *fp = fopen("poem.txt", "r");
char buf[256];
// char *p;
// while (1)
// {
// p = fgets(buf, sizeof(buf), fp);
// if (p == NULL)
// break;
// printf("%s", buf);
// }
while (fgets(buf, sizeof(buf), fp))
{
printf("%s", buf);
}
fclose(fp);
}
void write_file_1()
{
FILE *fp = fopen("sample.txt", "w");
for (int i = 0; i < 26; i++)
fputc('a' + i, fp);
fputc('\n', fp);
fputs("Friday, i am happy!", fp);
fclose(fp);
}
// 퀴즈
// 사용자가 exit을 입력할 때까지 입력한 모든 문자열을 파일에 저장해 보세요.
void write_file_2()
{
FILE *fp = fopen("sample.txt", "w");
char buf[256];
while (1)
{
scanf("%s", buf);
if (strcmp(buf, "exit") == 0)
break;
fputs(buf, fp);
fputc('\n', fp);
}
fclose(fp);
}
void csv_file()
{
FILE *fp_w = fopen("sample.csv", "w");
// printf("%d %lf %c %s\n", 3, 4.5, 'A', "ace");
// fprintf(fp_w, "%d,%lf,%c,%s\n", 3, 4.5, 'A', "ace");
// fprintf(fp_w, "%d,%lf,%c,%s\n", 1, 2.7, 'B', "bed");
char buf[256];
// 모든 자료형을 문자열로 변환할 수 있다.
sprintf(buf, "%d,%lf,%c,%s\n", 3, 4.5, 'A', "ace");
fputs(buf, fp_w);
sprintf(buf, "%d,%lf,%c,%s\n", 1, 2.7, 'B', "bed");
fputs(buf, fp_w);
fclose(fp_w);
FILE *fp_r = fopen("sample.csv", "r");
int a;
double b;
char c;
char d[256];
fscanf(fp_r, "%d,%lf,%c,%s", &a, &b, &c, &d);
printf("%d %lf %c %s\n", a, b, c, d);
fscanf(fp_r, "%d,%lf,%c,%s", &a, &b, &c, &d);
printf("%d %lf %c %s\n", a, b, c, d);
fclose(fp_r);
}
- Stack

#include <stdio.h>
// C -> 자료구조 -> C++
// 스택: 곽티슈, 프링글스, 변수 할당, 함수 호출, 무르기
int g_stack[256];
int g_top = 0; // 데이터가 들어가는 위치
void push(int n);
int pop();
int is_empty();
void show_array(int *p, int size);
int main()
{
push(1);
push(2);
push(3);
// 퀴즈
// 스택에 들어있는 모든 데이터를 출력하세요.
while (!is_empty())
{
printf("%d\n", pop());
}
// 퀴즈
// 스택을 사용해서 1차원 배열을 거꾸로 뒤집어보세요.
int orders[] = {5, 1, 8, 3, 4, 9, 2, 1};
int size = sizeof(orders) / sizeof(orders[0]);
for (int i = 0; i < size; i++)
{
push(orders[i]);
}
for (int i = 0; i < size; i++)
{
orders[i] = pop();
}
show_array(orders, size);
// 퀴즈
// 스택을 사용하지 말고 1차원 배열을 거꾸로 뒤집어보세요.
for (int i = 0; i < size / 2; i++)
{
int tmp = orders[i];
orders[i] = orders[size - 1 - i];
orders[size - 1 - i] = tmp;
}
show_array(orders, size);
return 0;
}
void push(int n)
{
g_stack[g_top++] = n;
}
int pop()
{
return g_stack[--g_top];
}
int is_empty()
{
return g_top == 0;
}
void show_array(int *p, int size)
{
for (int i = 0; i < size; i++)
{
printf("%d ", p[i]);
}
printf("\n");
}
- struct
#include <stdio.h>
// 관례적으로 대문자를 씀
struct POINT
{
int x, y;
};
struct RECT
{
struct POINT pt1, pt2;
};
void show_point(struct POINT pt);
struct POINT change_1();
void change_2(struct POINT *p);
int main()
{
struct POINT pt = {10, 20};
show_point(pt);
// 퀴즈
// scanf 함수를 통해 pt에 좌표를 입력 받아 보세요.
scanf("%d %d", &pt.x, &pt.y);
show_point(pt);
// 퀴즈
// POINT 구제의 x, y를 88, 99로 변경하는 함수를 만드세요.
pt = change_1();
show_point(pt);
change_2(&pt);
show_point(pt);
struct RECT rc = {{1, 2}, {3, 4}};
// 퀴즈
// RECT 구조체에 포함된 모든 값을 출력하세요.
printf("%d %d %d %d\n", rc.pt1.x, rc.pt1.y, rc.pt2.x, rc.pt2.y);
show_point(rc.pt1);
show_point(rc.pt2);
// 퀴즈
// p를 선언하고 p를 사용해서 RECT의 모든 값을 출력하세요.
struct RECT *p = &rc;
printf("%d %d %d %d\n", (*p).pt1.x, p->pt1.y, *(&(*p).pt2).x, (&p->pt2)->y);
return 0;
}
void show_point(struct POINT pt)
{
printf("%d %d\n", pt.x, pt.y);
}
struct POINT change_1()
{
struct POINT pt = {88, 99};
return pt;
}
void change_2(struct POINT *p)
{
// (*p).x = 88;
// (*p).y = 99;
p->x = 88;
p->y = 99;
}