2017-02-17 1 views
2

두 개의 다른 함수 save_struct_model_1save_struct_model_2으로 구조체의 멤버 변수를 인쇄하려고합니다. 둘 다 잘 작동하고 올바른 값을 인쇄하는 것 같습니다. 이 두 가지는 정확하고 선호되는 것입니다.C에서 구조 포인터

#include <stdio.h> 
#include <stdlib.h> 

struct model{ 
    char *name; 
    int year; 
}; 

void save_struct_model_1(struct model *s){ 
     printf("%s ", s->name); 
     printf("%d \n",s->year); 
} 

void save_struct_model_2(struct model s){ 
     printf("%s ", s.name); 
     printf("%d \n",s.year); 
} 

int main() 
{ 

typedef struct model M; 

M * honda = (M *) malloc (sizeof(M)); 
honda->name="civic"; 
honda->year=2000; 

save_struct_model_1(honda); 
save_struct_model_2(*honda);  

return 0; 
} 
+3

두 번째 사본 임시 값과 원래의 구조체를 변경할 수 없습니다. –

+0

감사합니다. @BlagovestBuyukliev, – marc

+3

'model_1'이 거의 항상 선호됩니다. 만약 print 만하고 싶다면'void save_struct_model_1 (const struct model * s);을 사용하십시오.'struct model {int x [1000000000]; } 그러면 스택에 4GB +를 푸시합니다. 그것은 스택을 날려 버릴 것입니다, 각 통화마다 성능 저하는 말할 것도 없습니다. 그래서 struct 포인터를 전달하는 것입니다. C를 35 년 이상 해본 적이 있는데, 모델 2를 사용할 기회가 없었습니다. –

답변

3

대부분 주관적입니다. 하지만 구조체 값을 복사하지 않기 때문에 포인터 버전 (save_struct_model_1() 사용)이 더 좋다고 말할 수 있습니다.

코드에 눈에 띄는 영향을 미치지 않을 수도 있습니다.하지만 구조체에 100 명 이상의 멤버가 있고 모두 인쇄하려는 경우를 상상해보십시오.

+0

그래서 참조 나 값으로 전달하는 옵션이 주어지면 참조로 전달하는 것이 좋습니다. – marc

+1

@kris : C는 값에 의한 전달 언어입니다. 첫 번째 변형에서는 포인터 만 복사되고 두 번째 변형에서는 전체 구조체가 복사됩니다. –

+2

우선, C에서 "통과 기준"이 없습니다. 모든 것이 가치에 의해 전달됩니다. 그냥 지나가는 (가치에 따라) 것은 다릅니다. 대체로 네, 포인터를 전달하는 것이 구조 복사가 잠재적으로 비싸기 때문에 더 좋습니다. 반면에'save_struct_model_2()'를 사용하면 호출자에서'honda'가 수정 될 수 없습니다 - 당신이 원하거나 원하지 않을 수도 있습니다. 일반적으로 *가 아닌 좋은 이유가없는 한 포인터 버전을 사용한다고 말하고 싶습니다. – usr

0

save_struct_model_1 함수에서 전체 구조는 주소별로 다른 함수로 전달됩니다. 즉, 구조체의 주소 만 다른 함수로 전달됩니다. 전체 구조는 모든 멤버와 그 값을 가진 다른 함수로 전달되지 않습니다. 따라서이 구조체는 호출 된 함수에서 해당 주소로 액세스 할 수 있습니다.

함수에서 전체 구조체는 value에 의해 다른 함수로 전달됩니다. 이는 전체 구조체가 모든 멤버와 그 값을 가진 다른 함수로 전달됨을 의미합니다. 따라서이 구조체는 호출 된 함수에서 액세스 할 수 있습니다. C.

에 매우 큰 프로그램을 작성하면서이 개념은
-1

은 내가 이렇게 거라고 생각 매우 유용합니다

값에 의해 가리키는 const 포인터 및 전달 구조체에 의해 통과 구조체의 차이는 후자이다
int //to singnal errors in printf 
save_struct_model_3(struct model const *s){ 
     //const to guarantee immutability 
     int r = 0; 
     r |= 0>printf("%s ", s->name); 
     r |= 0>printf("%d \n",s->year); 
     return -r; 
} 

아주 작은 구조체 (덜 간접적 인 경우)에서는 약간 더 빠르지 만, 전자는 다른 모든 구조체 (복사하지 않음)보다 빠릅니다.

오버 헤드를 한 번 측정했는데 x86_64에서 구조체의 크기가 int32_t보다 크거나 같을 때 값으로 전달되기 시작하면 포인터로 구조체를 전달하는 것이 좋은 기본 전략입니다. 여기

내 벤치 마크 결과입니다 :`* honda`에서

n_ints val/ns ptr/ns 
1 4.552 5.544 
2 4.748 5.336 
3 4.712 5.572 
4 5.556 5.460 << 
5 6.180 4.436 
6 5.252 5.424 
7 5.620 4.100 
8 4.316 4.164 
9 5.612 4.220 
10 6.656 4.656 
11 6.148 4.472 
12 6.708 4.708 
13 6.192 5.200 
14 8.560 4.652 
15 7.392 4.620 
16 8.512 4.728 
17 8.244 5.488 
18 10.108 5.360 
19 8.540 4.740 
20 10.028 5.468