(筆記) struct對function可以call by value嗎?可以return一個struct嗎? (C/C++)

Abstract

Introduction

1.根據以往的經驗，struct都是以call by address的方式，所以不確定C compiler是否能接受struct call by value的寫法。(須實驗)2.就算C compiler能接受語法，是真的call by value?還是只是call by address的syntax sugar? (須實驗)3.就算C compiler能struct call by value，效率一定遠比struct call by address差，因為struct通常都很大，且需整個struct copy進stack，再整個struct從stack內copy出來。(這點可以確定)

 1 /*  2 (C) OOMusou 2011 http://oomusou.cnblogs.com 3  4 Filename    : struct_call_by_address.c 5 Compiler    : Visual C++ 10.0 6 Description : struct call by address in C 7 Release     : 02/18/2011 1.0 8  */ 9 10 #include <stdio.h>11 #include <string.h> // strcpy()12  13 typedef struct {14   int no;15   char name[10];16 } student, *pstudent;17 18 pstudent struct_call_by_address(pstudent pboy) {19   pboy->no = 10;20   strcpy(pboy->name, "oomusou");21   printf("in function:\n");22   printf("no=%d, name=%s\n", pboy->no, pboy->name);23   return pboy;24 }25 26  int main() {27   student boy = {20, "John"};28   pstudent pboy = 0;29   30   printf("before function\n");31   printf("no=%d, name=%s\n", boy.no, boy.name);32   pboy = struct_call_by_address(&boy);33   printf("after function\n");34   printf("no=%d, name=%s\n", boy.no, boy.name);35   printf("no=%d, name=%s\n", pboy->no, pboy->name);36 }

before functionno=20, name=Johnin function:no=10, name=oomusouafter functionno=10, name=oomusouno=10, name=oomusou

13行

typedef struct {  int no;  char name[10];} student, *pstudent;

27行

student boy = {20, "John"};

28行

pstudent pboy = 0;

18行

pstudent struct_call_by_address(pstudent pboy) {

30行

printf("before function\n");printf("no=%d, name=%s\n", boy.no, boy.name);

before functionno=20, name=John

32行

pboy = struct_pass_by_address(&boy);

19行

pboy->no = 10;strcpy(pboy->name, "oomusou");

21行

printf("in function:\n");printf("no=%d, name=%s\n", pboy->no, pboy->name);

in function:no=10, name=oomusou

33行

printf("after function\n");printf("no=%d, name=%s\n", boy.no, boy.name);printf("no=%d, name=%s\n", pboy->no, pboy->name);

after functionno=10, name=oomusouno=10, name=oomusou

 1 /*  2 (C) OOMusou 2011 http://oomusou.cnblogs.com 3  4 Filename    : struct_call_by_address_2.c 5 Compiler    : Visual C++ 10.0 6 Description : struct call by address in C 7 Release     : 02/18/2011 1.0 8  */ 9 10 #include <stdio.h>11 #include <string.h> // strcpy()12  13  struct student {14   int no;15   char name[10];16 };17 18  struct student* struct_call_by_address(struct student* pboy) {19   pboy->no = 10;20   strcpy(pboy->name, "oomusou");21   printf("in function:\n");22   printf("no=%d, name=%s\n", pboy->no, pboy->name);23   return pboy;24 }25 26  int main() {27   struct student boy = {20, "John"};28   struct student *pboy = 0;29   30   printf("before function\n");31   printf("no=%d, name=%s\n", boy.no, boy.name);32   pboy = struct_call_by_address(&boy);33   printf("after function\n");34   printf("no=%d, name=%s\n", boy.no, boy.name);35   printf("no=%d, name=%s\n", pboy->no, pboy->name);36 }

13行

struct student {  int no;  char name[10];};

27行

struct student boy = {20, "John"};struct student *pboy = 0;

struct student* struct_call_by_address(struct student* pboy) {

struct_call_by_value.c / C

 1 /*  2 (C) OOMusou 2011 http://oomusou.cnblogs.com 3  4 Filename    : struct_call_by_value.c 5 Compiler    : Visual C++ 10.0 6 Description : struct call by value in C 7 Release     : 02/18/2011 1.0 8  */ 9 10 #include <stdio.h>11 #include <string.h> // strcpy()12  13 typedef struct {14   int no;15   char name[10];16 } student, *pstudent;17 18 student struct_call_by_value(student boy) {19   boy.no = 10;20   strcpy(boy.name, "oomusou");21   printf("in function:\n");22   printf("no=%d, name=%s\n", boy.no, boy.name);23   return boy;24 }25 26  int main() {27   student boy = {20, "John"};28   student boy2;29 30   printf("before function\n");31   printf("no=%d, name=%s\n", boy.no, boy.name);32   boy2 = struct_call_by_value(boy);33   printf("after function\n");34   printf("no=%d, name=%s\n", boy.no, boy.name);35   printf("no=%d, name=%s\n", boy2.no, boy2.name);36 }

before functionno=20, name=Johnin function:no=10, name=oomusouafter functionno=20, name=Johnno=10, name=oomusou

18行

student struct_call_by_value(student boy) {

34行

printf("no=%d, name=%s\n", boy.no, boy.name);printf("no=%d, name=%s\n", boy2.no, boy2.name);

no=20, name=Johnno=10, name=oomusou

boy.no與boy.name都與before function一樣，所以原本的struct未受function影響，符合call by value的觀念。

boy2.no與boy2.name與in function一樣，顯然boy2接收了function改變之後所return出來的值，這是一個重新copy出來新的struct。

1.根據以往的經驗，struct都是以call by address的方式，所以不確定C compiler是否能接受struct call by value的寫法。(須實驗)2.就算C compiler能接受語法，是真的call by value?還是只是call by address的syntax sugar? (須實驗)

在舊版C的某些實作，結構並無法傳遞參數給函數，但使用指向結構的指標卻可以

array是否能pass by value呢?

array_pass_by_value.c / C

 1 /*  2 (C) OOMusou 2011 http://oomusou.cnblogs.com 3  4 Filename    : array_call_by_value.c 5 Compiler    : Visual C++ 10.0 6 Description : array call by value in C 7 Release     : 02/18/2011 1.0 8  */ 9 10 #include <stdio.h>11 12  void array_call_by_value (int arr[]) {13   arr[0] = 2;14   printf("in function\n");15   printf("%d %d %d\n", arr[0], arr[1], arr[2]);16 }17 18 19  int main() {20   int arr[] = {1, 2, 3};21 22   printf("before function\n");23   printf("%d %d %d\n", arr[0], arr[1], arr[2]);24   array_call_by_value(arr);25   printf("after function\n");26   printf("%d %d %d\n", arr[0], arr[1], arr[2]);27 }

before function1 2 3in function2 2 3after function2 2 3

12行

void array_call_by_value (int arr[]) {

int [] array_call_by_value (int arr[]) {  arr[0] = 2;  printf("in function\n");  printf("%d %d %d\n", arr[0], arr[1], arr[2]);}

struct_call_by_value.7z (struct以call by value傳給function)
array_call_by_value.7z (array以call by value傳給function，事實上是call by address的syntax sugar)

Conclusion

2.使用typedef一次定義無pointer與有pointer兩種型別，之後的宣告會較方便。

3.struct pass by value在絕大部分的C compiler都能通過，而且也不是pass by address的syntax sugar，不過在一些很老舊的C compiler很可能不支援。

4.array沒有pass by value，就算有也是pass by address的syntax sugar，而且根本連語法都不支援return array by value。

Reference
[1] Brian W. Kernighan, DEnnis M.Ritchie 1988, The C Programming Language, Pewnrixw Hall PTR
[2] 蔡明志 譯 2006, C Primer Plus 5/e 中文精華增訂版，碁峰資訊股份有限公司
[3] 蔡明志 2009, 指標的藝術, 碁峰資訊股份有限公司

posted on 2011-02-18 20:37  真 OO无双  阅读(32199)  评论(1编辑  收藏