ex.250512 공부노트 - Hwanghyewon06/c- GitHub Wiki
#include <stdio.h>
int main()
{
int n = 10;
int n2 = n;
int* p = &n;
int* p2 = p;
}
- **정수형 변수
n
**을 선언하고 값 10을 저장합니다. - 이 변수는 스택 메모리(stack)에 저장됩니다.
- 예)
n
의 주소가0x100
이라면,n
에는 10이라는 값이 저장됨.
n (주소: 0x100) → 10
-
n
의 값을 복사하여 **새로운 변수n2
**에 저장합니다. -
n2
도 스택에 저장되며,n
과는 완전히 독립된 메모리 공간을 가집니다. - 즉,
n2
를 바꿔도n
은 영향을 받지 않습니다.
n2 (주소: 0x104) → 10
-
p
는int
형을 가리키는 포인터 변수입니다. -
&n
은n
의 주소값 (예:0x100
)이므로,p
에는n
의 주소가 저장됩니다. -
*p
를 사용하면n
의 값(10)에 접근할 수 있습니다.
p (주소: 0x108) → 0x100 (n의 주소)
*p → 10
-
p2
도int
형 포인터입니다. -
p
가 가리키는 주소(즉,n
의 주소)를 그대로 복사해 저장합니다. - 따라서
p2
도n
을 가리키며,*p2 == 10
입니다.
p2 (주소: 0x10C) → 0x100 (n의 주소)
*p2 → 10
[ 변수명 ] [ 메모리 주소 ] [ 저장값 ] [ 의미 ]
-------------------------------------------------------------
n 0x100 10 정수 값
n2 0x104 10 n의 값 복사
p 0x108 0x100 n의 주소
p2 0x10C 0x100 p의 값 복사 (역시 n의 주소)
항목 | 설명 |
---|---|
n |
정수 변수, 값 10 저장 |
n2 = n |
n 의 값을 복사한 독립 변수 |
p = &n |
포인터 p 가 변수 n 의 주소를 가짐 |
p2 = p |
포인터 p2 가 p 와 같은 주소(n의 주소)를 가짐 |
*p , *p2
|
모두 n 의 값을 간접적으로 참조 (10) |
✅ 1. char와 문자열 처리, 아스키 코드
🔹 예제 코드
char* s = "ABC";
printf("%c %d\n", s[0], s[0]); // A 65
🔸 개념 설명
char는 1바이트(8비트)의 정수형 타입으로, 문자를 저장합니다.
C 언어에서 문자열은 char 배열로 표현되며, 마지막에는 항상 '\0' (NULL 문자)로 끝남.
"ABC"는 다음과 같이 저장됨:
+----+----+----+----+
| A | B | C | \0 |
+----+----+----+----+
주소: s s+1 s+2 s+3
s[0] == 'A', 'A'의 아스키 코드값은 65입니다.
✅ 2. 포인터의 기본 개념과 문자열 포인터 🔹 예제 코드
char* s = "ABC";
printf("%s\n", s); // ABC
printf("%s\n", s + 1); // BC
🔸 개념 설명
char* s는 문자열 상수 "ABC"의 시작 주소를 가리키는 포인터입니다.
s + 1 → 포인터 연산으로 한 문자(1바이트) 뒤를 가리킵니다. 즉, "ABC"의 두 번째 문자 'B'부터 출력 → "BC"
✅ 3. 문자열을 아스키 값으로 출력 🔹 예제 코드
void PrintStringToAscii(char* s1)
{
for (int i = 0; s1[i] != '\0'; ++i)
printf("%c : %d\n", s1[i], s1[i]);
}
🔸 개념 설명
각 문자를 반복문으로 접근하여 출력
%c는 문자, %d는 해당 문자의 아스키 코드 (정수값)
예: "ABC" →
A : 65 B : 66 C : 67
✅ 4. double 자료형과 포인터 연산 🔹 예제 코드
double da[4] = { 1.1, 2.2, 3.3, 4.4 };
double* pd = &da[1];
printf("%g %g\n", da[1], pd[0]);
// 2.2 2.2
printf("%g %g\n", da[2], pd[1]);
// 3.3 3.3
🔸 개념 설명
double은 실수형 타입 (8바이트)
double* pd = &da[1]는 da[1] 즉 2.2의 주소를 가리킴
pd[1] == *(pd + 1) == da[2] == 3.3
포인터 연산에서 pd + 1은 8바이트 뒤 주소로 이동
✅ 5. 배열과 포인터 차이 🔹 예제 코드 char* s = "ABC"; char arr[4] = "ABC"; 🔸 개념 설명
특성 포인터 (s) 배열 (arr)
메모리 할당 코드 영역
(읽기 전용) 스택 메모리 수정 가능성 X
(컴파일러 경고/에러 발생 가능) O (가능)
크기 포인터 자체는 8바이트 (x64 기준)
데이터 크기 만큼 (여기선 4바이트)
"ABC"는 컴파일 시 메모리에 상수로 저장됨
포인터는 문자열의 첫 글자 주소만 저장함
배열은 실제 문자열을 스택에 복사함
✅ 6. 포인터 연산 및 주소 출력 🔹 예제 코드
int n = 10;
int* p = &n;
printf("%p %p\n", &n, p);
printf("%p %p\n", &n + 1, p + 1);
🔸 개념 설명
%p는 주소 출력
p + 1은 sizeof(int)(보통 4바이트) 만큼 주소 증가
p + 1은 실제 메모리 상에서 4바이트 다음 위치를 가리킴
✅ 7. 포인터 다양성 — char*, int*, double*
포인터 타입
단위 연산 크기 (p + 1) 설명
char* 1바이트 문자열,
문자 배열 처리
int* 4바이트 (보통) 정수 배열 처리
double* 8바이트 실수 배열 처리
배열 이름은 주소
arr[0]의 주소는 &arr[0]
arr == &arr[0]
포인터와 배열의 공통점
arr[i] == *(arr + i)
p[i] == *(p + i) (포인터도 인덱스로 사용 가능)
✅ 8. 문자와 정수의 연관성 (아스키 코드) 🔹 예제 코드 int n1 = 65;
int n2 = 'A';
printf("%d %d\n", n1, n2); // 65 65
printf("%c %c\n", n1, n2); // A A
🔸 개념 설명
문자 'A'는 내부적으로 정수 65로 저장됨
%d → 정수로 출력
%c → 문자로 출력
따라서 int와 char는 변환이 가능 (단, 범위에 주의)
✅ 9. 요약 — 개념별 핵심 정리 개념 설명 char 1바이트 문자 자료형, 문자열 구성 double 8바이트 실수 자료형 포인터
변수(또는 배열)의 주소 저장 배열 이름 배열의 첫 요소 주소 (arr == &arr[0])
아스키 코드 문자를 정수로 표현하는 시스템 ('A' == 65)
포인터 연산 p + 1은 타입 크기만큼 이동
(int*은 4바이트 증가) 문자열 char 배열 + 마지막에 \0 포함
%c %d %p %s 각각 문자, 정수, 주소, 문자열 출력 포맷
좋습니다! 아래는 코드에 등장하는 각 자료형, 포인터, 메모리 구조를 중심으로 기초부터 정확하게 설명한 내용입니다. 배열과 포인터가 메모리에서 어떻게 동작하는지를 시각적으로 이해할 수 있게 정리했습니다.
#include <stdio.h>
int main()
{
char arr[3] = { 10, 20 ,30 };
double darr[4] = { 10.1, 20.2, 30.3, 40.4 };
char* pc = &arr[0];
double* pd = &darr[0];
}
-
char
타입은 1바이트 크기의 정수형 자료형입니다. -
arr
는 크기 3인 문자형 배열이며, 메모리에 연속적으로 저장됩니다. - 배열 초기값:
arr[0] = 10
,arr[1] = 20
,arr[2] = 30
예를 들어 메모리 구조는 이렇게 될 수 있습니다 (주소는 예시):
주소 값
0x100 10 ← arr[0]
0x101 20 ← arr[1]
0x102 30 ← arr[2]
-
double
타입은 8바이트 크기의 실수형 자료형입니다. -
darr
는 4개의 실수형 데이터를 저장하는 배열이며, 각 요소는 8바이트씩 차지합니다.
예시 메모리 구조:
주소 값
0x200 10.1 ← darr[0]
0x208 20.2 ← darr[1]
0x210 30.3 ← darr[2]
0x218 40.4 ← darr[3]
참고:
double
배열의 각 요소는 8바이트 간격으로 메모리에 저장됨
-
pc
는char
타입을 가리키는 포인터 변수 -
&arr[0]
는 배열arr
의 첫 번째 요소의 주소 (예:0x100
) - 따라서
pc
는arr
배열의 시작 주소를 가리킵니다
pc → 0x100 (arr[0]의 주소)
*pc == 10
-
pd
는double
타입을 가리키는 포인터 -
&darr[0]
는 배열darr
의 첫 번째 요소의 주소 (예:0x200
) -
pd
는darr
배열의 시작 주소를 가리킴
pd → 0x200 (darr[0]의 주소)
*pd == 10.1
[ 배열 arr (char[3]) ] [ 배열 darr (double[4]) ]
주소 값 주소 값
0x100 10 ← arr[0] 0x200 10.1 ← darr[0]
0x101 20 ← arr[1] 0x208 20.2 ← darr[1]
0x102 30 ← arr[2] 0x210 30.3 ← darr[2]
0x218 40.4 ← darr[3]
[ 포인터 ]
pc = 0x100 → arr[0]
pd = 0x200 → darr[0]
항목 | 설명 |
---|---|
char arr[3] |
3개의 1바이트 정수 배열, 연속된 메모리에 저장 |
double darr[4] |
4개의 8바이트 실수 배열, 각 요소는 8바이트 간격으로 저장 |
char* pc |
arr[0] 의 주소를 가리킴 (pc = &arr[0] ) |
double* pd |
darr[0] 의 주소를 가리킴 (pd = &darr[0] ) |
포인터 연산 |
pc + 1 → 1바이트 증가, pd + 1 → 8바이트 증가 |
표현 | 의미 |
---|---|
pc + 1 |
1바이트 다음 주소 (0x101 ) |
pd + 1 |
8바이트 다음 주소 (0x208 ) |
*pc |
arr[0] 의 값 (10) |
*pd |
darr[0] 의 값 (10.1) |