嵌入式C學習第四次任務

2021-10-19 05:11:10 字數 4263 閱讀 5470

#include #include using namespace std;

struct student

;void outcome(student s)

;//引用傳遞不會進行記憶體重新分配,因此和指標傳參類似,效率很高

void outcome(student &s) //引用傳參

;void outcome(student *s)

#ifndef _fun_h_ //條件編譯,解決檔案重複包含所引起的重定義問題

#define _fun_h_

struct student

;extern int global_var;

extern struct student wang;

#endif

#include "fun1.h" //沒有實際**

#include "fun.h" //包含fun.h

#include "stdio.h"

#include "fun.h"

#include "fun1.h"

//extern int global_var;

//extern struct student wang;

int main(void)

總結:優點:解決了檔案重複包含造成的重定義問題;函式,全域性變數,結構體,結構體變數都能在外部呼叫;每一處呼叫變數的檔案處不用重複的寫宣告語句,因為宣告語句直接寫在了.h標頭檔案中,直接包含標頭檔案即可。

大多數處理器中記憶體是可以以位元組為單位進行定址的,當資料型別(int, long)大於1個位元組時,其所占用就的位元組在記憶體中的順序存在兩種模式,分別是小端模式(little endian)和大端模式(big endian)。小端模式低位位元組存放在低位址,大端模式高位位元組存放在低位址。

位元組序,就是 大於乙個位元組型別的資料在記憶體中的存放順序。是在跨平台和網路程式設計中,時常要考慮的問題。

在十進位制中靠左邊的是高位,靠右邊的是低位,在其他進製也是如此。例如 0x12345678,從高位到低位的位元組依次是0x12、0x34、0x56和0x78。

網路位元組序 就是 大端位元組序:4個位元組的32 bit值以下面的次序傳輸,首先是0~7bit,其次8~15bit,然後16~23bit,最後是24~31bit

主機位元組序 就是 小端位元組序,現代pc大多採用小端位元組序。

位元組序有兩種,大端和小端

採用little-endian模式的cpu對運算元的存放方式是從低位元組到高位元組,而big-endian模式對運算元的存放方式是從高位元組到低位元組。

小端儲存後:0x78563412  大端儲存後:0x12345678

1. 記憶體以8bit為乙個位址單位:早期的處理器位址以8bit為乙個單位(8位處理器),也就是說一次可以訪問8bit的資料,後來出現了16位,32位甚至64位的處理器,但為了相容最早的8位處理器,因此沿用8bit為乙個位址單位。

2. 大於8位的處理器,如32位處理器,雖然每個8bit(乙個位元組)儲存資料的方式是一樣的,但是針對整形這樣的有多個位元組的資料結構的資料,每個位元組內儲存資料方式相同,但位元組間(即幾個位元組的順序)儲存方式不同。

3.其他歷史原因.

不同的處理器結構對整形這樣的大資料型別的每個位元組在記憶體中存放順序不一樣,這樣,在不同架構的處理器平台進行通訊時,就產生了位元組序的問題。

不同處理器的通訊一般通過網路通訊進行,於是我們統一了網路位元組序(使用大端位元組序)。

關鍵點:

位元組序:  大整形資料型別(如int,short,而char就不算了)的資料中各個位元組在記憶體的儲存書序。

一般在網路通訊是需要關注。

16表示16bit,short佔16位。 32表示32位,unsigned int 佔32位。

h表示host, n表示network。 l表示long, s表示short

有些資訊在儲存時,並不需要占用乙個完整的位元組, 而只需佔幾個或乙個二進位制位。例如在存放乙個開關量時,只有0和1 兩種狀態, 用一位二進位即可。為了節省儲存空間,並使處理簡便,c語言又提供了一種資料結構,稱為「位域」或「位段」。所謂「位域」是把乙個位元組中的二進位劃分為幾 個不同的區域,並說明每個區域的位數。每個域有乙個網域名稱,允許在程式中按網域名稱進行操作。 這樣就可以把幾個不同的物件用乙個位元組的二進位制位域來表示。

位域通過乙個結構宣告來建立:該結構宣告為每個字段提供標籤,並確定該字段的寬度。例如,下面的宣告建立了個4個1位的字段:

struct 

prnt;

根據該宣告, prnt包含4個1位的字段。現在,可以通過普通的結構成員運算子(.)單獨給這些字段賦值:

prnt.itals = 0:

prnt.undin = 1;

由於每個字段恰好為1位,所以只能為其賦值1或0。變數prnt被儲存在int大小的記憶體單元中,但是在本例中只使用了其中的4位。

:後面的數字用來限定成員變數占用的位數。位域的寬度不能超過它所依附的資料型別的長度。通俗地講,成員變數都是有型別的,這個型別限制了成員變數的最大長度,:後面的數字不能超過這個長度。

如上述結構中autfd、bldfc、undin、itals後面的數字不能超過unsigned int的位數,即在32bit環境中就是不能超過32。

其中位域列表的形式為: 型別說明符 位網域名稱:位域長度     

例如:     

struct bs     

;

位域變數的說明與結構變數說明的方式相同。 可採用先定義後說明,同時定義說明或者直接說明這三種方式。例如:     

說明data為bs變數,共佔兩個位元組。其中位域a佔8位,位域b佔2位,位域c佔6位。

使用位域的主要目的是壓縮儲存,其大致規則為:

1) 如果相鄰位域字段的型別相同,且其位寬之和小於型別的sizeof大小,則後面的字段將緊鄰前乙個字段儲存,直到不能容納為止

2) 如果相鄰位域字段的型別相同,但其位寬之和大於型別的sizeof大小,則後面的字段將從新的儲存單元開始,其偏移量為其型別大小的整數倍;

3) 如果相鄰的位域字段的型別不同,則各編譯器的具體實現有差異,vc6採取不壓縮方式,dev-c++,gcc採取壓縮方式;

4) 如果位域字段之間穿插著非位域字段,則不進行壓縮;

5) 整個結構體的總大小為最寬基本型別成員大小的整數倍。

第乙個結構體中,i,j,a共佔15個位,不足8個位元組,按double 8位元組對齊,共16位元組

第二個結構體中,i,j共佔12位,不足8位元組,按8位元組對齊,a也按8位元組對齊,加上double共8+8+8=24個位元組

char* fun1(char* p1, char* p2)// 1

char** fun2(char* p1, char* p2);// 2

char*(*fun3)(char* p1, char* p2);// 3

1,2,3分別是什麼意思呢?

int (*) [10]p//陣列指標
這裡的fun3不是函式名,是指標變數,它指向乙個函式。

函式指標的定義就是,乙個指向函式的指標

我們上面定義了乙個函式指標,那我們該如何使用它呢?

我們在使用指標的時候,需要通過鑰匙「 * 」來取其指向的記憶體的值,函式指標使用也如此。通過用(*fun1)取出該位址的函式然後呼叫他。也可以直接使用fun1,因為函式名被編譯後其實就是乙個位址。

char* (*fun[3])(char* p);//函式指標陣列
它是乙個陣列,陣列名是fun,陣列記憶體了3個指向函式的指標。這些指標指向的一些返回值型別為指向字元的指標,引數為乙個指向字元指標的函式。

我一開始看到這東西我腦子裡都是???,然後查了些部落格啥的就弄清楚了。我們都知道什麼事陣列指標,套用陣列指標的理解來理解函式指標陣列不就好了嗎?

char* (*(*fun)[3]))(char* p);

嵌入式c第四次作業

一,結構體的引數傳遞 首先結構體做函式引數有三種傳遞方式 一是傳遞結構體變數,這是值傳遞,二是傳遞結構體指標,這是位址傳遞,三是傳遞結構體成員,當然這也分為值傳遞和位址傳遞。以傳引用呼叫方式傳遞結構比用傳值方式傳遞結構效率高。以傳值方式傳遞結構需要對整個結構做乙份拷貝。下面看乙個列子,student...

嵌入式第四次課堂總結

偵錯程式 gdb 1.gnu計畫的工具 核心除錯kgdb 2.程式的錯誤分類 編譯時錯誤 語法錯誤 執行時錯誤 記憶體錯誤,邏輯錯誤 3.gdb的功能 執行程式 設定斷點 檢視變數的值 4.gdb的用法 hello.c gcc g hello.c o hello gdb hello 可執行檔案 gd...

第四次任務

一 etc passwd 的 檔案結構 從下面的例子我們可以看到,etc passwd中一行記錄對應著乙個使用者,每行記錄又被冒號 分隔為7個字段,其格式和具體含義如下 root x 0 0 root root bin bash 使用者名稱 口令 使用者標識號 組標識號 注釋性描述 主目錄 登入sh...