불필요한 반복 제거
특정 기능 추가 및 사용
#include <stdio.h>
#define WIDTH 20 // 기호적 상수 WIDTH 선언
#define NAME "Tae-Il Nam" // 기호적 상수 NAME 선언
#define ADDRESS "Seoul, Korea" // 기호적 상수 ADDRESS 선언
int main()
{
for (int i = 0; i < WIDTH; ++i) // WIDTH 값(20) 만큼 for문 실행. 아래 for문과 동일.
printf("*");
printf("\n");
printf(" %s \n", NAME); // NAME 값 출력.
printf(" %s \n", ADDRESS); // ADDRESS 값 출력.
for (int i = 0; i < WIDTH; ++i) // WIDTH 값(20) 만큼 for문 실행. 위 for문과 동일.
printf("*");
printf("\n");
return 0;
}
#include <stdio.h>
#define WIDTH 20
#define NAME "Tae-Il Nam"
#define ADDRESS "Seoul, Korea"
void print_star(int n_star) // print_star 함수 정의 (정수형 매개변수 = n_star)
{
for (int i = 0; i < n_star; ++i) // n_star 값(20) 만큼 for문 실행.
printf("*");
printf("\n");
}
int main()
{
print_star(WIDTH); // print_star 함수 호출. 매개변수에 WIDTH 값(20) 전달.
printf(" %s \n", NAME);
printf(" %s \n", ADDRESS);
print_star(WIDTH); // print_star 함수 호출. 매개변수에 WIDTH 값(20) 전달.
return 0;
}
#include <stdio.h>
#define WIDTH 20
#define NAME "Tae-Il Nam"
#define ADDRESS "Seoul, Korea"
void print_star(int n_star) // 매개변수 = (int n_star).
{
for (int i = 0; i < n_star; ++i)
printf("*");
printf("\n");
}
int main()
{
print_star(WIDTH); // print_star 함수 호출. 인수 = WIDTH(20).
printf(" %s \n", NAME);
printf(" %s \n", ADDRESS);
print_star(WIDTH); // print_star 함수 호출. 인수 = WIDTH(20).
return 0;
}
💡 함수의 내용 없이 프로토타입만 선언 한다면? (링킹 에러)
- 컴파일에러는 발생하지 않으나 링킹 과정에서 에러 발생.
- 컴파일러는 프로토타입이 있으니 함수가 있을 것이라고 판단.
- 실제로 함수의 내용을 프로토타입과 매핑하는 링킹 과정에서, 함수의 내용을 찾지 못해 에러 발생.
#include <stdio.h>
#define WIDTH 20
#define NAME "Tae-Il Nam"
#define ADDRESS "Seoul, Korea"
void print_star(int n_star); // print_star 함수의 프로토타입. (세미콜론';' 입력 필수)
int main()
{
print_star(WIDTH);
printf(" %s \n", NAME);
printf(" %s \n", ADDRESS);
print_star(WIDTH);
return 0;
}
void print_star(int n_star) // print_star 함수 내용.
{
for (int i = 0; i < n_star; ++i)
printf("*");
printf("\n");
}
#include <stdio.h>
int print_sum(int n1, int n2); // print_sum 함수의 프로토타입.
int main()
{
int a = 1;
int b = 2;
printf("%d", print_sum(a, b));
return 0; // main() 함수의 반환값 = 0.
}
int print_sum(int n1, int n2) // print_sum 함수 정의.
{
int sum = n1 + n2; // 매개변수 n1, n2를 더하고 정수형 변수 sum에 대입.
return sum; // print_sum 함수의 반환값 = sum의 값(정수).
}
#include <stdio.h>
#define WIDTH 20
#define NAME "Tae-Il Nam"
#define ADDRESS "Seoul, Korea"
void print_star(int n_star);
int main() // main() 함수의 반환값(return) 자료형 = int
{
print_star(WIDTH);
printf(" %s \n", NAME);
printf(" %s \n", ADDRESS);
print_star(WIDTH);
return 0; // main() 함수의 반환값 = 0(정수).
}
void print_star(int n_star) // 반환값(return)이 없는 함수의 반환값 자료형 = void.
{
for (int i = 0; i < n_star; ++i)
printf("*");
printf("\n");
}
#include <stdio.h>
int main()
{
int a = 1; // main() 함수의 지역 변수 a 선언.
printf("%d\n", a); // main() 영역의 변수 a의 값 출력.
printf("%p\n", a); // main() 영역의 변수 a의 실제 Memory 주소 출력.(포인터)
{ // 내부 영역 추가.
int a = 2; // 내부 영역의 지역 변수 a 선언.
printf("%d\n", a); // 내부 영역의 변수 a의 값 출력.
printf("%p\n", a); // 내부 영역의 변수 a의 실제 Memory 주소 출력.(포인터)
}
printf("%d\n", a); // main() 영역의 변수 a의 값 출력.
printf("%p\n", a); // main() 영역의 변수 a의 실제 Memory 주소 출력.(포인터)
return 0;
}
💡 프로그램을 실행할 때마다 Memory 주소가 달라지는 이유.
- 프로그램 실행시, 운영체제(OS)가 그때그때 상황에 맞게 변수의 Memory 주소 할당.
#include <stdio.h>
void my_func(int n); // my_func 함수 프로토타입.
int main()
{
my_func(1); //my_func 함수 호출.
return 0;
}
void my_func(int n)
{
printf("Level %d, address of variable n = %p\n", n, &n); // n의 값과 Memory 주소 출력.
if (n <= 4) n이 4보다 작거나 같을 때까지
my_func(n + 1); // 매개 변수에 1을 더해서 재귀 호출.
}
#include <stdio.h>
/*
factorial : 3! = 3 * 2 * 1
5! = 5 * 4!
0! = 1
*/
long loop_factorial(int n); // 반복문 함수.
long recursive_factorial(int n); // 재귀 호출 함수.
int main()
{
int num = 5;
printf("%d\n", loop_factorial(num));
printf("%d\n", recursive_factorial(num));
return 0;
}
long loop_factorial(int n)
{
long sum = 1;
for (int i = 1; i <= n; ++i)
sum *= i;
return sum;
}
long recursive_factorial(int n)
{
if (n > 0) // n이 0보다 클 경우.
{
return n * recursive_factorial(n - 1); // n 이 0이 될 때까지 재귀 호출.
}
else
return 1;
}
#include <stdio.h>
int fibonacci(int number); // fibonacci 함수 프로토타입.
int main()
{
for (int count = 1; count < 13; ++count)
printf("%d ", fibonacci(count));
return 0;
}
int fibonacci(int number)
{
if (number > 2) // number 값이 2보다 큰 경우.
return fibonacci(number - 1) + fibonacci(number - 2);
else
return 1; // number 값이 2보다 작거나 같은 경우.
}
#include <stdio.h>
int main()
{
int a; // 정수가 저장될 4바이트 memory 공간을 변수 a에 할당.
int b; // 정수가 저장될 4바이트 memory 공간을 변수 b에 할당.
int c; // 정수가 저장될 4바이트 memory 공간을 변수 c에 할당.
a = 7; // a라는 4바이트 memory 공간에 정수 7 저장.
b = 8; // b라는 4바이트 memory 공간에 정수 8 저장.
c = a + b; // c라는 4바이트 memory 공간에 정수 a + b 연산 값 저장.
return 0;
}
1. 포인터 변수
- memory 주소 값을 저장하는 변수.
- 변수 선언시 앞에 '*' 기입. (Asterisk)
- 포인터 변수의 자료형은, memory 주소를 가져올 대상 변수의 자료형과 동일해야 함.
- 포인터 변수도 값 저장을 위한 memory 공간을 가짐.
2. 주소 연산자(Address-of operator)
- '&' 를 변수 앞에 기입.
- 변수의 실제 memory 주소 값 반환.
#include <stdio.h>
int main()
{
int a = 7;
int *a_ptr = &a; // 포인터 변수 a_ptr 에 a의 memory 주소 값 대입.
// 변수 a의 자료형이 int 이므로, 포인터 변수 자료형도 동일하게 int로 지정.
return 0;
}
#include <stdio.h>
int main()
{
int a = 7;
int *a_ptr = &a; // 포인터 변수 a_ptr 에 변수 a의 memory 주소 값 대입.
*a_ptr = 8; // 변수 a의 memory 주소에 해당하는 공간에 8 대입.
printf("%d", a); // 변수 a 값 출력 = 8.
return 0;
}
#include <stdio.h>
int main()
{
int a, b; // 정수형 변수 a, b 선언.
a = 123; // 변수 a에 값 123 대입.
int* a_ptr; // 포인터 변수 a_ptr 선언. * : asterisk
a_ptr = &a; // 포인터 변수 a_ptr에 변수 a의 memory 주소 대입. & : address-of operator
printf("%d %d %p\n", a, *a_ptr, a_ptr);
// 변수 a의 값, 포인터 변수 a_ptr의 indirect 값(변수 a의 값), 포인터 변수 a_ptr의 값(memory 주소) 출력.
// 포인터 변수의 값(memory 주소)을 출력하기 위한 형식지정자 = %p.
*a_ptr = 314; // 변수 a의 memory 주소에 해당하는 공간에 314 대입.
printf("%d %d %p\n", a, *a_ptr, a_ptr);
// 변수 a의 값, 포인터 변수 a_ptr의 indirect 값(변수 a의 값), 포인터 변수 a_ptr의 값(memory 주소) 출력.
return 0;
}
#include <stdio.h>
int main()
{
int* a; // 자료형 쪽에 '*' 기입.
int* b; // 자료형 쪽에 '*' 기입.
return 0;
}
#include <stdio.h>
int main()
{
int *a; // 변수명 쪽에 '*' 기입.
int *b; // 변수명 쪽에 '*' 기입.
return 0;
}
#include <stdio.h>
int main()
{
int* a = NULL; // 포인터 변수 a의 값을 NULL로 초기화.
int* b = NULL; // 포인터 변수 b의 값을 NULL로 초기화.
return 0;
}
#include <stdio.h>
int main()
{
char a; // 1 바이트 크기의 정수형 변수 a 선언.
float b; // 4 바이트 크기의 실수형 변수 b 선언.
double c; // 8 바이트 크기의 실수형 변수 c 선언.
char* ptr_a = &a; // 변수 a의 memory 주소를 포인터 변수 ptr_a 에 대입.
float* ptr_b = &b; // 변수 b의 memory 주소를 포인터 변수 ptr_b 에 대입.
double* ptr_c = &c; // 변수 c의 memory 주소를 포인터 변수 ptr_c 에 대입.
printf("%zd %zd %zd\n", sizeof(a), sizeof(b), sizeof(c)); // 변수 a, b, c의 memory 크기 출력.
printf("%zd %zd %zd\n", sizeof(ptr_a), sizeof(ptr_b), sizeof(ptr_c)); // 포인터 변수 ptr_a, ptr_b, ptr_c의 memory 크기 출력.
printf("%zd %zd %zd\n", sizeof(&a), sizeof(&b), sizeof(&c)); // 변수 a, b, c의 포인터 memory 크기 출력.
printf("%zd %zd %zd\n", sizeof(char*), sizeof(float*), sizeof(double*)); // 포인터 변수 char, float, double의 memory 크기 출력.
return 0;
}
#include <stdio.h>
void swap(int* a_ptr, int* b_ptr) // 변수 a, b의 값을 바꿔주는 swap() 함수 정의.
{ // 포인터형 매개변수로 a, b의 주소 값을 받음.
int temp = *a_ptr; // temp 변수에 변수 a의 값 대입.
*a_ptr = *b_ptr; // 변수 a에 변수 b의 값 대입.
*b_ptr = temp; // 변수 b에 변수 temp의 값 대입.
}
int main()
{
int a = 123; // 정수형 변수 a 초기화 = 123.
int b = 456; // 정수형 변수 b 초기화 = 456.
swap(&a, &b); // swap() 함수 호출. 인자 = 변수 a, b의 주소값.
printf("%d %d\n", a, b); // 변수 a, b의 값 출력.
return 0;
}
🚩 출처 및 참고자료 : 홍정모의 따라하며 배우는 C 언어 (따배씨)