포인터에 대한 간단한 설명은 아래 참고.
https://ansan-survivor.tistory.com/1237
포인터는 크게 상수형 포인터와 변수형 포인터로 나뉠 수 있다.
결론부터 말하자면, 배열을 선언하는 변수는 "상수형 포인터" 그 외는 "변수형 포인터"이다.
배열 선언시 char arr[ ]; 이런식으로 선언하는데 실제 arr 은 상수형 포인터다. 즉 주소값을 알고있는 Lable이다.
그래서 char * arr; 이랑 똑같은 구조라 할 수 있지만, * 로 선언하면 "변수"로 선언했기 때문에 포인터 변수의 주소값을 바꿀 수 있고,
char arr [ ] 으로 선언하면 상수이므로 그 주소를 바꿀 수 없다. 그리고 이 arr은 내 첫번째 배열값의 주소를 가리키고 있다.
(이때 arr의 자료형이 무엇이냐? 하면 포인터이므로 char * 자료형이다 라고 한다.)
<아래 그림의 예시 설명>
- int arr[ ]; 으로 선언하면 int형크기(4 byte) 간격으로 나란히 배열되어있는 메모리의 주소를 선언하는 것이다.
- 아래 그림의 화살표는 메모리상의 주소를 가리키는 것을 표현
- arr 은 주소값을 저장할 수 있는 포인터이다. 그러나 가리키는 방향(화살표)를 바꿀 수 없는 "상수" 이다.
- ptr 은 &num 같이 어떤걸 입력하냐에 따라 가리키는 방향(화살표)를 바꿀 수 있는 "변수"이다.
- arr도 포인터기 때문에 *arr = 10과 같이 연산이 가능하다. (arr 첫번째 배열값 변경을 의미)
<배열의 주소값 int 타입 확인>
- 아래 결과를 보면, arr 의 주소는 첫번째 배열의 주소값인 &arr[0] 임을 알 수 있다.
- 그리고 뒤 이어 배열의 값들은 int형이 4byte 임으로 순차로 4씩 증가함을 알 수 있다.
#include <stdio.h>
int main()
{
int arr[3] = {0, 1, 2};
// 배열의 각 주소값 확인
// 자료형은 int이므로 4byte씩 증가
printf("배열 주소: %p\n", arr);
printf("첫번째 : %p\n", &arr[0]);
printf("두번째 : %p\n", &arr[1]);
printf("세번째 : %p\n", &arr[2]);
return 0;
}
<포인터를 이용해서 배열 내부값 조작 - 방법 1>
배열이 포인터 형태임을 알았으니, 포인터를 이용해서 배열 내부의 값들을 조작할 수 있다.
int * ptr = &arr[0] ; 은 arr의 첫번째 주소를 ptr으로 가리키는 것이다. (arr 자체가 주소값이므로 int * ptr = arr 으로도 사용 가능)
*ptr 는 배열의 첫번째 항의 값을 출력함으로 0을 리턴.
*(ptr + 1) 은 ptr의 주소값에서 +1 (int형이므로 4byte) 뒤로 더한곳으로 주소를 가리킨다.
#include <stdio.h>
int main()
{
int arr[3] = { 0, 1, 2 };
// 배열 초기값 출력 해보기
printf("arr[0] : %d\n", arr[0]);
printf("arr[1] : %d\n", arr[1]);
printf("arr[2] : %d\n", arr[2]);
// 배열을 조작할 포인터 선언, arr[0] 첫번째 주소를 가리킴.
int* ptr = &arr[0];
// 첫번째 값 바꾸기
*ptr = 10;
// 두번째 값 바꾸기, 자료형이 int이므로 1씩 증가하면 4byte씩 뒤로 이동.
*(ptr + 1) = 30;
// 세번쨰 값 바꾸기
*(ptr + 2) = 300;
// 배열 출력해보기
printf("변경 후 배열 출력\n");
printf("arr[0] : %d\n", arr[0]);
printf("arr[1] : %d\n", arr[1]);
printf("arr[2] : %d\n", arr[2]);
return 0;
}
<포인터를 이용해서 배열 내부값 조작 - 방법 2>
선언한 포인터가 배열의 첫번째 칸을 가리키면, 포인터도 마치 배열처럼 쓸 수 있다.
#include <stdio.h>
int main()
{
int arr[3] = { 0, 1, 2 };
// 배열 초기값 출력 해보기
printf("arr[0] : %d\n", arr[0]);
printf("arr[1] : %d\n", arr[1]);
printf("arr[2] : %d\n", arr[2]);
// 배열을 조작할 포인터 선언, arr[0] 첫번째 주소를 가리킴.
int* ptr = &arr[0];
// 첫번째 값 바꾸기
ptr[0] = 50;
// 두번째 값 바꾸기, 자료형이 int이므로 1씩 증가하면 4byte씩 뒤로 이동.
ptr[1] = 70;
// 세번쨰 값 바꾸기
ptr[2] = 100;
// 배열 출력해보기
printf("변경 후 배열 출력\n");
printf("arr[0] : %d\n", arr[0]);
printf("arr[1] : %d\n", arr[1]);
printf("arr[2] : %d\n", arr[2]);
return 0;
}
C언어 문자열에 관한 배열, 포인터 선언 차이는 아래 참고.
https://ansan-survivor.tistory.com/1251
'C언어 \ C++ > 포인터 \ 배열' 카테고리의 다른 글
[C언어] 포인터로 문자열 선언, 배열 문자열 선언과 차이. (문자열 내부 변경하기) (0) | 2022.02.05 |
---|---|
[C언어] C언어 배열을 포인터로 변환하기 (배열을 포인터로 바꾸기) (0) | 2022.02.05 |
[C언어] 포인터 변수의 초기화 선언 (잘못된 사용시 위험성) (0) | 2022.02.05 |
[C언어] 포인터란? 포인터에 대해 쉽게 이해하기. (포인터 변수 사용하기, 포인터로 값 변경하기, * 연산자의 역할) (0) | 2022.02.03 |
[C언어] C언어 문자열 배열 만들기, 구조에 대해서, scanf 문자열 출력 (0) | 2022.02.01 |