1. 程式人生 > 其它 >嵌入式C學習第四課

嵌入式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。

LSB 0 位序是指:位元組的第0位存放資料的least significant bit,即我們的資料的最低位存放在位元組的第0位。
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。這是因為函式名被編譯之後其實就是一個地址,所以這裡兩種用法沒有本質的差別。

參考文章:https://blog.csdn.net/weixin_41055260/article/details/108313923?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-2&spm=1001.2101.3001.4242