PGR21.com
이전 질문 게시판은 새 글 쓰기를 막았습니다. [질문 게시판]을 이용바랍니다.
Date 2011/09/26 19:12:20
Name zeros
Subject c 프로그래밍 구조체 포인터에 대한 질문입니다
메인에서 어떤 구조체를 생성하고 함수에 그 구조체변수에 대한 주소값을 불러 값을 변경하는 프로그래밍을 하는 중인데요
메인에서 생성하는 구조체를 글로벌로 선언하면 아무런 문제없이 되는데 메인에서 생성을 하면 함수를 빠져나오는 순간 값이
원상태로 가더라구요.. 아무래도 call by value 로 인정되는거 같은데.. 생각을 해봐도 잘 이해가 안갑니다.

비슷한 컨셉의 예시프로그램입니다.
include <stdio.h>

struct node{
     int value;
};
void test(struct node*);
int main()
{
     struct node forTest;
     forTest.value = 10;
     test(&forTest);
     printf("%d",forTest.value);
     return 0;
}
void test(struct node* test)
{
       test->value = 99;
}

call by value 라면 **를 해야하는거 같긴한데.. 저는 왜 이것이 call by reference가 될 수 없는지가 이해가 잘안되네요..
답변 부탁드립니다 ^^

통합규정 1.3 이용안내 인용

"Pgr은 '명문화된 삭제규정'이 반드시 필요하지 않은 분을 환영합니다.
법 없이도 사는 사람, 남에게 상처를 주지 않으면서 같이 이야기 나눌 수 있는 분이면 좋겠습니다."
Cazellnu
11/09/26 19:40
수정 아이콘
코드 슬쩍 봤는데 문제 없어 보이는데요?
김연우
11/09/26 19:42
수정 아이콘
혹시나 했는데 정상적으로 99 찍히네요.
뭐가 문제인가요?
11/09/26 20:10
수정 아이콘
희안하네요.. 비슷한 컨셉으로 그냥 즉석에서 짠거라 당연히 안될거라 생각했는데.. ㅡㅡ;;;
원래 코드 붙여봅니다.
struct node

int key;
struct node* next;
;
int InsertKeyH(struct node*, int,struct node*);
int main()

struct node head, newNode1, newNode2,newNode3,newNode4,newNode5,newNode6,newNode7;

head.key = -1;
InsertKeyH(&head, 100, &newNode1);
InsertKeyH(&head, 250, &newNode2);
InsertKeyH(&head, 467, &newNode3);
InsertKeyH(&head, 150, &newNode4);
InsertKeyH(&head, 300, &newNode5);
return 0;


int InsertKeyH(struct node* root, int data, struct node* source)

struct node* preNode;
struct node* nowNode = root;
source -> key =data;
source->next =NULL;

while(1)
{
if(nowNode->key == -1) //if the head of Linked List has no data, new node should be the head of Linked List
{
root = source;
nowNode = source;
return 0;


//if the input is smaller, new node place before root, and should change the value of next
//but if the root node is ptr_first, program have to link newNode and root, and then make newNode as ptr_first

else if(nowNode->key > data)

if(nowNode == root)
{
source->next = nowNode;
root = source;
return 0;

else

preNode->next = source;
source->next = nowNode;
return 0;

}

//this program doesn't allow duplicated value

else if(nowNode->key == data)
return -1;

//if data is bigger than root->key, check whether root has next node or not.
//if it has, go to next node and compare again
//if it doesn't, just link it

else

if(nowNode->next != NULL)
{
preNode = root;
nowNode = root->next;


else

nowNode->next = source;
return 0;

}

}

}
11/09/26 20:41
수정 아이콘
c 에서 call by reference 라 부르는 것조차 사실은 주소값을 넘겨주는 call by value에 불과합니다.
그 주소값을 이용해서 메모리를 참조 해야 비로소 call by reference가 되는 것이죠.

예를 들어 보여주신 소스코드에서 int InsertKeyH(struct node* root, int data, struct node* source) 함수선언은 주소를 가진 포인터 변수를 하나 만들고, 함수를 호출할때 넣은 주소값을 call by value로 넘겨주는 겁니다. 여기에서 중요한점은 root라는 변수는 함수내에 사용되는 로컬 변수라는 것이죠. 따라서 root = source; 문장은 함수안의 로컬 변수 값을 바꾸는것 밖에 안됩니다.

여기서 구분하는 요령을 알려드리면, call by reference, 원본 메모리의 값을 변경하기 위해서는 원하는 변수의 주소값을 포인터로 넘겨야 합니다. 위 예에서는 구조체 포인터인 root 값을 변경해야 하니까 더블포인터를 써야겠네요.

제가 설명을 조리있게 하는 편이 아니라 이해가 되실지는 모르겠는데, 궁금한점을 리플로 다시면 제가 답변해드리겠습니다.
Cazellnu
11/09/26 21:06
수정 아이콘
윗분 설명대로 root = source 해봤자 도루묵입니다.
memcpy 같은걸로 메모리 내용을 카피 해야됩니다.
(스트럭쳐 카피할때 주의점은 패딩문제가 있긴한데 이건 지금단계에서는 잊으시고)

그리고 그것보다 애초에 리스트를 저렇게 구현할려는것 같은데
저 논리대로(물론 구현이 잘못되었지만 할려고 하는 방향으로 생각해 보면)
보면 헤드에 1번 노드를 덮어쓰고 그다음 달리는것이 헤드 다음에 2번노드가 달리게 되므로
메인에 있는 1번노드 자체는 쓸모가 없어집니다. (어드레스조차 쓸모가 없어지죠. 값만 카피되어 나갈뿐)

헤드를 하나 두고 뒤에 계속 달아가는게 올바른방법입니다.

조금 써 드리자면 (말로해서 잘 전달이 될지 모르겠네요)
헤드를 하나받고 뒷링크가 있는지 없는지 유무를 노드 탐색의 조건으로 걸고
키를 비교해서 무결성 검사를 하고 위배시 에러 뱉고
무결성검사 통과가 되면 뒤에 노드를 달아버리면 됩니다.

사실 저렇게 단순한 리스트는 구조학습의미 이외에는 의의가 거의 없지만
C 입문이면 이정도로도 뭐 충분합니다.
목록 삭게로! 맨위로
번호 제목 이름 날짜 조회
115398 심리전이 주요 소재인 영화 있나요? [19] VKRKO 3128 11/09/27 3128
115397 평일 시내 교통상황 잘 아시는 분 조언 부탁드립니다. [16] 삭제됨1204 11/09/27 1204
115396 영화를 찾고 있습니다. [4] 현묵1623 11/09/26 1623
115395 작명...어렵네요..투표 부탁드립니다. PGRer 님들 [27] 전영소년2126 11/09/26 2126
115394 최근에 갑자기 인터넷이 이상한데 왜그럴까요? [2] 언데드네버다��1220 11/09/26 1220
115393 소니 바이오 SE 17GK 신제품 어떤가요? [3] 거북거북1488 11/09/26 1488
115392 악성코드 질문입니다.. 수지남편1514 11/09/26 1514
115391 동영상 퍼가는 방법이나 다운받는 방법 [3] StevenGerrard1270 11/09/26 1270
115390 휴대전화의 약정 등 질문입니다. [2] 좋은마음1533 11/09/26 1533
115389 스마트폰에서 Adobe Flash Player 10.3 업데이트 질문입니다. [2] 으랏차차2215 11/09/26 2215
115388 [1박2일] 가장 기억에 남는 시청자 투어 3탄 참가자는?? [6] 창이2951 11/09/26 2951
115387 헬스장의 유명 가요 뽕짝 리믹스는 어디서 구할 수 있는 것일까요? [3] 아르바는버럭2747 11/09/26 2747
115386 페이스북, 여러분은 이런일 겪지 않으시나요? [3] 정용현2685 11/09/26 2685
115385 에반게리온이 명작인 이유? [41] 삭제됨7277 11/09/26 7277
115384 구글 사이트만 접속이 안됩니다. [5] ZerGaa3032 11/09/26 3032
115383 Arena가 필요합니다 CrazyNansa1546 11/09/26 1546
115382 생동성 알바 해보신분 있나요? [7] 그것이알고있다2905 11/09/26 2905
115381 노래제목 좀 알려주세요. [5] 비야레알2175 11/09/26 2175
115380 백화점 카드결재 질문드립니다. [1] 현상1598 11/09/26 1598
115378 수능 올1등급 컷의 대학 수준이 어떻게 되나요? [19] 가치파괴자10300 11/09/26 10300
115377 c 프로그래밍 구조체 포인터에 대한 질문입니다 [12] zeros2121 11/09/26 2121
115376 지난 몇 년간 온겜 엠겜 보시면서 기억 나는 장면 어떤거 있으세요? [16] 개신1705 11/09/26 1705
115375 여자에게 줄 5만원 이하 선물은 뭐가 좋을까요? [10] 다크나이트8749 11/09/26 8749
목록 이전 다음
댓글

+ : 최근 6시간내에 달린 댓글
+ : 최근 12시간내에 달린 댓글
맨 위로