圖片來自網上
一、結構體與函式引數
結構體作函式引數可分為
傳值與傳指標
。
1.傳值時結構體引數會被複製一份,在函式體內修改結構體引數成員的值實際上是修改呼叫引數的一個臨時複製的成員的值,這不會影響到呼叫引數。在這種情況下,由於涉及到結構體引數的複製,程式空間及時間效率都會受到影響,所以這種方法
基本不用。
例如:
typedef struct tagSTUDENT{
char name[20];
int age;
}STUDENT;
void fun(STUDENT stu)
{
printf(“stu。name=%s,stu。age=%d/n”,stu。name,stu。age);
}
2.傳指標時直接將結構體的
首地址
傳遞給函式體,在函式體中透過指標引用結構體成員,可以對結構體引數成員的值造成實際影響。這種用法
效率高,經常採用
。
例如:
typedef struct tagSTUDENT{
char name[20];
int age;
}STUDENT;
void fun(STUDENT* pStu)
{
printf(“pStu->name=%s,pStu->age=%d/n”,pStu->name,pStu->age);
}
二、結構體與函式返回值
對於某些版本的C語言編譯器,返回值僅能為基本資料型別如int、char以及指標,因此結構體作為一種組合資料型別,不能以值的方式返回,而在有些版本的C編譯器中又可以直接返回結構體變數 ,在C++中也是可以直接返回結構體變數的。
直接返回結構體變數示例如下;
typedef struct tagSTUDENT{
char name[20];
int age;
}STUDENT;
STUDENT fun();
int _tmain(int argc, _TCHAR* argv[])
{
STUDENT p=fun();
printf(“p。name=%s”,p。name);
return 0;
}
STUDENT fun()
{
STUDENT stu;
stu。age=18;
strcpy(stu。name,“xiaoming”);
return stu;
}
以指標方式返回結構體示例如下:
typedef struct tagSTUDENT{
char name[20];
int age;
}STUDENT;
STUDENT* fun()
{
STUDENT* p=malloc(sizeof(STUDENT));
p->age=18;
strcpy(p->name,“xiaoming”);
return p;
}
關於結構體中含有位域的問題:
C99規定int、unsigned int和bool可以作為位域型別,但編譯器幾乎都對此作了擴充套件,允許其它型別型別的存在。
使用位域的主要目的是壓縮儲存,其大致規則為:
1) 如果相鄰位域欄位的型別相同,且其位寬之和小於型別的sizeof大小,則後面的欄位將緊鄰前一個欄位儲存,直到不能容納為止;
2) 如果相鄰位域欄位的型別相同,但其位寬之和大於型別的sizeof大小,則後面的欄位將從新的儲存單元開始,其偏移量為其型別大小的整數倍;
3) 如果相鄰的位域欄位的型別不同,則各編譯器的具體實現有差異,VC6採取不壓縮方式,Dev-C++採取壓縮方式;
4) 如果位域欄位之間穿插著非位域欄位,則不進行壓縮;
5) 整個結構體的總大小為最寬基本型別成員大小的整數倍。
還是讓我們來看看例子。
struct A{
char f1 : 3;
char f2 : 4;
char f3 : 5;
};
a b c
A的記憶體佈局:
111, 1111 *, 11111 * * *
位域型別為char,第1個位元組僅能容納下f1和f2,所以f2被壓縮到第1個位元組中,而f3只能從下一個位元組開始。因此sizeof(A)的結果為2。
struct B{
char f1 : 3;
short f2 : 4;
char f3 : 5;
};
由於相鄰位域型別不同,在VC6中其sizeof為6;
struct C{
char f1 : 3;
char f2;
char f3 : 5;
};
非位域欄位穿插在其中,不會產生壓縮,在VC6中得到的大小均為3。
提示:
在設計結構體的時候,一般會尊照一個習慣,就是把佔用空間小的型別排在前面,佔用空間大的型別排在後面,這樣可以相對節約一些對齊空間!