[C 입문중] 포인터 상수, 포인터 변수의 차이좀 헤깔리네요.
글쓴이: meekdmn / 작성시간: 수, 2004/11/24 - 3:58오후
#include <stdio.h>
#define NUM 5
typedef struct _student Student;
struct _student
{
int kor;
};
void pointer_test(Student *s);
void pointer_test1(Student s1[NUM]);
int main()
{
Student student[NUM];
int i;
for(i=0;i<NUM;i++){
student[i].kor = i;
}
printf("student address --> %x\n",student);
for(i=0;i<NUM;i++){
printf("%d\n",*student);
printf("%x\n",student);
/*여기는 student가 포인터 상수죠? 그래서 상수값을 바꾸려고 하면 안되죠.?*/
student++;
}
pointer_test(student);
pointer_test1(student);
}
void pointer_test(Student *s)
{
int i;
for(i=0;i<NUM;i++){
printf("%d\n",*s);
printf("%x\n",s);
s++;
}
}
/*근데 여기서 s1은 포인터 상수가 아닌가요.?
제가 간단하게 아는 바로는 배열명은 주소값을 가지게 되고 이는 바뀔 수 없으므로 포인터 상수라 한다. 였는데..아래에서 s1++;을 해줄 수 있단거에 대해서 의문이..생겼습니다.*/
void pointer_test1(Student s1[NUM])
{
int i;
for(i=0;i<NUM;i++){
printf("%d\n",*s1);
printf("%x\n",s1);
s1++;
}
}배열명은 포인터 상수이고 , 함수로 전달된 배열명은 그 함수에서 새로이 생성이 되어서? 포인터 상수가 아닌건가.? 주소를 찍어보면 같은거 보니깐 새로이 생성은 아니고 참조인것 같은데.
pointer_test1(Student s1[NUM])의 s1과 main에서 student와는 어떤 관계가 있는거죠.?
void pointer_test1(Student s1[NUM]) 와
void pointer_test1(Student *s)
의 궁극적인 차이는 없는건가요.?
입문중인데 한번 헤깔리니깐..이랬다고 믿던 것 마저 흔들려서. 저의 답답함을 좀 식혀 주세여..
감사합니다 꾸뻑.
Forums:


Re: [C 입문중] 포인터 상수, 포인터 변수의 차이좀 헤깔리네요.
student++이 안되는 이유는 포인터 상수(pointer constant)라서 그런 것이 아니라
변경 가능한 좌변값(modifiable l-value)이 아니기 때문입니다. 이것은 포인터
상수와는 전혀 다른 것입니다. 포인터 상수의 예로는 NULL이 있습니다.
main()의 배열명 student는 함수로 전달되면서 포인터로 변환됩니다. 이 동작을 코드로 나타내면
Student* p = student; pointer_test(p);정도가 될 수 있습니다.
배열과 포인터는 전혀 다른 것이지만 많은 경우에 배열명은 포인터로 변환될 수
있습니다. 함수로 전달된 배열명은 배열의 선두 주소를 가리키는 포인터로 바뀌고
함수 내부에서는 변환된 포인터에 대한 복사본이 사용되는 것입니다. 당연히
같은 주소를 가리키게 됩니다.
예, 똑같은 함수입니다. pointer_test1() 안에서는 전달된 것이 배열인지 포인터인지
구별할 수 없습니다.
s1++;을 해줄 수 있단거에 대해서 의문이..생겼습니다함수 호출
s1++;을 해줄 수 있단거에 대해서 의문이..생겼습니다
함수 호출이 call by value 아닌가요..?
[quote="Anonymous"]s1++;을 해줄 수 있단거에 대해서
함수 호출의 형식과는 전혀 관련이 없고, C가 함수의 매개변수에 적용하는 특별한 변환 규칙과 관련이 있습니다.
#include <stdio.h> void func(int a[]) { printf("%d\n", *a); ++a; printf("%d\n", *a); } int main(void) { int arr[3] = {1, 2, 3}; func(arr); return 0; }위의 프로그램이 전혀 틀린 곳이 없는 프로그램이 될 수 있는 것은, 함수 정의나 선언의 파라미터 리스트에 사용된 모든 형태의 array of ... 꼴의 변수는 자동으로 pointer to ... 형태로 변환되기 때문입니다. 따라서 실제로 a의 데이터형은 array of int[]가 아니라 pointer to int입니다.
위와 같은 규칙 덕분에 함수 선언부에는 배열 형태로 적고 함수 정의부에는 포인터 형태로, 혹은 그 반대로 적어놓아도 아무런 문제가 없습니다.
void func(int a[]); // 함수 선언에는 배열 형태를 사용 void func(int *a) { ... } // 함수 정의에는 포인터 형태를 사용참고로, 다차원 배열의 경우에는 다음과 같이 가장 바깥쪽의 배열만 벗겨져 포인터 형태로 변환됩니다.
int func(int a[], short b[3][4], long c[][6][7]) { ... } -> int func(int *a, short (*b)[4], long (*c)[6][7]) { ... }위와 같은 규칙 때문에 함수가 호출될 때 배열은 call by reference로 전달된다고 말하기도 하는데, 틀린 설명입니다. C언어의 함수는 배열을 매개변수로 전달할 수 없습니다. 다만 포인터를 이용하여 배열의 주소값만을 전달할 수 있을 뿐입니다.
댓글 달기