신입 개발자 공부 과정

C언어 - 포인터(2) 상수포인터 본문

C/공부

C언어 - 포인터(2) 상수포인터

Lewisjkim 2022. 2. 22. 22:01

상수 포인터

int a;
int b;
const int *p = &a; //상수처리
*p = 3 //잘못된것 = 그 이유는 const 뒤에 오는 *를 포합하여 상수처리가 되기 때문
p = &b;//고로 위에 상수처리한 것은 *p이고  p 자체가 아니기 때문에 가능하다

*%p = 변수의 주소를 헥사로 표현할 떄 사용하는 것

int a;
int b;
int *const p = &a;//const가 *와 변수 p 사이에 왔으므로 
//상수처리된것은 변수 p일 뿐이다
*p =3;//고로 이는 올바른 문장이다

포인터의 덧셈

int a;
int* p;
p = &a;
printf("pa 의 값 : %p \n", p);
printf("(pa + 1) 의 값 : %p \n", p + 1);
return 0;

차이가 4 차이가 나는것은 4바이트 차이기 때문이다


배열과 포인터

int main() {
int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int i;
for (i = 0; i < 10; i++) {
printf("arr[%d] 의 주소값 : %p \n", i, &arr[i]);
}
return 0;
}

그럼 포인터를 통해서  접근할 수 있다.

#include <stdio.h>

int main() {
	int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	int* p;
	int i;
	p = &arr[0];//주소값
	for (i = 0; i < 10; i++)
	{
		printf("arr[%d]의 주소값= %d\n", i, p+i);
	}
	return 0;
}


또한 포인터로 배열의 주소값도 찾았으니
배열 값을 출력할 수 도 있게된다.

#include <stdio.h>

int main() {
	int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	int* p;
	int i;
	p = &arr[0];//주소값
	for (i = 0; i < 10; i++)
	{
		printf("arr[%d]의 값= %d\n", i, *(p+i));
	}
	return 0;
}


또한 포인터를 사용해서 배열을 순서대로 출력할 수 도 있습니다


#include <stdio.h>

int main() {
	int arr[10] = {100, 200, 300, 400, 500, 600, 700, 800, 900, 1000};
	int *p = arr;//주소값
	int sum = 0;
	while (p - arr <= 9)//정수 평균 내기
	{
		sum += (*p);
		p++;
	}
	
	printf("내 시험 점수 평균 : %d \n", sum/10);
	return 0;
}


포인터의 포인터

int **p; = int를 가리키는 포인터를~ 가리키는 포인터

#include <stdio.h>
int main() {
int a;
int *pa;
int **ppa;
pa = &a;
ppa = &pa;
a = 3;
printf("a : %d // *pa : %d // **ppa : %d \n", a, *pa, **ppa);
printf("&a : %p // pa : %p // *ppa : %p \n", &a, pa, *ppa);
printf("&pa : %p // ppa : %p \n", &pa, ppa);
return 0;
}

ppa는 pa를 가리키고
pa는 a를 가리킨다

고로,
a = *pa = **ppa
&a = pa = *ppa
&pa = ppa 가 된다


배열 이름의 주소 값

#include <stdio.h>
int main() {
	int arr[3] = { 1, 2, 3 };
	int(*parr)[3] = &arr;
	printf("arr[1] : %d \n", arr[1]);
	printf("parr[1] : %d \n", (*parr)[1]);
	return 0;
}

기존 arr 은 arr[0] 을 암묵적으로 변환되었지만
앞에 &연산자가 올때에는 이루어지지 않는다.
고로 &arr은 크기가 3인 배열을 가리키는 주소 값이 된다.


2차원 배열

#include <stdio.h>
int main() {
	int arr[2][3] = { {1, 2, 3}, {4, 5, 6} };
	printf("전체 크기 : %d \n", sizeof(arr));//24 = arr는 전체 길이
	printf("총 열의 개수 : %d \n", sizeof(arr[0]) / sizeof(arr[0][0]));// 12 / 4 = 3
	printf("총 행의 개수 : %d \n", sizeof(arr) / sizeof(arr[0]));// 24 / 12 = 2
	printf(" %d \n", sizeof(arr[0][0]));//4 = 0번쨰 행의 0번쨰 열의 길이 ok
	printf(" %d \n", sizeof(arr[0]));//12 = 0번째 행의 길이 ok
	return 0;
}


포인터 형을 결정하는 것
arr[a][b] 를 정의했을 때

1. 가리키는 것에 대한 정보 (예를 들어, int* 이면 int 를 가리킨다, char** 이면 char* 을 가리킨다 등등)

2. 1 증가시 커지는 크기 (2 차원 배열에서는 b * (형의 크기) 를 의미한다)



2차원 배열을 가리키는 포인터 - 배열 포인터

(배열 형식) (*(포인터이름)) [2차원 배열의 열 개수]'
ex) int (*p) [4];

#include <stdio.h>
int main() {
	int arr[2][3] = { {1, 2, 3}, {4, 5, 6} };
	int(*parr)[3]; // 괄호를 꼭 붙이세요
	parr = arr; // parr 이 arr 을 가리키게 한다.
	printf("parr[1][2] : %d , arr[1][2] : %d \n", parr[1][2], arr[1][2]);
	return 0;
}

 


포인터 배열 (배열)

#include <stdio.h>
int main() {
	int a = 1, b = 2, c = 3;
	int *parr[3];
	parr[0] = &a; //a의 주소값
	parr[1] = &b;
	parr[2] = &c;
	printf("a: %d, *parr[0]: %d\n", a, *parr[0]);
	printf("b: %d, *parr[1]: %d\n", b, *parr[1]);
	printf("c: %d, *parr[2]: %d\n", c, *parr[2]);
	return 0;
}