C(6): 포인터&배열

이규현·2024년 12월 5일

포인터 산술연산

int main() {
	int num;
    int arr[10];
    int *p;
    
    p = #
    p = arr;
    p = arr[0];
}
  1. p가 num이라는 단일 변수를 가리킨다.
    -> 출력해보면 &num은 p와 같다.
    -> num이 int 타입이기 때문에 p+1은 주소값에 int의 크기(4byte) 4를 더해서 출력한다.
  2. 배열의 이름은 첫번째 배열의 주소
    -> p = arr 과 p = arr[0]는 같은 의미.
int main() {
  int arr[] = {10, 20, 30};

  int *p, num1, num2, num3;

  p = arr;
  num1 = *(++p);
  printf("%d\n", num1);
  p = arr;

  num2 = *(p++);
  printf("%d\n", num2);
  p = arr;

  num3 = ++(*p);
  printf("%d\n", num3);

  return 0;

}

num1: 1 증가시킨 주소의 값
num2: 주소의 값을 넣은 후 증가
num3: arr[0]값에 +1

#define MAX 5
int main() {
  int i, sum, *p, arr[MAX] = {5,10,15,20,25};

  sum = 0;
  for(p = arr; p < &arr[MAX]; p++)
    sum += *p;
  printf("Sum is %d\n", sum);

  sum = 0;
  for(i = 0; i < MAX; i++)
    sum += *(arr+i);
  printf("Sum is %d\n", sum);

  sum = 0;
  p = arr;
  for(i = 0; i < MAX; i++)
    sum += *(p++);
  printf("Sum is %d\n", sum);

  return 1;
}

세가지 방법 모두 같은 결과 출력.

void swap(int* p, int* q) {
  int temp;
  temp = *p;
  *p = *q;
  *q = temp;
}

void bubble_sort(int* arr, int length) {
  int pass, current, sorted = 0;
  for(pass = 1; (pass < length) && (!sorted); pass++){
    sorted = 1;
    for(current=0; current < (length - pass); current++){
      if(arr[current] > arr[current+1])
        swap(&arr[current], &arr[current+1]);
      sorted = 0;
    }
  }
}
  1. swap 함수 ->
    swap(&a, &b) a와 b의 주소가 함수의 매개변수로 등장
  • p가 가리키는 값을 temp에 저장 -> 즉 a의 값이 temp에 저장
  • p가 가리키는 값(a)을 q가 가리키는 값으로 바꿈
  • q가 가리키는 값을 temp의 값(a)으로 바꿈
  1. bubble sort
  • pass는 1부터

  • pass < length 이고 sorted = 0 일때 까지

  • pass++

  • 배열 첫 번째부터 다음 꺼 보고, arr[current]가 다음 꺼보다 크면 swap -> 다시 pass가 있는 반복문으로.

이중 포인터

포인터를 가리키는 포인터가 2중 포인터다.

int main() {
  int num = 10;
  int *ptr= &num;
  int **dptr = &ptr;

  printf("num: %d\n", num);
  printf("*ptr: %d\n", *ptr);
  printf("**dptr: %d\n", **dptr);

  return 1;
}
  • ptr이 num을 가리키는 포인터. (단일 포인터)

  • dptr = &ptr --> dptr이 ptr을 가리킨다.

void swap(int **, int**);
int main() {
  int first, second;
  int *fp = &first, *sp = &second;

  printf("Enter two: \n");
  scanf("%d %d", &first, &second);
  printf("Before swap: *fp: %d *sp: %d\n", *fp, *sp);
  swap(&fp, &sp);
  printf("After swap: *fp: %d *sp: %d\n", *fp, *sp);

  return 1;
}

void swap(int **p1, int **p2) {
  int * temp;
  temp = *p1;
  *p1 = *p2;
  *p2 = temp;
}

변수 원본 변경시 변수의 주소를 넘긴다.

포인터 원본을 변경시 포인터의 주소를 넘겨야한다.

-> first, second 변수를 만들고 변수를 가리키는 포인터 fp, sp를 만든다.
-> swap 함수에 2중 포인터인 &fp, &sp 넘겨준다.
-> &fp = &&first, &sp = &&second

int main() {
  int *p, arr[4] = {10, 20, 30, 40};

  printf("arr: %p\n", arr);
  printf("arr+1: %p\n", arr+1);
  printf("sizeof(*arr): %lu\n\n", sizeof(*arr));

  printf("&arr: %p\n", &arr);
  printf("&arr+1: %p\n", &arr+1);
  printf("sizeof(*(&arr)): %lu.\n\n", sizeof(*(&arr)));

  p = arr;
  printf("p: %p\n", p);
  printf("p+1: %p\n", p+1);
  printf("&p: %p\n", &p);
  printf("&p+1: %p\n", &p+1);

  return 1;
}

arr: 0x16b117300
arr+1: 0x16b117304
sizeof(*arr): 4

&arr: 0x16b117300
&arr+1: 0x16b117310
sizeof(*(&arr)): 16.

p: 0x16b117300
p+1: 0x16b117304
&p: 0x16b1172f0
&p+1: 0x16b1172f8

  • arr과 &arr은 똑같은 주소 출력

  • 하지만 arr+1과 &arr+1은 다르다.

  • 왜?: arr+1에서는 int형의 크기 4를 더하지만 &arr+1은 배열의 크기인 16을 더하기 때문.

왜 0x16b117300 + 16 = 0x16b117310인가?
16진수 계산
0x16b117300은 16진수 값입니다.
배열의 크기 16 bytes를 더하면:

0x16b117300+0x10=0x16b117310
16진수 덧셈 이유
16진수에서 0x10은 십진수로 16을 의미합니다.
따라서, 배열 전체 크기인 16 bytes를 더하면 주소가 정확히 0x16b117310으로 이동합니다.

0개의 댓글