임베디드/임베디드 레시피

Pointer

twoweeks-within 2024. 12. 4. 15:54

 Pointer
  : 주소를 가리키는 word 크기의 자료 형입니다.
  // word형 : 32bit machine > 32bit  64bit machine > 64bit크기

ex) 32bit machine
int *address;
 address: pointer형 자료, 
address 자체의 크기 : 32bit 크기, 
address가 가리키는 자료 형 : integer type

 int* address 가 맞는 표현
 int* : integer type을 가리키는 pointer형이라는 자료 구조, address가 그 자료의 이름

   > sizeof(address) = 32 bit, 4byte 
 address: integer형을 가리킴

 address : 주소가 담김 
*address: address가 갖고 있는 주소 > int형 만큼의 data를 가리킴.

 & 연산자 :   pointer에 data가 저장되어 있는 주소를 알려줄 수 있음

char *text = "Recipes";  // 문자열 시작주소를 저장
*text : "R" 의미

 *(text++) : 0x101 // char형


char *text = "Recipes";
text[1]; // 'e'
*(text+ 1); // 'e'
  > Sugar expression : Software Engineer가 어떻게 하더라도 같은걸 가리키게 해줌

    array [번호] = * (array주소 + 번호) 

char *pointer;
char array[3];

array[0] = 0;
array[1] = 1;
array[2] = 2;

pointer = array;
pointer = &array[0];

Pointer 장점
1. Pointer는 직접 주소를 가리킬 수 있음 ~= Assembly
   > 각종 Memory 주소 >  C (High Level Language) 에서도 마음대로 Access가능

 2. 대용량의 Data의 전달을 간단하게 주소 하나만 넘김으로써 가능 
     > Function Call을 할 때 Passing Argument로 주소를 직접 
// 10000개 인덱스의 배열 전달시 배열이름만 넘겨주면되니깐


3. Caller 함수와 Callee 함수 사이의 관계
  하나 이상의 return값이 필요 할 때, 
   > 여러 개의 pointer를 넘겨줌
     > 거기다가 결과를 넣어서 돌려줌


void calculate(int a, int b, int *sum, int *product) {
    *sum = a + b;
    *product = a * b;
}

int main() {
    int num1 = 5, num2 = 10;
    int resultSum, resultProduct;

    calculate(num1, num2, &resultSum, &resultProduct);
// &resultSum = sum , *sum = resultSum


    printf("Sum: %d\n", resultSum);
    printf("Product: %d\n", resultProduct);

    return 0;
}



void main (void)
{
    char *p= "Recipes";
    char **pp;
    *pp= p;
    printf ("p address : %p\n", pp);
    printf ("p address : %p\n", ++pp);
    return;
}

이 code의 결과는 어떻게 될까요? 한번 상상해 보세요.

p address : 0x00408058
p address : 0x0040805c

 이런 pointer를 가리키기 위한 이중 pointer를 또 하나 선언해서 p를 가리키게 해서 주소를 알아 낸답니다. 이런 건 언제 사용하느냐! 전통적인 예가 하나 있는데 한번 보시죠.

void gettag (char *ptag)
{
    ptag=(char *)malloc(40); //40byte 공간 할당, 프로그래머가 할당한 heap 영역
    strncpy(ptag,"pointer tag", sizeof(char)*40); // 12byte (NULL 포함) 넣음
}

void process()
{
    char *tag;
    gettag(tag); // tag
    free(tag);
}

 tag : init되지 않은 pointer > gettag의 Passing Parameter 
ptag에 heap을 할당 > 받아 그 시작 주소를 넣음
  > 값 복사라 함수 종료시 소멸

 void gettag (char **ptag)
{
    *ptag=(char *)malloc(40);  // *ptag : char* 타입 // 자동으로됨
    strncpy(*ptag,"pointer tag", sizeof(char)*40); // 40byte 공간의 메모리의 시작 주소를 반환
}

void process()
{
    char *tag;    // tag 는 char * 타입
    gettag(&tag);  // &tag 는 char** 타입 
// 
    free(tag);
}
ptag : char** 타입의 포인터 >> *ptag : char* 타입
(char *)malloc(40); // 40byte 공간의 메모리의 시작 주소를 반환

char **ptag = &tag
*ptag  // ptag가 가리키는 주소에 있는 값을 참조 // *ptag == tag (값)
// void process() 에서 char *tag; 아직 선언 X > 빈공간임
   > (char *)malloc(40); 동적으로 40byte 공간할당 
     > 거기에 12byte 넣음

**ptag // ptag가 가리키는 값(tag)**이 가리키는 값을 참조

- pointer를 함수의 passing parameter로 제대로 넘겨 주려면
   pointer의 주소를 넘김 >이중 pointer로 받음 > 그 주소를 제대로 넘겨 받을 수 있음

이중 pointer 주로사용 > pointer 배열
   > 배열 선언  > 그 내용물들이 pointer인 경우
    >  이중 pointer를 선언 > pointer를 수정 > 그 값 수정



>>>> pointer  함수에서 사용시 주의

 주소 접근 해서 값을 변경 하려면 기존 선언한거의 값과 동일해야함 !!! 

함수에서 그냥 가져만 오면 종료시 해제됨

'임베디드 > 임베디드 레시피' 카테고리의 다른 글

Stack , Heap  (0) 2024.12.05
struct , packed  (0) 2024.12.05
Context와 AAPCS  (1) 2024.12.03
Scatter Loading 주의점, heap 및 stack  (2) 2024.12.02
Reset Handler에서 main까지 (Entry Point)  (0) 2024.12.01