嵌入式C學習第四課
技術標籤:嵌入式C
結構體的引數傳遞
參考文章:https://blog.csdn.net/lin37985/article/details/38582027
一是傳遞結構體變數,這是值傳遞,二是傳遞結構體指標,這是地址傳遞,三是傳遞結構體成員,當然這也分為值傳遞和地址傳遞。
以傳引用呼叫方式傳遞結構比用傳值方式傳遞結構效率高。以傳值方式傳遞結構需要對整個結構做一份拷貝。
下面看一個列子,student結構體中包含該學生的各種資訊,我們在change函式中對其進行部分修改,再在主函式中輸出其結果
1.下面傳遞結構體變數
#include<stdio.h> #include<string.h> #define format "%d\n%s\n%f\n%f\n%f\n" struct student { int num; char name[20]; float score[3]; }; void change( struct student stu ); int main() { struct student stu; stu.num = 12345; strcpy(stu.name, "Tom"); stu.score[0] = 67.5; stu.score[1] = 89; stu.score[2] = 78.6; change(stu); printf(format, stu.num, stu.name, stu.score[0], stu.score[1],stu.score[2]); printf("\n"); return 0; } void change(struct student stu) { stu.score[0] = 100; strcpy(stu.name, "jerry"); }
輸出結果不變
2.地址傳遞
<span style="font-family:Arial Black;font-size:12px;">#include<stdio.h> #include<string.h> #define format "%d\n%s\n%f\n%f\n%f\n" struct student { int num; char name[20]; float score[3]; }; void change( struct student* stu ); int main() { struct student stu; stu.num = 12345; strcpy(stu.name, "Tom"); stu.score[0] = 67.5; stu.score[1] = 89; stu.score[2] = 78.6; change(&stu); printf(format, stu.num, stu.name, stu.score[0], stu.score[1],stu.score[2]); printf("\n"); return 0; } void change(struct student* p) { p->score[0] = 100;//提取資料 strcpy(p->name, "jerry"); }</span>
可以看到,通過地址傳遞修改了結構體內的資料
用&stu做實參,&stu是結構體變數stu的地址。在呼叫函式時將該地址傳送給形參p(p是指標變數)。這樣p就指向stu。
在change函式中改變結構體內成員的值,在主函式中就輸出了改變後的值
檔案的包含
#include操作是,若後面帶的是<>,則檔案在安裝路徑中找;若後面帶的是“”,則檔案在源目錄中找。
大小端和位元組序
位元序 / 位序
我們知道一個位元組有8位,也就是8個位元位。從第0位到第7位共8位。位元序就是用來描述位元位在位元組中的存放順序的。
(1)位元序分為兩種:LSB 0 位序和MSB 0 位序。
LSB是指 least significant bit,MSB是指 most significant bit。
MSB 0 位序是指:位元組的第0位存放資料的most significant bit,即我們的資料的最高位存放在位元組的第0位。
所以說對於程式碼:char *ch = 0x96; // 0x96 = 1001 0110
指標ch到底指向哪裡呢?不難知道,如果是LSB 0 位序則顯然指標ch指向最右邊的也是最低位的0.
而如果是MSB 0 位序則顯然指標ch指向最左邊的也是最高位的1.
(2)小端CPU通常採用的是LSB 0 位序,但是大端CPU卻有可能採用LSB 0 位序也有可能採用的是MSB 0 位序
(3)推薦的標準是MSB 0 位序。
大小端和位元組序
術語“端”是指:在記憶體中的一個較大的資料,它是由各個可以被單獨定址的部分組成,這些組成部分在該資料中是以怎樣的順序存放的呢?而這個問題涉及到“端”的概念,CPU是大端還是小端決定了這些組成部分的存放順序。這些組成部分可能是16或32位的字、8位的位元組、甚至是位元位。
0x0A0B0C0D在大小端儲存器上的排列順序:
小端
大端
很顯然“小端”機器符合“高高低低”的原則,即高位位元組或字存放在高地址,低位位元組或字存放在低地址。
另外“小端”機器中,資料在CPU的暫存器和記憶體中的存放順序是一致的。
位域
參考文章:https://blog.csdn.net/zhengnianli/article/details/8zhi7386078
函式指標
函式指標定義:函式指標是指向函式的指標變數。因此“函式指標”本身首先應是指標變數,只不過該指標變數指向函式。這正如用指標變數可指向整型變數、字元型、陣列一樣,這裡是指向函式。
其通用表示式為:型別說明符 (*函式名) (引數)
int (*fun)(int x) //函式指標的定義
int (*fun)(int x,int y) //函式指標的定義
函式指標的賦值
函式指標和其他指標一樣定義之後使用之前也是需要初始化。
函式指標有兩個用途:呼叫函式
和做函式的引數
int (*fun)(int x,int y) //函式指標的定義
fun = &Function //函式指標的賦值方式1
fun = Function //函式指標的賦值方式2
x = (*fun)() //函式指標的呼叫方式1
x = fun() //函式指標的呼叫方式2
函式賦值的時候取地址運算子&
不是必需的,因為一個函式識別符號就表示了它的地址,並且賦值的時候函式不需要帶圓括號;
如果是函式呼叫,還必須包含一個圓括號括起來的引數表。
函式指標的用法
我們使用指標的時候,需要通過鑰匙*
來取其指向的記憶體裡面的值,函式指標使用也如此。通過用(*pf)
取出存在這個地址上的函式,然後呼叫它。
char* fun(char* p1,char* p2)
{
int i = 0;
i = strcmp(p1,p2);
if(0 == i)
{
return p1;
}
else
{
return p2;
}
}
int main()
{
char * (*pf)(char* p1,char* p2);
pf = &fun;
(*pf)("aa","bb");
return 0;
}
這裡需要注意到是,在Visual C++6.0
裡,給函式指標賦值時,可以用&fun
或直接用函式名fun
。這是因為函式名被編譯之後其實就是一個地址,所以這裡兩種用法沒有本質的差別。