1. 함수
함수의 작성과 사용
- 함수는 반복적으로 사용하는 코드를 묶어놓은 블록이다.
- C 언어에서 함수는 반환형, 함수 이름, 매개변수로 구성된다.
- 함수 정의를 통해 프로그램의 특정 기능을 캡슐화하고 코드의 재사용성을 높일 수 있다.
int add(int a, int b) {
return a + b;
}
- 위 코드는 int 타입의 값을 반환하는 add라는 함수로, 두 개의 정수를 더한 결과를 반환한다.
- 정의된 함수는 함수 이름(매개변수) 형식으로 호출한다.
- 함수가 호출되면 함수의 실행이 시작되며, return 키워드를 통해 결괏값을 반환한다.
int result = add(3, 4); // result는 7이 됨
- 함수 정의는 보통 main() 함수 아래에 위치하는데, 이 경우 컴파일러가 이를 미리 알 수 있도록 함수 선언을 먼저 해야 한다.
- 함수 선언은 함수의 반환형, 이름, 매개변수를 명시한 것으로 끝에 세미콜론(;)을 붙인다.
int add(int a, int b); // 함수 선언
여러 가지 함수 유형
- 매개변수가 없는 함수는 외부로부터 값을 받지 않고 자체적으로 동작한다.
void greet() {
printf("Hello, World!\n");
}
greet(); // Hello, World! 출력
- 반환값이 없는 함수는 void 반환형을 사용하며, 작업을 수행하더라도 반환값을 갖지 않는다.
void print_sum(int a, int b) {
printf("합계: %d\n", a + b);
}
print_sum(3, 4); // 합계: 7 출력
- 매개변수와 반환값이 모두 없는 함수는 데이터를 입력받지도, 결과를 반환하지도 않는다.
void print_message() {
printf("이것은 매개변수와 반환값이 없는 함수입니다.\n");
}
print_message();
- 재귀호출 함수는 함수가 자기 자신을 호출하는 형태로, 특정 문제를 더 작은 문제로 나누어 해결할 때 유용하다.
- 대표적인 예로 팩토리얼 계산이 있다.
int factorial(int n) {
if (n <= 1) return 1;
else return n * factorial(n - 1);
}
int result = factorial(5); // result는 120이 됨
- 재귀 호출은 코드의 가독성을 높이는 장점이 있지만, 깊은 호출로 인해 스택 오버플로가 발생할 수 있다.
- 반복문은 재귀보다 메모리 사용량이 적어 성능 면에서 더 효율적이다.
2. 배열
배열의 선언과 사용
- 배열은 동일한 자료형의 데이터 집합을 의미한다.
- 배열을 선언할 때는 자료형과 배열의 크기를 지정한다.
int numbers[5]; // 5개의 정수 저장 가능
- 배열은 선언과 동시에 초기화할 수 있다.
int numbers[5] = {1, 2, 3, 4, 5};
- 배열의 각 요소에 접근할 때는 반복문을 사용하는 것이 일반적이다.
for (int i = 0; i < 5; i++) {
printf("%d ", numbers[i]); // 1 2 3 4 5 출력
}
- sizeof 연산자를 사용하면 배열의 전체 크기와 각 요소의 크기를 구해 배열의 길이를 계산할 수 있다.
int length = sizeof(numbers) / sizeof(numbers[0]);
printf("배열의 길이: %d\n", length); // 출력: 5
문자를 저장하는 배열
- 문자 배열은 문자열을 저장하는 데 사용되며, 선언 시 초기화할 수 있다.
char greeting[] = "Hello";
- 문자 배열에 문자열을 대입할 때는 strcpy 함수를 사용해야 한다.
- 문자열을 직접 대입할 수 없다.
#include <string.h>
char greeting[10];
strcpy(greeting, "Hi");
- gets() 함수는 문자열을 입력받을 때 사용하며, puts() 함수는 문자열을 출력할 때 사용된다.
char name[20];
gets(name); // 사용자로부터 문자열 입력
puts(name); // 입력된 문자열 출력
- 문자열의 끝에는 항상 널 문자(\0)가 있어야 한다.
- 만약 널 문자가 없다면 문자열의 끝을 알 수 없으므로, 프로그램이 예기치 않은 동작을 하게 된다.
3. 포인터
포인터의 기본 개념
- 포인터는 변수의 메모리 주소를 저장하는 변수이다.
- 이를 통해 변수의 위치를 직접 참조하거나 조작할 수 있다.
- 주소 연산자 &는 변수의 메모리 주소를 구하는 데 사용된다.
int a = 10;
int *p = &a; // a의 주소를 p에 저장
- 간접 참조 연산자 *는 포인터가 가리키는 주소의 값을 참조한다.
- 이를 통해 포인터를 사용해 변수의 값을 간접적으로 접근할 수 있다.
printf("a의 값: %d\n", *p); // a의 값 출력: 10
- 포인터는 배열, 함수의 매개변수 등 여러 곳에서 다양하게 활용된다.
- 배열의 첫 번째 요소의 주소를 포인터에 저장해 배열을 순회할 수 있다.
int numbers[] = {1, 2, 3};
int *p = numbers;
for (int i = 0; i < 3; i++) {
printf("%d ", *(p + i)); // 1 2 3 출력
}
- const 키워드를 사용하여 포인터가 가리키는 값을 변경하지 못하도록 할 수 있다.
const int value = 100;
const int *p = &value;
// *p = 200; // 오류: const로 지정된 값을 변경할 수 없음
포인터 완전 정복을 위한 포인터 이해
- 주소는 메모리에서 변수의 위치를 나타내는 숫자이며, 포인터는 이 주소를 저장하는 변수이다.
- 포인터의 크기는 운영체제에 따라 달라지며, 보통 32비트 시스템에서는 4바이트, 64비트 시스템에서는 8바이트이다.
- 포인터 변수에 다른 자료형의 주소를 대입하려면 형변환이 필요하다.
- 예를 들어 int형 포인터에 float형 변수의 주소를 대입하려면 (int *)와 같은 형변환을 해야 한다.
- 포인터는 효율적인 메모리 사용, 함수 간의 데이터 공유, 동적 메모리 할당 등을 가능하게 한다.
- 특히, 배열과 문자열, 함수 인자 등을 다룰 때 매우 유용하다.
'IT & AI > AI 지식' 카테고리의 다른 글
C 언어 변수, 다차원 배열, 응용 포인터 정리 (1) | 2024.11.19 |
---|---|
C 언어 배열, 포인터, 문자열 활용 심화 (0) | 2024.11.19 |
C 언어 연산자와 제어문 총정리 (0) | 2024.11.18 |
C 언어 기본 개념과 프로그램 구조, 변수, 상수, 데이터 입력과 출력 (1) | 2024.11.17 |
파이썬 활용 (2): 클로저, 제너레이터, 정규 표현식 (2) | 2024.11.15 |