日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

结构和其他数据形式

發布時間:2023/12/1 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 结构和其他数据形式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

0x01 結構聲明

結構聲明(structure declaration)描述了一個結構的組織布局。

struct book{char title[MAXTITL];char author[MAXAUTL];float value; };

該聲明描述了一個由兩個字符數組和一個float類型變量組成的結構。該聲明并未創建實際的數據對象,只描述了該對象由什么組成。
struct,它表明跟在其后的是一個結構,后面是一個可選的標記(該例中是 book),稍后程序中可以使用該標記引用該結構。
我們在后面的程序中可以這樣聲明:

struct book library;

這把library聲明為一個使用book結構布局的結構變量。

#include "stdio.h"#define MAXTITL 30 #define MAXAUTL 30struct book{char title[MAXTITL];char author[MAXAUTL];float value; };int a; struct book book2; int main() {struct book book1={"Hello","d1l1endh",7.6};printf("title=%s\n",book1.title);printf("author=%s\n",book1.author);printf("value=%f\n",book1.value);return 0; }

反匯編我們看看結構聲明會產生什么:

struct book相當于一個類型,和int 相似,book2相當于a,結構布局告訴編譯器如何表示數據,但是它并未讓編譯器為數據分配空間。

0x02 定義結構變量

struct book book2;

編譯器執行這行代碼便創建了一個結構變量book2。編譯器使用book模
板為該變量分配空間:一個內含MAXTITL個元素的char數組、一個內含
MAXAUTL個元素的char數組和一個float類型的變量。這些存儲空間都與一
個名稱book2結合在一起
struct book book2;
是以下聲明的簡化:

struct book { char title[MAXTITL]; char author[AXAUTL]; float value; } book2; 

換言之,聲明結構的過程和定義結構變量的過程可以組合成一個步驟。如果打算多次使用結構模板,就要使用帶標記的形式;或者,使用typedef。

2.1 初始化結構

初始化一個結構變量(ANSI之前,不能用自動變量初始化結構;ANSI之后可以用任意存儲類別)與初始化數組的語法類似:

struct book book1={"Hello","d1l1endh",7.6};
2.2 訪問結構成員

使用結構成員運算符——點(.)訪問結構中的成員。

0x03 嵌套結構

在一個結構中包含另一個結構

#include "stdio.h"#define LEN 30struct names{char first[LEN];char last[LEN]; };struct guy{struct names handle;char favfood[LEN];char job[LEN];float income;};int main() {struct guy fellow={{"Ell","end"},"salmon","programmer",100000};printf("firset=%s\n",fellow.handle.first);printf("job=%s\n",fellow.job);printf("income=%f\n",fellow.income);return 0; }

訪問嵌套結構的成員,這需要使用兩次點運算符。handle是fellow的成員,first是handle的成員

0x04 指向結構的指針

4.1 聲明和初始化指針

我們定義一個int類型指針是:

int *p;

結構也是一種類型,所以聲明結構體指針很簡單

struct guy *him;

struct guy 是一種類型,相當于int,這個語法和其他指針聲明一樣。該聲明并未創建一個新的結構,但是指針him現在可以指向任意現有的guy類型的結構。如果barney是一個guy類型的結構,可以這樣寫:

him = &barney;

和數組不同的是,結構名并不是結構的地址,因此要在結構名前面加上&運算符。

4.2 用指針訪問成員

使用->運算符。
->運算符后面的結構指針和.運算符后面的結構名工作方式相同
如果him == &barney,那么him->income 即是 barney.income

4.3 向函數傳遞結構的信息

這里我們重點說傳遞結構的地址和傳遞結構
傳遞結構的地址

#include "stdio.h"#define LEN 30struct names{char first[LEN];char last[LEN]; };struct guy{struct names handle;char favfood[LEN];char job[LEN];float income;};double sum(struct guy *);int main() {struct guy fellow={{"Ell","end"},"salmon","programmer",100000};double sum_income=sum(&fellow);//printf("firset=%s\n",fellow.handle.first);//printf("job=%s\n",fellow.job);printf("sum_income=%f\n",sum_income);return 0; }double sum(struct guy *people) {return (people->income+people->income); }


因為結構名不是其地址別名,所以我們必須用&運算符,然后通過->運算符獲取值

傳遞結構

#include "stdio.h"#define LEN 30struct names{char first[LEN];char last[LEN]; };struct guy{struct names handle;char favfood[LEN];char job[LEN];float income;};double sum(struct guy );int main() {struct guy fellow={{"Ell","end"},"salmon","programmer",100000};double sum_income=sum(fellow);//printf("firset=%s\n",fellow.handle.first);//printf("job=%s\n",fellow.job);printf("sum_income=%f\n",sum_income);return 0; }double sum(struct guy people) {return (people.income+people.income); }

傳遞結構直接把結構名當參數就行

0x05 typedef

typedef工具是一個高級數據特性,利用typedef可以為某一類型自定義名稱。

typedef unsigned char BYTE;

隨后,便可使用BYTE來定義變量:

BYTE x, y[10], * z;

該定義的作用域取決于typedef定義所在的位置。

0x06 函數與指針

聲明一個函數指針時,必須聲明指針指向的函數類型。為了指明函數類型,要指明函數簽名,即函數的返回類型和形參類型。

void ToUpper(char *); // 把字符串中的字符轉換成大寫字符

ToUpper()函數的類型是“帶char * 類型參數、返回類型是void的數”。

void (*pf)(char *);  // pf 是一個指向函數的指針

第1對圓括號把*和pf括起來,表明pf是一個指向函數的指針
把**函數名ToUpper替換為表達式(*pf)**是創建指向函數指針最簡單的方式。
所以,如果想聲明一個指向某類型函數的指針,可以寫出該函數的原型后把函數名替換成(*pf)形式的表達式,創建函數指針聲明。

#include "stdio.h"void add(int a,int b);void main(void) {int a=4,b=3,s=0;void (*funp)(int a,int b);funp=add;(*funp)(a,b);funp(a,b);}void add(int a,int b) {printf("a+b=%d\n",a+b);}


聲明一個函數指針時,必須聲明指針指向的函數類型。包括返回值、參數,如果想聲明一個指向某類型函數的指針,可以寫出該函數的原型后把函數名替換成(*pf)形式的表達式,這樣就聲明好一個函數指針了。用函數指針調用函數是有兩種方式:

  • 指針名(參數)
  • (* 指針名)(參數)
    我們反匯編看一下
9: void (*funp)(int a,int b); 10: funp=add; 00410B2D C7 45 F0 0F 10 40 00 mov dword ptr [ebp-10h],offset @ILT+10(_add) (0040100f) 11: (*funp)(a,b); 00410B34 8B F4 mov esi,esp 00410B36 8B 45 F8 mov eax,dword ptr [ebp-8] 00410B39 50 push eax 00410B3A 8B 4D FC mov ecx,dword ptr [ebp-4] 00410B3D 51 push ecx 00410B3E FF 55 F0 call dword ptr [ebp-10h] 00410B41 83 C4 08 add esp,8 00410B44 3B F4 cmp esi,esp 00410B46 E8 E5 06 FF FF call __chkesp (00401230)

可以看出,把首地址賦值給我們的函數指針,也就是把函數首地址放到dword ptr [ebp-10h]里,調用的時候直接call dword ptr [ebp-10h],和平常調用函數一樣

總結

以上是生活随笔為你收集整理的结构和其他数据形式的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。