포인터란 다른 변수의 주소를 저장하는 변수입니다. 즉, 포인터는 "값"이 아닌 "주소"를 가리킵니다.
int a = 10;
int *p = &a; // p는 변수 a의 주소를 저장함
a는 정수형 변수
&a는 변수 a의 주소를 의미
*p는 포인터가 가리키는 주소에 저장된 값을 의미 (역참조)
int num = 100;
int *ptr = #
printf("num의 값: %d\n", num); // 100
printf("ptr이 가리키는 값: %d\n", *ptr); // 100
printf("ptr의 주소값: %p\n", ptr); // num의 주소
포인터는 배열과 밀접한 관계가 있습니다.
int arr[3] = {1, 2, 3};
int *p = arr;
printf("%d\n", *p); // 1
printf("%d\n", *(p+1)); // 2
배열 이름 arr 자체가 첫 번째 요소의 주소 (&arr[0])로 작동
*(p + i)는 arr[i]와 동일
void swap(int *x, int *y) {
int temp = *x;
*x = *y;
*y = temp;
}
int main() {
int a = 5, b = 10;
swap(&a, &b);
printf("a = %d, b = %d\n", a, b); // a = 10, b = 5
}
포인터를 통해 함수 내에서 원본 값을 바꿀 수 있음 (참조에 의한 호출)
int val = 20;
int *p = &val;
int **pp = &p;
printf("%d\n", **pp); // 20
동적 메모리 할당 시 메모리의 주소를 함수에서 반환하려면 이중 포인터가 필요함
#include <stdio.h>
#include <stdlib.h>
void allocateMemory(int **ptr) {
*ptr = (int *)malloc(sizeof(int)); // 메모리 할당
if (*ptr != NULL) {
**ptr = 1234; // 값 저장
}
}
int main() {
int *p = NULL;
allocateMemory(&p); // 포인터의 주소 전달 (이중 포인터 사용)
if (p != NULL) {
printf("할당된 메모리의 값: %d\n", *p); // 1234 출력
free(p); // 메모리 해제
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main() {
int *p = (int *)malloc(sizeof(int));
*p = 42;
printf("%d\n", *p);
free(p);
}
malloc은 힙 영역에 메모리 공간을 동적으로 할당
사용이 끝난 후 반드시 free로 해제해야 메모리 누수 방지 가능
char *str = "Hello";
printf("%c\n", *str); // 'H'
printf("%s\n", str); // "Hello"
char *ptrs[3]; // 포인터들의 배열
int (*ptr)[3]; // 정수 배열을 가리키는 포인터
int p[3] ==> int를 가리키는 포인터 3개
int (p)[3] ==> int 3개짜리 배열 1개를 가리키는 포인터
int arr[5];
int *p = arr;
sizeof(arr); // 20 (5 * sizeof(int))
sizeof(p); // 4 or 8 (포인터 크기, 시스템 의존)
배열은 고정 크기를 가지지만 포인터는 주소만 참조
배열의 이름은 포인터처럼 쓰일 수 있으나 완전히 동일하지는 않음
struct Point {
int x, y;
};
struct Point p = {1, 2};
struct Point *ptr = &p;
printf("%d\n", ptr->x); // 1
#include <stdio.h>
#include <string.h>
struct Student {
int id;
char name[20];
float grade;
};
void printStudent(struct Student s) {
printf("학번: %d\n", s.id);
printf("이름: %s\n", s.name);
printf("성적: %.2f\n", s.grade);
}
int main() {
struct Student s1;
s1.id = 2023202042;
strcpy(s1.name, "김현우");
s1.grade = 93.5;
printStudent(s1);
return 0;
}
struct Student students[3]; // 여러 학생 저장 가능
struct Student *sp = &s1; // 구조체 포인터로 접근
printf("%s\n", sp->name); // -> 연산자 사용
int *p;
{
int a = 10;
p = &a;
} // a는 여기서 소멸됨
printf("%d\n", *p); // 잘못된 접근 → 정의되지 않은 동작
스코프 밖으로 나간 지역변수의 주소를 사용하면 댕글링 포인터
free() 후에도 해당 포인터를 계속 사용하면 동일한 문제가 발생
정수형 변수 하나를 선언하고, 해당 변수의 주소를 포인터에 저장합니다. 이후 포인터를 통해 변수의 값을 변경합니다. 포인터를 통해 변수의 값을 읽고 쓸 수 있다는 개념을 익히는 데 초점을 둡니다.
요구 사항:
변수 a에 값 10을 저장
포인터 p에 a의 주소 저장
*p를 통해 a의 값을 20으로 변경
변경 전후의 a 값 출력
정수형 배열을 선언한 뒤, 배열 이름을 포인터처럼 사용해 배열 요소에 접근합니다. 포인터 산술 연산(p + i)을 사용하여 각 요소에 접근하며 출력합니다.
요구 사항:
정수 배열 arr에 1, 2, 3 저장
포인터 p를 arr로 초기화
반복문을 사용하여 *(p + i)로 배열 요소 출력
세 개의 정수 중 가장 큰 값을 첫 번째 변수에 저장되도록 포인터를 활용하여 reorder_max_first() 함수를 작성합니다. 단순한 swap보다 논리적 분기가 포함되며, 포인터로 다수의 값을 비교/수정하는 패턴을 학습합니다.
요구 사항:
int a, b, c를 인자로 받아
세 변수 중 가장 큰 값을 a에 위치시키고 나머지 두 값은 그대로 둠
예: a=3, b=7, c=5 → a=7, b=3, c=5
main() 함수에서 세 변수의 주소를 전달
함수 호출 전/후 세 값 출력
학생 5명의 정보를 구조체 배열로 저장하고, 학생의 ID로 검색했을 때 해당 학생의 이름과 점수를 출력하는 프로그램입니다. 포인터 연산을 통해 구조체 배열을 탐색하며, 포인터와 배열, 구조체의 결합을 학습합니다.
요구 사항:
struct Student { int id; char name[20]; float grade; }
5명의 정보를 구조체 배열에 저장
ID를 입력받고, 포인터를 사용해 배열을 선형 탐색
일치하는 학생이 있으면 이름과 성적 출력, 없으면 "찾을 수 없음"
사용자에게 행과 열의 개수를 입력받아, malloc()을 사용해 동적으로 2차원 배열을 생성합니다. 각 원소를 사용자에게 입력받고, 평균을 계산한 뒤, 메모리를 해제합니다. 중첩 포인터 int **matrix를 이용한 메모리 할당/접근 패턴을 학습합니다.
요구 사항:
사용자로부터 행(row), 열(col) 수 입력받기
int **matrix를 사용해 2차원 배열 동적 생성
각 원소 입력받아 저장
전체 평균 계산 및 출력
free()로 모든 동적 메모리 해제
char **words를 사용해 문자열 3개를 저장하는 프로그램을 작성합니다. 각 문자열을 malloc()으로 동적 할당한 뒤 내용을 복사하고, 모든 문자열을 출력합니다. 이중 포인터를 통해 다수의 문자열을 동적으로 처리하는 패턴을 학습합니다.
요구 사항:
char **words를 선언하여 문자열 3개 저장
각 문자열 공간을 malloc()으로 확보하고, strcpy()로 값 복사
반복문으로 문자열 전체 출력
free()로 각 문자열 및 words 자체 해제
구조체, 포인터, 배열, 동적 메모리 할당, 함수 호출 시 포인터 전달 등의 개념을 실전 문제에 종합적으로 적용할 수 있는지 평가합니다.
당신은 편의점 포스기 소프트웨어를 개발 중입니다. 사용자는 여러 상품을 입력하고 결제를 진행할 수 있어야 합니다. 아래의 조건을 만족하는 프로그램을 작성하세요.
상품 구조체 정의
struct Item 구조체는 다음 멤버를 포함합니다:
char name[30] : 상품 이름
int price : 가격
int quantity : 수량
사용자에게 구매할 상품 개수(N)를 입력받고, 동적으로 구조체 배열을 할당하여 상품 정보를 입력받습니다.
int calculateTotal(struct Item *items, int count) 함수를 작성하여, 총 결제 금액을 계산합니다.
void printReceipt(struct Item *items, int count) 함수를 작성하여 아래와 같은 형태로 영수증을 출력합니다.
--- 영수증 ---
1. 콜라 x2 = 3000원
2. 과자 x1 = 1500원
총액: 4500원
malloc을 사용한 만큼 free()를 사용해 동적 메모리를 모두 해제하세요.