/********************************************************************** * 版權所有 (C)2017, Wang maochun。 * * 文件名稱:stu.c * 文件標識:無 * 內容摘要:演示程序 * 其它說明:主要學習三點知識: 1.建立一個結構體,類型名為student 2.當定義結構體變量時,通過成員操作符訪問成員(.) 當定義指向結構體的指針時,通過間接訪問操作符(->) 3.傳值操作,子函數對實參進行了一份拷貝,對其的操作不會影響到orginal value,我們通過打印地址和實參不同可以看到 傳址操作,子函數傳遞了實參地址,此時操作的是orginal value,優點是節省空間和花銷。如果子函數不修改需const修飾 * 當前版本:V1.0 * 作 者:Wang maochun * 完成日期:2017.7.23 * **********************************************************************/ #include <stdio.h> struct student{ int code; char name[10]; char sex[10]; int age; }; void printStuInfobyValue(student stu) { printf("in fun結構體傳值:學號、姓名、性別、年齡:\n"); printf("%5d [%p]\n %5s [%p]\n %5s [%p]\n %5d [%p]\n\n",stu.code,&stu.code,stu.name,&stu.name, stu.sex,&stu.sex,stu.age,&stu.age); } void printStuInfoByAdress(student* pstu) { printf("in fun結構體傳地址:學號、姓名、性別、年齡:\n"); printf("%6d [%p]\n %6s [%p]\n %6s [%p]\n %6d [%p]\n\n",pstu->code,&pstu->code,pstu->name,&pstu->name, pstu->sex,&pstu->sex,pstu->age,&pstu->age); } int main(){ //struct student stu; student stu = {123,"wsq","Male",23}; student *pstu = &stu; printf("in main:學號、姓名、性別、年齡:\n"); //scanf("%d %s %s %d",&stu.code,stu.name,stu.sex,&stu.age); printf("%5d [%p]\n %5s [%p]\n %5s [%p]\n %5d [%p]\n\n",stu.code,&stu.code,stu.name,&stu.name, stu.sex,&stu.sex,stu.age,&stu.age); printf("%6d [%p]\n %6s [%p]\n %6s [%p]\n %6d [%p]\n\n",pstu->code,&pstu->code,pstu->name,&pstu->name, pstu->sex,&pstu->sex,pstu->age,&pstu->age); printStuInfobyValue(stu); //結構體傳值 printStuInfoByAdress(&stu); //結構體傳地址 return 0; }
運行效果:
我們可以看到:
結構體對象作為參數時,編譯器對其進行了copy,(我們通過傳入的地址和main中不同可以發現)。此時在函數中的操作都是對其拷貝的操作,不影響main函數中的origin value
缺點是,當結構體變量非常大時,編譯器對其進行復制,開銷較大。
用結構體變量作實參時,采取的是"值傳遞"的方式,將結構體變量所占的內存單元的內容全部順序傳遞給形參.形參也必須是同類型的結構體變量.在函數調用期間形參也要占用內存單元. 這種傳遞方式在空間和時間上開銷較大,如果結構體的規模很大時,開銷是很可觀的.
結構體地址作為參數時,子函數中操作和main函數操作的是同一個結構體,此時傳遞的參數時一個地址。
優點是不需要進行copy,但是使用時要小心,如果不想修改其值,需用const關鍵字修飾