- (상수,변수) 포인터 기본형 준비 -
#include <stdio.h> //다차원 배열과 포인터의 관계, 상수포인터와 변수포인터란?
int main(void) // 다시 정리하자면 값< *(A+1) , A[1] >에 &붙이면 주소로 쓰이고 주소< A+1 , &A[1] >에서 *만 붙이면 다 값으로 쓸 수 있다.
{
int A[5] = {1, 2, 3, 4, 5}; // 배열도 포인터
int B[5] = {1, 2, 3, 4, 5};
int* p1 = A; //포인터도 배열처럼 쓸 수 있다.
int* const p2 = B; // const를 사용함으로써 p2는 주소값을 지니는 상수가 되었다.
int const* const p3 = B; //*이 안변합니다. 라는 소리 즉 도착하는 목적지를 변경할 수 없다. 라는 소리가 된다. *(p2 + 2) = 1000; 이것이 성립이 안 된다 라는 뜻이다.
//즉, 정리 하자면 도착한 주소 값을 수정할 수 없다, 도착한 주소의 메모리 값을 수정할 수 없다.
*(A+2) = 100; //A[2] = 100
printf("배열 A의 A[2]의 값은? : %d\n",A[2]);
printf("포인터 p의 p1[2]의 값은? : %d\n\n",p1[2]);
p1 = B; //가르키는 곳을 바꿀 수 있다 라는 예를 보여주고자 선언했다.
printf("포인터 p의 p1[2]의 값은? : %d\n\n",p1[2]); // 가르키는 곳을 바꿨기에 거기있는 값을 출력한다. 값 : 3
//A = 100; (주소)상수 = (정수형)상수, 컴파일이 안된다. 배열의 타입은 int[] 이다. 포인터의 타입은 int* , 사용방법은 같지만 가르키고 안되고의 차이가 있다.
//B = A; (주소)상수 = (주소)상수, 배열에서 배열로 복사를 하려면 하나하나 for문으로 집어넣는 방법과 위에서 초기화할때 직접 집어넣는 방법. 또는 구조체를 선언 후 대입 시키는 방법.
//p2 = A; (주소)상수 = (주소)상수, l-value 는 대입 할 수 없다라는 에러이다. const p2 하면 p2가 상수입니다. 라는 뜻이다. 즉, 이제 p2를 변수가 아닌 상수로 사용하겠다라는 뜻이니까 변경을 불가능하게끔 하는 작업인 것이다. const 사용 방법
*(p2 + 2) = 1000; //const를 했어도 그 주소에 있는 값을 따라갔을 시 값은 수정이 가능 하다. 즉, 지금 막아놓은 것은 가르키는 포인터 이다.
printf("배열 A의 B[2]의 값은? : %d\n",B[2]);
printf("배열 A의 p[2]의 값은? : %d\n\n",p2[2]);
printf("배열 A의 p[2]의 값은? : %d\n\n",p3[2]);
//*(p3 + 2) = 10000; 현재 p3를 상수화 시키고 *까지 상수화를 시켰기 때문에 이것은 대입 할 수 없다라는 뜻인 l-value 에러가 뜬다.
return 0;
}
/*
배열 A는 이름 자체가 주소기에 바뀔 수 없는 상수 이다. < (상수)주소[0] > --> 이름 자체를 뭐 어찌 할 수가 없다(상수) 라는 뜻이다.
포인터 p는 주소값이 바뀔 수 있는 변수 이다. < (변수)주소[0] > --> 이름 자체를 다른 곳을 가르키도록 바꿀 수(변수) 있다.
사용면에서는 포인터나 배열은 같지만 차이점은 배열은 가르킬 수 없고 포인터는 가르킬 수 있다라는 것이다.
*/
- 다차원 배열의 심화 이해 -
#include <stdio.h>
int main(void)
{
int A[2][3] =
{
{1, 2, 3},
{4, 5, 6}
};//배열의 저장을 이미지화, 실제로 메모리에는 이렇게 저장이 안되어 있다.
int iCnt1;
int iCnt2;
for(iCnt1 = 0; iCnt1 < 2; ++iCnt1) //메모리 값 출력
{
for(iCnt2 = 0; iCnt2 < 3; ++iCnt2)
{
printf("[%d]",A[iCnt1][iCnt2]);
}
putchar('\n');
}
for(iCnt1 = 0; iCnt1 < 2; ++iCnt1) //주소 값 출력, 4바이트씩 변한다. 3열까지 하고 나면 그 다음줄 1행에 오게되면 12바이트 차이가 나는 것이다.
{
for(iCnt2 = 0; iCnt2 < 3; ++iCnt2)
{
printf("[%08X]",&A[iCnt1][iCnt2]);
}
putchar('\n');
}
printf("[%d]\n",A[0][0]); //1
printf("[%d]\n",*(A[0]+0)); //1
printf("[%d]\n\n",*(*(A+0)+0)); //1 출력. 2차원 배열을 1차원 배열처럼 점차 분해해 가는 과정.
printf("[%d]\n",*(A[0]));
printf("[%d]\n",*A[0]);
printf("[%d]\n",*(*(A+0)));
printf("[%d]\n",*(*A));
printf("[%d]\n\n",**A); //0,0 일 때만 이렇다. 다 1 값 출력. 논리적으로 풀어쓴 과정이다.
printf("[%d]\n",A[1][2]); //2차원 배열의 끝 값인 6을 출력하는 3가지 방법이다. 논리적으로 풀어 써보면
printf("[%d]\n",*(A[1]+2)); //*을 빼면 주소 값이 십진수로 출력된다.
printf("[%d]\n",*(*(A+1)+2)); //
return 0;
}
/*
KEY WORD : 차원에 갯수만큼 대괄호가 없으면 주소가 된다.
2차원 배열에서의..
[][] -> 값
[] -> 주소 (값을 출력하려면 *[] == 값, 즉 *이 []를 대신 한다. []가 하나 없어지면 *이 하나 있어야 []를 대신하여 값을 출력시키는 것이다.)
-> 주소 ( 값으로 표현하려면 * 2 개 필요)
1차원 배열에서의..
[] -> 값
-> 주소 (값을 출력하려면 *이 붙어야 된다. 여기서 유추할 수 있는건 *의 갯수로 몇차원의 배열인지 알 수 있다.)
이제 이것으로 말미암아
3차원 배열에서의..
[][][]-> 값
[][] -> 주소 ( 값으로 표현하려면 * 1 개 필요)
[] -> 주소 ( 값으로 표현하려면 * 2 개 필요)
-> 주소 ( 값으로 표현하려면 * 3 개 필요)
내일은 교환법칙에 대해 알아 볼 것이다.
*/
'[Programming] Language > C' 카테고리의 다른 글
C언어_네크워크 select() 사용 다중 접속 채팅 프로그램 만들기 (0) | 2018.02.13 |
---|---|
C언어_원,투 포인트 함수 이용 복습 , 리눅스 (0) | 2015.04.20 |
C언어_다차원 배열 (0) | 2015.04.17 |
C언어_교환법칙, (2,3)차원 배열, 더블 포인터의 이해 (0) | 2015.04.17 |
C언어_구조체 메모리 최적화(전처리어 pragma 사용법),구조체 활용, 공용체 사용법 (0) | 2015.04.17 |