코드네임 :

C혼공 12, 13일차 - 응용포인터 (이중**/배열/함수/void) - 도전실전예제 영상좀 보고 해ㅇ라 본문

⚙️Computer System/C

C혼공 12, 13일차 - 응용포인터 (이중**/배열/함수/void) - 도전실전예제 영상좀 보고 해ㅇ라

비엔 Vien 2024. 2. 4. 18:27

2/6

므ㅓ여 이거 처음 보는데 (아닐수도 내가 기억 못하는 걸수도 

아니 일단 에타에 질문함... 2,3학년때 나오냐고.... 아니 나 진짜 처음 본단 말임 ㅜㅜ - 나온답니다 ㅎ

 

 

이중포인터 (**)

포인터의 주소는 이중포인터에 저장됨

**ppi : 첫번째 *  = ppi가 가리키는 자료형이 포인터임을 뜻함,  두번째 * = ppi자신이 포인터임을 뜻함 

(즉 **ppi는 ppi가 가리키는 포인터가 가리키는 값)

<포인터 마법의 원칙> (447p 아래부분에 자세한 설명)
1. 포인터를 변수명으로 쓰면 그 안의 값이 됩니다.
2. 포인터에 & 연산을 하면 포인터 변수의 주소가 됩니다. (포인터가 변수이므로 주소연산사 사용 가능)
3. 포인터 * 연산은 화살표를 따라갑니다. (그것이 가리키는 대상)

 

451p - 바꾸고자 하면 함수의 인수로 그 값의 주소를 줘야 한다 (이중 포인터를 사용한 swap 말고 처음에 swap도 그래서 포인터랑 주소 사용한겨)

 

배열명 = 포인터 주소(첫번째 요소의 주소) (아래 16행 주석 주목)

//포인터 배열의 값을 출력하는 함수
#include <stdio.h>

void print_str(char** pps, int cnt);

int main() {
	char* ptr_ary[] = {...}; //문자열 배열 선언
	int count; // 배열 요소 수를 저장할 변수
	
	count = sizeof(ptr_ary) / sizeof(ptr_ary[0]); //배열 요소의 수를 계산
	print_str(ptr_ary, count); //배열명(포인터주소)과 배열 요소 수를 주고 호출

	return 0;
}

void print_str(char** pps, int cnt) //매개변수로 이중 포인터 사용 (가리키는 값이 ptr_ary 배열명, 즉 포인터 주소(ptr_ary[0]의 주소)이므로)
{
	....
	}
}

 


 

464p 1번

double grade = 4.5;
double *pg = &grade;
double **ppg = &pg;

      ppg -> pg -> grade
값     200   300     4.5
주소   300    200    100

**ppg : ppg가 가리키는 포인터가 가리키는 변수 값, 즉 grade의 값 =4.5

&ppg : ppg의 주소 = 300

*&pg : pg의 주소가 가리키는 변수의 값, 결국 pg의 값 = 100

*ppg : ppg가 가리키는 변수의 값, 결국 pg의 값 = 100

&*ppg : ppg가 가리키는 변수의 주소, 결국 pg의 주소 = 200

 

 

465p 2번

ppa -> pa -> a=10   /   ppb -> pb -> b=20

temp = *ppa;
*ppa = *ppb;
*ppb = temp;

 

이중 포인터로 pa, pb의 값을 바꾼 것이며, a, b의 값은 변함이 없음

그러나 pa, pb가 가리키는 대상(값)이 바뀜


 

 

배열포인터 

455p 여기서잠깐! 배열의 크기(메모리에 할당된 크기(전체바이트수) 와 배열요소의 개수

//455p 코드 9~10행

//배열의 정수 연산
printf("  ary + 1 : %u\t", ary + 1); 
// ary자체가 주소로 쓰일 때 가리키는 대상 = 첫번째 요소 의 크기 :+1 : sizeof(int)만큼

//배열의 주소에 정수 연산 ( but 할당되지 않은 공간까지 넘어가므로 특별경우 아니면 사용 X)
printf(" &ary + 1 : %u\n", &ary + 1); 
// 배열의 주소&ary가 가리키는 대상 = 배열의주소전체 의 크기 : +1: sizeof(int) * 배열 요소의 개수 (5)

 

456p

2차원 배열의 이름 = 1차원 배열의 주소 : 배열을 가리키느 포인터에 저장

배열 포인터 = 배열을 가리키는 포인터 : 2차원 배열의 이름을 저장 가능

 

 

포인터 배열(문자열배열) : int *pa[4]; (1차원 배열)

배열 포인터 : int (*pa)[4];  (2차원 배열부터)

 

461p - 중요!! 위에 코드 블럭처럼 배열에 숫자 더한거라 간접참조를 시켜 숫자 더한거랑 다르다구 

배열 ary[3][4]

ary + 1 의 결과인 116번지 : 두번째 부분배열 '전체'를 가리키는 주소

*(ary+1)의 연산결과인 116번지 : '다섯번째 물리적 요소'의 주소 (물리적 요소를 사용하려면 반드시 간접참조연산자 사용 - 462p위)

 

//2차원 배열 int ary[3][4]; 에서 다음 주소는 모두 같은 값을 가지지만 같은 종류는 아니다

&ary        // (1) 2차원 배열 전체의 주소
ary         // (2) 첫번쨰 부분 배열의 주소 (배열)
&ary[0]     // (3) 첫번쨰 부분 배열의 주소 (주소)
ary[0]      // (4) 첫번째 부분 배열의 첫번째 배열요소의 주소 (부분배열) (첫번째 행을 의미)
&ary[0][0]  // (5) 첫번째 부분 배열의 첫번째 배열요소의 주소 (주소)


sizeof(ary)        // (1) 배열 전체의 크기 48바이트
sizeof(&ary[0])    // (2) 주소의 크기 4바이트
sizeof(ary[0])     // (3) 부분배열 전체의 크기 16바이트 (첫번째 행을 의미)
sizeof(&ary[0][0]) // (4) 주소의 크기 4바이트

 

 

465p 3번 다시....


 

2/9

 

함수 포인터

함수명 : 함수정의가 있는 메모리의 시작 위치

함수명이 주소가 됨

 

이거 코드도 보삼 

 

475p 1번...


 

void 포인터

- 가리키는 자료형이 다른 주소를 저장하는 경우

 

475p 2번... 틀림..

형변환 연산자가 배열 연산자보다 우선 순위 낮음 - 따라서 형변환 먼저 되게 괄호 써줘야함