치악산 복숭아

[시스템 프로그래밍 기초] C 포인터 본문

CS/시스템 프로그래밍 기초

[시스템 프로그래밍 기초] C 포인터

Juliie 2023. 3. 26. 20:26

1. &: Reference operator

  • 변수의 메모리 주소
    • 메모리 주소는 컴퓨터를 실행할 때마다 바뀜

2. *: Dereference operator

  • 포인터가 가리키는 메모리 주소에 저장된 반환

3. Pointers

  • C 프로그램에서 메모리에 접근, 주소를 조작하기 위해 사용됨
  • 데이터보다는 메모리 주소값을 갖고있는 특별한 변수 타입
    • 이러한 변수들을 pointer variable 또는 간단하게 pointer 라고 칭함 
// *를 어디에 붙이던 같은 뜻
int* pval;
int * pval;
char *pch;

data_type* variable_name;
main() {
    int a;
    int *b;
    
    a = 38; // (O)
    b = 40; // (X), 포인터로 선언했기 때문에 정수X, 주소값을 넣어야 함 
    *b = 40; // (O)
}

예제 1)

#include <stdio.h>

int main() {
  int val = 10;
  printf("Value: %d, Address: %d \n", val, &val);
    return 0;
}

출력 결과:

더보기

Value: 10

Address: 1295815448

예제 2)

#include <stdio.h>

int main(void) {
  int *pv;
  int num = 20;
  printf("[pv] Address: %d, Content: %d \n", pv, *pv);
  printf("[num] Address: %d, Value: %d \n\n", &num, num);
  pv = &num;
  printf("[pv] Address: %d, Content: %d \n\n", pv, *pv);
  num = 11;
  printf("[pv] Address: %d, Content: %d \n", pv, *pv);
  *pv = 2;
  printf("[num] Address: %d, Value: %d \n", &num, num);
  return 0;
}

출력 결과:

더보기

[pv] Address: 2040457912, Content: 0 
[num] Address: 2040457596, Value: 20 

[pv] Address: 2040457596, Content: 20 

[pv] Address: 2040457596, Content: 11 
[num] Address: 2040457596, Value: 2 

예제 3)

#include <stdio.h>

int main(void) {
  char c[4] = {'a', 'b', 'c', 'd'};
  int d[4] = {5, 6, 7, 8};
  int i;
  for(i = 0; i < 4; i++) {
    printf("Address of c[%d] = %x\n", i, &c[i]);
    printf("&c[%d] = %x, (d + %d) = %x\n",i, &c[i], i, (c + i));
    printf("c[%d] = %d, *(c + %d) = %d\n", i, c[i], i, *(c + i));
  }
  for(i = 0; i < 4; i++) {
    printf("Address of d[%d] = %x\n", i, &d[i]);
    printf("&d[%d] = %x, (d + %d) = %x\n",i, &d[i], i, (d + i));
    printf("d[%d] = %d, *(d + %d) = %d\n", i, d[i], i, *(d + i));
  }
  return 0;
}
  • 배열의 주소값을 요청하면 대표 번지수가 리턴된다

출력 결과:

더보기

Address of c[0] = 72cb5c
&c[0] = 72cb5c, (d + 0) = 72cb5c
c[0] = 97, *(c + 0) = 97
Address of c[1] = 72cb5d
&c[1] = 72cb5d, (d + 1) = 72cb5d
c[1] = 98, *(c + 1) = 98
Address of c[2] = 72cb5e
&c[2] = 72cb5e, (d + 2) = 72cb5e
c[2] = 99, *(c + 2) = 99
Address of c[3] = 72cb5f
&c[3] = 72cb5f, (d + 3) = 72cb5f
c[3] = 100, *(c + 3) = 100
Address of d[0] = 72cb60
&d[0] = 72cb60, (d + 0) = 72cb60
d[0] = 5, *(d + 0) = 5
Address of d[1] = 72cb64
&d[1] = 72cb64, (d + 1) = 72cb64
d[1] = 6, *(d + 1) = 6
Address of d[2] = 72cb68
&d[2] = 72cb68, (d + 2) = 72cb68
d[2] = 7, *(d + 2) = 7
Address of d[3] = 72cb6c
&d[3] = 72cb6c, (d + 3) = 72cb6c
d[3] = 8, *(d + 3) = 8

예제 4)

#include <stdio.h>

int main(void) {
  int i, val[4], sum = 0;
  printf("Enter 4 numbers: \n");
  for(i = 0; i < 4; ++i) {
    scanf("%d", (val + i));
    sum += *(val + i);
  }
  printf("Sum = %d", sum);

  return 0;
}
  • val을 배열 자체로 접근한 뒤 int 값을 더하는 방법으로 변수의 메모리 주소값에 접근
  • scanf는 메모리 주소가 필요한 함수
  • 참고 블로그
 

[C언어] scanf()함수에서 &(ampersand)를 쓰는 이유

[&(ampersand)에 대하여] c언어를 시작하면 printf에서는 &를 안썼는데, scanf에서는 &를 쓸때가 있고, 안쓸때가 있다.&의 역할은 무엇이며, &는 언제 쓰는 것일까. &(ampersand)의 역할- &(ampersand(앰퍼샌드))

security-nanglam.tistory.com

예제 5)

#include <stdio.h>

void swap(int *a, int *b);

int main() {
  int num1 = 5, num2 = 10;
  printf("Number1 = %d\n", num1);
  printf("Number2 = %d\n", num2);

  swap(&num1, &num2);
  
  printf("Number1 = %d\n", num1);
  printf("Number2 = %d\n", num2);
  
  return 0;
}

void swap(int *a, int *b) {
  int temp;
  temp = *a;
  *a = *b;
  *b = temp;
}
  • 왜 직접 값을 안바꾸고 주소값을 넘겨서 바꿀까?
    1) 값은 한 개 밖에 리턴되지 않음
    2) 로컬함수에서 계산한 값이 메인 함수로 돌아왔을 때 남아있다는 보장이 없음

출력 결과:

더보기

Number1 = 5
Number2 = 10
Number1 = 10
Number2 = 5

Comments