배열과 포인터의 관계
배열의 이름과 1차원 배열
int arr[] = {1,2,3,4,5};
// 배열이름 arr은 포인터이다.
// 함수의 인자로 배열을 1차원 배열을 전달하기 위해서는
// 파라미터를 아래와 같이 선언한다.
simpleMethod(int* arr) {
...
}
배열 arr의 i번째 값은
- arr[i]
- *(arr+i)
두 가지 방식을 사용하여 접근할 수 있다.
문제!
int* arr[] = {a,b,c};
simpleMethod(???){
...
}
simpleMethod에서 int* arr[]를 파라미터로 받고 싶을때 어떻게 선언해주어야 할까
-
정답
int* arr[] = {a,b,c}; simpleMethod(int** arr) { ... }
2차원 배열
int main(void) {
int arr2d[3][3];
// arr2d는 주소 100에 선언되었다.
//%p는 포인터 주소를 가리키는 형식, 16진수
printf("%p \n", arr2d); // ??
printf("%p \n", arr2d[0]); // ??
printf("%p \n", &(arr2d[0][0])); // ??
4바이트 -> 3개 = 12바이트 112
16진수 : 0~9,A,B,C,D,E,F // 100 + 16 = 110
printf("%p \n", arr2d[1]); // ?? 10C C->12
printf("%p \n", &(arr2d[1][0])); // ??
//%lu는 부호가 없는 long형 출력, unsigned long
printf("size : %lu", sizeof(arr2d)); // 36
printf("size : %lu", sizeof(arr2d[0])); // 12
printf("size : %lu", sizeof(arr2d[1])); // 12
printf("size : %lu", sizeof(arr2d[2])); // 12
return 0;
}
-
정답
100, 100, 100
10c, 10c
36, 12, 12, 12
그럼 포인터를 활용해보자
int main(void) {
int apple[3][2];
//apple은 주소 100에 선언되었다.
int banana[2][3];
//banana는 주소 500에 선언되었다.
printf("%p \n", apple); // 100
printf("%p \n", apple+1); // 100 + 8
printf("%p \n", apple+2); // 100 + 8 + 8 = 110
printf("%p \n", banana); // 500
printf("%p \n", banana+1); // 500 + 12(c) = 50c
printf("%p \n", banana+2); // 510 + 8 = 5
return 0;
}
-
정답
100, 108, 110
500, 50c, 518
배열 포인터와 포인터 배열
- 배열 포인터와 포인터 배열의 차이
int* dully[3]; // 포인터 배열 -> 배열을 선언한 것이다.
int (*dully)[3]; // 배열 포인터 -> 포인터를 선언한 것이다.
- 포인터 배열이란
배열의 요소가 포인터들로 이루어져 있다.
int* dully[3]; -> 배열 요소의 자료형이 int*인 배열, 요소의 갯수는 3개
char* dully[4]; -> 배열 요소의 자료형이 char*인 배열, 요소의 갯수는 4개
동적할당을 이용하기
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(void) {
char* arr[3];
char tmp[30]; //문자를 받을 char 배열 30자 까지만 받자
unsigned long len;
int i;
for (i = 0; i < 3; i++)
{
printf("[%d] : ", i);
scanf("%s", tmp); //문자열 입력받기
len = strlen(tmp) + 1; //문자열 길이 + 1 할당 ('\0' 문자 포함)
printf("[%d] : tmp \t주소 : %p\n", i, &tmp); //tmp 주소 출력
arr[i] = (char*)malloc(sizeof(char) * len); //메모리 할당
printf("[%d] : arr[%d]\t주소 : %p\n\n", i, i, &arr[i]); //할당받은 arr[i] 메모리 주소 출력
strcpy(arr[i], tmp); //문자열을 arr[i]가 가리키고 있는 메모리로 복사
}
printf("\n");
for (i = 0; i < 3; i++)
{
printf("arr[%d] = %s\t주소 : %p\n", i, arr[i], &arr[i]);
}
for (i = 0; i < 3; i++)
{
free(arr[i]); //메모리 해제
}
return 0;
}
결과는??
주소로 나온 값을 유심히 살펴보자
-
주소의 차이
주소가 8만큼 차이 나는 이유는 바로 64비트 환경에서 작업하고 있기 때문이다. 많은 책에서 포인터의 크기는 4비트라고 하고 있지만 그건 32비트 환경일 때의 이야기이다.
- 배열 포인터란
→ 배열을 가리키는 포인터
→ 특정 사이즈의 배열만 가리킬 수 있는 "하나"의 포인터
팁🔥 특정 사이즈의 배열을 하나의 새로운 타입이라고 생각
크기가 다른 배열에 사용할 수 없음!!
선언방법
int (*ptr)[5]; //int 타입의 인덱스를 5개 가지고 있는 배열을 가리키는 포인터
int apple[5];
int bublle[5];
int wefaew[4];
char (*ptr)[3]; //char 타입의 인덱스를 3개 가지고 있는 배열을 가리키는 포인터
char aef[3] char bdfda[4]
// "타입이름 (*변수명)[N]
Author And Source
이 문제에 관하여(배열과 포인터의 관계), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@chiyongs/배열과-포인터의-관계저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)