1. 문자열 비교(strcmp) - string compare
strcmp(ineq, ">") == 0
- if(ineq == “>”) 안됨!!
- C에서는 문자열을 == 로 비교하면 주소 비교라서 안됨. 내용 비교는 반드시 strcmp() 사용
2. 문자열 붙이기(strcat) - string catenate
#include <string.h>
char str[100] = "Hello ";
strcat(str, "world!");
3. int ↔ char (sprintf) / char ↔ int 변환 (atoi)
'0' + num
sprintf(str, "%d", num);
sprintf(str, "%d%d", a, b)
atoi(str)
4. 문자열 복사 - strdup()
strdup() 은 문자열을 복사해서 새로운 메모리 공간에 저장하는 함수
char* strdup(const char* s);
5. qsort() 란?
void qsort(void* base, size_t nitems, int (*compar)(const void*, const void*));
- 매개변수 하나씩 설명
base : 정렬할 배열의 시작 주소
nitems : 배열의 요소 개수
size : 배열 하나당 요소 크기 (바이트)
compar : 정렬 기준이 담긴 함수 포인터 (비교 함수)
- 예제 1: 숫자 배열 오름차순 정렬
#include <stdio.h>
#include <stdlib.h>
int cmp(const void* a, const void* b) {
return (*(int*)a - *(int*)b);
}
int main() {
int arr[] = {5, 3, 2, 4, 1};
int len = sizeof(arr) / sizeof(arr[0]);
qsort(arr, len, sizeof(int), cmp);
for (int i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
}
int cmp_str(const void* a, const void* b) {
return strcmp(*(char**)a, *(char**)b);
}
char* words[] = {"banana", "apple", "cherry"};
qsort(words, 3, sizeof(char*), cmp_str);
int cmp(const void* a, const void* b) {
}
6. 포인터 VS 배열
🔁 정리 비교표
| 표현 | 의미 | 변경 가능? | 메모리 위치 |
|---|
"abc" | 문자열 리터럴 | ❌ 읽기 전용 | 상수 영역 (Read-Only) |
char* str = "abc"; | 문자열 리터럴을 가리키는 포인터 | ❌ | 읽기 전용 영역 |
char str[] = "abc"; | 문자열을 복사한 배열 | ✅ | 스택 영역 (또는 데이터 영역) |
문자열 리터럴을 수정하고 싶을 때?
char* src = "abc";
char str[10];
strcpy(str, src);
srt[0] = 'x';
char* src = "abc";
char* str = (char*)malloc(strlen(src)+1);
strcpy(str, src);
str[0] = 'x'
7. C 문자열/포인터/배열 정리 (헷갈렸던 포인트 중심)
char* a = "abc";
printf("%c", a[0]);
- 포인터도 배열처럼 a[i] 사용 가능 (포인터 산술 *(a+i))
char* arr[3] = {"a", "b", "c"}
printf("%s", arr[0]);
printf("%c", arr[1][0]);
- %s : 널 문자(\0)로 끝나는 문자열의 시작 주소를 받아서, 그 주소부터 하나씩 문자 출력
malloc은 바이트 단위 ⇒ 최소화!!!!!!
- malloc? memory(메모리) + allocation(할당) ⇒ 필요한 만큼 메모리를 동적으로 빌려주는 함
- 할당 후에는 꼭 free()로 해제 → 안하면 메모리 누수 생김!
- 동적으로 사이즈 조절도 가넝
char* str = malloc(10);
int* arr = malloc(sizeof(int) * N);
int* arr = malloc(10);
- malloc(N)은 N 바이트 → int 배열이라면
sizeof(int) * N 필요
왜 C는 포인터를 많이 쓸까??
- C는 하드웨어에 가까운 언어라서, 메모리를 직접 다루는 게 설계 철학이고 그걸 가능하게 해주는 도구가 바로
포인터 이다.
💡
1. C는 메모리를 “주소”로 다루는 언어
- 모든 변수는 메모리에 저장되고, 그 메모리는 주소로 접근
- 포인터는 그 주소를 직접 조작하거나 전달할 수 있는 도구
int x = 10;
int* p - &x;
2. 값을 복사하지 않고, 직접 “참조”할 수 있음
void modify (int* arr) {
arr[0] = 100;
}
- 배열 자체를 복사하면 느리고 비효율적이니까 주소를 넘겨서 원본을 찹조하게 만든다. → 성능, 메모리 효율, 직접 조작 모두 가능!!
3. C에는 “문자열 타입”이 없음 → 포인터로 다룸
- char str[] = “hello”; 는 사실상 char*로 동작함
- 문자열은 그냥 문자들의 배열이고, C는 배열을 넘기면 포인터로 취급
void print(const char* str) {
printf("%s\n", str);
}
4. 동적 메모리 할당이 전부 포인터 기반
malloc() 은 메모리를 런타임에 직접 확보
- 확보된 메모리는 주소값(포인터)로만 접근 가능
int* p = malloc(sizeof(int) * 10);
5. C에서 함수는 리턴값을 하나만 줄 수 있다.
void getSize(int* width, int* height) {
*width = 1920;
*height = 1080;
}
int main() {
int w, h;
getSize(&w, &h);
printf("%d x %d\n", w, h);
}
- 포인터는 ‘주소’를 담는 변수다!!!!!!!!!!
[ 값의 복사 ]
| 개념 | C | Java |
|---|
| 기본형 전달 | 값 복사 | 값 복사 |
| 배열/객체 전달 | 포인터(주소)를 직접 전달 | 참조값을 복사해서 전달 |
| 원본 변경 가능? | 포인터 쓰면 가능 | 참조값을 통해 내부는 변경 가능 |
| 원본 자체 교체 가능? | 가능 (*x = ...) | 불가능 (참조 자체는 복사본) |