왜 변수에 포인터를 입력해야하는지 ...
조회수 1565회
#include <stdio.h>
void main()
{
int a[] = {10,20,30,40,50,60,70,80,90,100};
int k,m,i,*ptr;
k=m=0;
ptr=a;
for(i=0; i<10; i+=2)
{
k+=ptr[i];
m+=ptr[i+1];
}
printf("***** result ***** \n\n");
printf("(10+30+50+70+90)=%d\n",k); //250
printf("(20+40+60+80+100)=%d\n",m); //300
}
저기 위 *ptr에서 왜 *을 붙여야 하는지 잘 모르겠습니다.
포인터를 주지 않고 그냥 ptr로 작성해도 괜찮지 않나요?
또한 *를 주었을 때 변수 a[]를 불러오는지 잘 모르겠습니다.
-
(•́ ✖ •̀)
알 수 없는 사용자
2 답변
-
안녕하세요! 올려주신 코드는 아래의 방식으로 하셔도 상관 없습니다!
#include <stdio.h> void main() { int a[] = {10,20,30,40,50,60,70,80,90,100}; int k,m,i; //*ptr; k=m=0; // ptr=a; for(i=0; i<10; i+=2) { k+=a[i]; m+=a[i+1]; } printf("***** result ***** \n\n"); printf("(10+30+50+70+90)=%d\n",k); //250 printf("(20+40+60+80+100)=%d\n",m); //300 }
그리고 배열을 포인터로 받은 이유는 배열 자체가 포인터의 집합이기 때문입니다.
예를 들자면 포인터는 열차의 1개 칸 혹은 동력이 있는 머리 부분이고 배열은 완성된 1개의 열차라고 보시면 됩니다.
따라서 포인터로 배열을 받아 배열처럼 사용하는 것이 가능하기 때문에 그것을 보여주기 위한 코드로 보입니다.
-
(•́ ✖ •̀)
알 수 없는 사용자
-
-
위의 답변으로도 충분하지만, 혹시라도 포인터와 배열의 관계에 대해 좀 더 깊이 알고 싶은 분들을 위해 추가적으로 내용을 남깁니다.
int main() { int a[] = {10,20,30,40,50,60,70,80,90,100}; // 위 코드는 암시적으로 아래 코드로 변환됩니다. // int a[10] = {10,20,30,40,50,60,70,80,90,100}; // c, c++ 에서 배열 타입은 고정된 크기가 정해져야만 하기 때문입니다. // 실제로 a 라는 변수의 타입은 'int [10]' 타입입니다. // 그런데 배열 타입은 보기에 좀 복잡해 보이기 때문에 가독성이 떨어집니다. // 그래서 보통은 포인터 타입으로 변환해서 사용합니다. // c, c++ 에서 배열 타입은 암시적으로 포인터 타입으로 캐스팅할 수 있습니다. int* ptr = a; // 때문에 a변수를 다른 변수에 저장하고 싶을 때, 이렇게 씁니다. // 하지만 위와 같은 경우 사실 암시적 캐스팅에 의해 배열의 길이 정보를 잃어버리게 됩니다. // 배열 타입은 타입 자체에 배열의 크기를 가지고 있다는 점에서 포인터와 다릅니다. // 즉, 변수 'a'와 변수 'ptr'은 사실상 같은 값(배열의 시작 주소)를 가지지만, // 'a'는 타입자체에 배열길이가 10이라는 정보를 가지고 있고, // 'ptr'은 단지 int형 주소값이라는 정보만 가지고 있는 점에서 차이가 생깁니다. // 그럼 그 배열길이 정보라는게 어디서 써먹냐? 싶을 수 있는데, // c에서의 예제는 이해하기 복잡한 부분이 많기 때문에, // c++의 Range-based for loop를 예로 들겠습니다. // 이 경우 'a'라는 변수의 타입이 배열의 길이정보를 가지기 때문에 배열을 순회할 수 있습니다. for (int i : a) { i = 0; } // 하지만 이 경우는 'ptr'이 포인터 타입이기 때문에 길이정보가 없어 배열을 순회할 수 없습니다. /* for (int i : ptr) // error { i = 0; } */ // 질문에서의 이 부분의 코드가 동작할 수 있는 이유는 int k,m,i; k=m=0; for (i = 0; i < 10; i += 2) { k += ptr[i]; // 여기서의 [ ]는 타입이 아니라 연산자이기 때문입니다. m += ptr[i+1]; } // '[ ]' 연산자는 포인터 타입에서도 사용할 수 있으며, // 해당 포인터 변수에 저장된 주소로부터 '[ ]' 안에 들어가는 숫자만큼 // 포인터 연산을 통해 이동한 해당 위치의 값의 참조를 반환하는 연산자입니다. // 즉, k += ptr[i] 는 k += *(ptr + i) 와 같은 코드이고, // (ptr + i)는 ptr값에 i값을 더한다는게 아니라, // ptr값에 (i * sizeof(int))의 결과값을 더한다는 뜻입니다. (포인터 연산) // 포인터 연산으로 변경된 위치의 주소값을 '*'연산자를 통해 참조하여 레퍼런스를 반환하게 되며, // 반환되는 타입은 int& 타입으로 볼 수 있습니다. // 참고로 위의 'a' 변수를 레퍼런스 타입으로 받으려면 int(&b)[10] = a; //이렇게 써야하며, // 배열 타입에 대한 레퍼런스 타입은 배열 타입과 똑같이 사용할 수 있습니다. for (int i : b) // ok { i = 0; } return 0; }
댓글 입력