임베디드를 배우기 전 간략한 C 이론 5

*(pa+0) == pa[0]

포인터 배열 - 포인터를 묶어놓은 배열이다.

더블포인터 - 싱글포인터의 주소를 저장하는 용도로써 사용된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
int arr_m[3][4] = {
{5,6,7,8},
{9,10,11,12},
{13,14,15,16}
} //2차원 배열 선언과 동시 초기화

int row,col;

for (row = 0;row<3; row++)
{
for(col = 0;col<4;col++)
printf("arr_m[%d][%d]:%d", row, col, arr_m[row][col]);
}

위의 경우에서 arr_m[2] == arr_m+2 == arr_m[2][0]

int (*pa)[3]; //길이가 3인 int형 2차원 배열을 가르키는 포인터 변수(배열포인터)
int *pa[3]; //포인터 배열

포인터배열 배열포인터를 헷갈리지 말자
배열 포인터는 - 2차원 배열을 가르키는 포인터
포인터 배열을 - 포인터를 배열로 만들어 놓은것.

char *(str)[50]; 일 때
str[0]+1 != str+1
좌측은 50만큼 증가하고 우측은 1바이트씩 증가

자료형 앞에 register 을 넣으면 변수가 register 변수에 저장이 된다. 빠르다!

static의 생존기간은 전역변수와 같지만 메모리 존재범위은 블록 내에서만!

함수포인터

함수명은 함수의 시작주소이다.

함수 포인터를 만드려고 하니
int *ptr(int a, int b); 와같은 형태가 나왔다,
이는 리턴타입이 int * 이라는 함수선언과 같으므로
괄호를 씌워 int (*ptr)(int a, int b); 로 함수포인터를 만든다.

배열포인터와 유사한 형태로 만들어졌다.
배열 포인터 또한 int *arr[3] 으로 만들라 했으나 이는 포인터 배열과 일치하므로 괄호를 추가해 int (*arr)[3]으로 처리했다.

1
2
3
int Add(int a, int b);

int (*ptr)(int a, int b) = Add;

위와같이 사용한다.

ptr(2,3) // 간접호출
Add(2,3) //직접호출

1
2
3
4
5
6
int temp = 5;
int * ptr = &temp;
void* pv = &temp; //가능하다.

*pv = 8; //불가능하다(시작부터 몇바이트를 읽을지는 pv의 자료형으로 판단하는데 몇바이트로 접근해야할지 알 수 없다)
*((int*)pv) = 8 //가능

void형 포인터는 모든 변수의 주소값을 저장할 수 있다.

주소값을 표현할 땐 다음과 같이
((volatile unsigned int)0x80000000) = 0xFF000000; //나중에 다시한번 배운다.

volatile 은 주소값의 데이터가 변경되는것을 막는다.

Share