溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

怎么用C語言玩轉(zhuǎn)結(jié)構(gòu)體

發(fā)布時(shí)間:2021-09-27 13:36:01 來源:億速云 閱讀:126 作者:小新 欄目:開發(fā)技術(shù)

小編給大家分享一下怎么用C語言玩轉(zhuǎn)結(jié)構(gòu)體,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

    一、結(jié)構(gòu)體的聲明與定義

    1.結(jié)構(gòu)體的聲明

    結(jié)構(gòu)是一些值的集合,這些值稱為成員變量。結(jié)構(gòu)的每個(gè)成員可以是不同類型的變量

    當(dāng)我們面對(duì)的事物有多個(gè)不同的數(shù)據(jù)類型的時(shí)候,我們就可以使用結(jié)構(gòu)體來組織了。

    比如說,一本書有書名、作者、售價(jià)、出版日期等等不同的數(shù)據(jù)類型,這時(shí)候我們可以創(chuàng)建結(jié)構(gòu)體來包含書的不同數(shù)據(jù)類型。

    而結(jié)構(gòu)體聲明是描述結(jié)構(gòu)體組合的主要方法,語法格式為:

    struct 結(jié)構(gòu)體名稱
    {
    結(jié)構(gòu)體成員1;
    結(jié)構(gòu)體成員2;
    結(jié)構(gòu)體成員3;

    };//分號(hào)不能丟

    【注意】

    結(jié)構(gòu)體成員既可以是任何一種基本的數(shù)據(jù)類型,也可以是另一種結(jié)構(gòu)體,如果是后者就相當(dāng)于結(jié)構(gòu)體的嵌套。(俗稱套娃)

    例如:

    struct Book//描述一本書的相關(guān)屬性,其中Book是這個(gè)框架的名稱
    {
    	char name[20];//書名
    	char author[20];//作者
    	float price;//價(jià)格
    };//分號(hào)一定不能丟

    這樣就相當(dāng)于描述了一本書的框架。

    2.結(jié)構(gòu)成員的類型

    結(jié)構(gòu)成員的類型可以是標(biāo)量、數(shù)組、指針、甚至是其他結(jié)構(gòu)體。

    3.結(jié)構(gòu)體的定義

    結(jié)構(gòu)體的聲明只是進(jìn)行一個(gè)簡單的描述,實(shí)際上在沒有定義結(jié)構(gòu)體類型變量之前,它是不會(huì)在內(nèi)存中分配空間的。

    也就是說,它還沒有被真正使用,虛擬存在,只有定義了結(jié)構(gòu)體類型變量,才真實(shí)存在。

    舉個(gè)例子,上面定義了書的框架

    struct Book//描述一本書的相關(guān)屬性,其中Book是這個(gè)框架的名稱
    {
    	char name[20];//書名
    	char author[20];//作者
    	float price;//價(jià)格
    };//分號(hào)一定不能丟

    這里在編譯器中,并不會(huì)分配內(nèi)存空間,它僅僅是虛擬存在。而一旦我們定義了結(jié)構(gòu)體類型變量,它就可以被分配空間了。

    比如:

    struct Book//描述一本書的相關(guān)屬性,其中Book是這個(gè)框架的名稱
    {
    	char name[20];//書名
    	char author[20];//作者
    	float price;//價(jià)格
    };//分號(hào)一定不能丟
    int main()
    {
    	struct Book book;//局部變量--放在棧區(qū)
    	return 0;
    }

    我們?cè)谏厦胬又幸部梢宰⒁獾?,定義結(jié)構(gòu)體變量的語法是:

    struct 結(jié)構(gòu)體名稱 結(jié)構(gòu)體變量名

    此外,還可以在結(jié)構(gòu)體聲明的時(shí)候定義結(jié)構(gòu)體變量

    struct Book//描述一本書的相關(guān)屬性
    {
    	char name[20];
    	char author[20];
    	float price;
    }b1,b2;//b1,b2是全局變量。放在靜態(tài)區(qū)
    int main()
    {
    	struct Book book;//局部變量--放在棧區(qū)
    	return 0;
    }

    b1、b2結(jié)構(gòu)體變量是一個(gè)全局變量,在其他函數(shù)中也可以對(duì)它進(jìn)行訪問。

    二、初始化結(jié)構(gòu)體

    我們?cè)诙x一個(gè)變量或數(shù)組的時(shí)候可以對(duì)其進(jìn)行初始化,

    例如:

    int a=10;
    int arr[10]={1,2,3,4,5,6,7,8,9,0};

    同理,定義結(jié)構(gòu)體變量的時(shí)候,我們也可以同時(shí)為其初始化

    struct Book//描述一本書的相關(guān)屬性
    {
    	char name[20];
    	char author[20];
    	float price;
    }b1,b2;//b1,b2是全局變量。放在靜態(tài)區(qū)
    int main()
    {
    	struct Book book=
    	{
    	"《笑傲江湖》","金庸",30
    	};//這樣的話,就將結(jié)構(gòu)體變量初始化了,也就是定義變量的同時(shí)賦初值
    	return 0;
    }

    三、訪問結(jié)構(gòu)體成員

    結(jié)構(gòu)體變量訪問成員 結(jié)構(gòu)變量的成員是通過點(diǎn)操作符(.)訪問的。點(diǎn)操作符接受兩個(gè)操作數(shù)。

    比如,book.name就是引用book結(jié)構(gòu)體變量的name成員,它是一個(gè)字符數(shù)組。

    #include <stdio.h>
    struct Book//描述一本書的相關(guān)屬性
    {
    	char name[20];
    	char author[20];
    	float price;
    }b1, b2;//b1,b2是全局變量。放在靜態(tài)區(qū)
    int main()
    {
    	struct Book book=
    	{
    		"《笑傲江湖》", "金庸", 30
    	};//這樣的話,就將結(jié)構(gòu)體變量初始化了,也就是定義變量的同時(shí)賦初值
    	printf("%s %s %f\n", book.name, book.author, book.price);
    //用. 來訪問
    	return 0;
    }

    怎么用C語言玩轉(zhuǎn)結(jié)構(gòu)體

    四、結(jié)構(gòu)體嵌套

    如果訪問嵌套的結(jié)構(gòu)體成員的話,就需要使用多層點(diǎn)號(hào)運(yùn)算符來進(jìn)行操作。因?yàn)镃語言的結(jié)構(gòu)體只能對(duì)最底層的成員進(jìn)行訪問,如果存在多級(jí)結(jié)構(gòu)體嵌套的話,就需要一級(jí)一級(jí)地深入,直到找到最底層的成員才行

    struct S
    {
    	int a;
    	char c;
    	double d;
    };
    struct T
    {
    	struct S s;//結(jié)構(gòu)體嵌套
    	char name[20];
    	int num;
    };
    int main()
    {
    	struct T t = { {100,'c',3.14},"里斯",30 };
    	printf("%d %c %f %s %d\n", t.s.a, t.s.c, t.s.d, t.name, t.num);//使用了兩層點(diǎn)號(hào)運(yùn)算符尋找成員
    	return 0;
    }

    怎么用C語言玩轉(zhuǎn)結(jié)構(gòu)體

    五、結(jié)構(gòu)體指針

    在開頭的時(shí)候說過,結(jié)構(gòu)的成員可以是標(biāo)量、數(shù)組、指針。

    在這里,我們來認(rèn)識(shí)一下結(jié)構(gòu)體指針。

    struct Book *pt;

    這里聲明了一個(gè)指向Book結(jié)構(gòu)體類型的指針變量pt

    struct S
    {
    	int a;
    	char c;
    	double d;
    };
    struct T
    {
    	struct S s;
    	char name[20];
    	int num;
    };
    int main()
    {
    	struct T t = { {100,'c',3.14},"里斯",30 };
    	printf("%d %c %f %s %d\n", t.s.a, t.s.c, t.s.d, t.name, t.num);
    	struct T*pt = &t;//拿到地址的方式
    	printf("%d %c %f %s %d\n", (*pt).s.a, (*pt).s.c, (*pt).s.d, (*pt).name, (*pt).num);
    	printf("%d %c %f %s %d\n",pt->s.a,pt->s.c,pt->s.d,pt->name,pt->num);
    	return 0;
    }

    【注意】數(shù)組名指向的是第一個(gè)元素的地址,所以可以直接將數(shù)組名賦值給指針變量。但是結(jié)構(gòu)體變量的變量名并不是指向該結(jié)構(gòu)體的地址,所以要使用取地址運(yùn)算符(&)才能獲取其地址。

    如上面的:

    struct T*pt = &t;//拿到地址的方式

    通過上面的例子我們也可以發(fā)現(xiàn),通過結(jié)構(gòu)體指針訪問結(jié)構(gòu)體成員有以下兩種方法:

    (1)(*結(jié)構(gòu)體指針).成員名
    (2)結(jié)構(gòu)體指針->成員名

    第一種由于點(diǎn)號(hào)運(yùn)算符(.)比指針的取值運(yùn)算符(*)優(yōu)先級(jí)高,所以要使用小口號(hào)先對(duì)指針進(jìn)行解引用,讓它變成該結(jié)構(gòu)體變量,再用點(diǎn)運(yùn)算符取訪問其成員。

    以上兩種方法在實(shí)現(xiàn)的時(shí)候完全等價(jià)。但是,切記,點(diǎn)號(hào)(.)只能用于結(jié)構(gòu)體,而箭頭(->)只能用于結(jié)構(gòu)體指針。

    【打印結(jié)果一樣】

    怎么用C語言玩轉(zhuǎn)結(jié)構(gòu)體

    當(dāng)二者皆可用的時(shí)候,優(yōu)先采用第二種方法,因?yàn)榧^具有指向性,很直觀的就可以把它與指針聯(lián)系起來了。

    六、結(jié)構(gòu)體傳參

    函數(shù)調(diào)用的時(shí)候,參數(shù)的傳遞就是值傳遞的過程,也就是將實(shí)參傳給形參的過程。所以,結(jié)構(gòu)體變量可以作為函數(shù)的參數(shù)傳遞,兩個(gè)相同結(jié)構(gòu)體類型的結(jié)構(gòu)體變量也支持直接賦值。

    struct S
    {
    	int arr[100];
    	int num;
    	char ch;
    	double d;
    };
    //結(jié)構(gòu)體傳參
    void print1(struct S ss)
    {
    	printf("%d %d %d %c %1f", ss.arr[0],ss.arr[2],ss.num,ss.ch,ss.d);
    }
    //結(jié)構(gòu)體地址傳參
    void print2(struct S*ps)
    {
    	printf("%d %d %d %c %1f", ps->arr[0], ps->arr[2], ps->num, ps->ch, ps->d);
    }
    int main()
    {
    	struct S s = { {1,2,3,4,5}, 100, 'w',3.14  };
    	print1(s);//傳結(jié)構(gòu)體
    	print2(&s);//傳地址
    	return 0;
    }

    怎么用C語言玩轉(zhuǎn)結(jié)構(gòu)體

    可以看到,確實(shí)把參數(shù)傳遞過去了。

    那么,上面的 print1 和 print2 函數(shù)哪個(gè)好些?

    答案是:首選print2函數(shù)。 原因:

    函數(shù)傳參的時(shí)候,參數(shù)是需要壓棧的。 如果傳遞一個(gè)結(jié)構(gòu)體對(duì)象的時(shí)候,結(jié)構(gòu)體過大,參數(shù)壓棧的的系統(tǒng)開銷比較大,所以會(huì)導(dǎo)致性能的下降。

    因此,結(jié)構(gòu)體傳參的時(shí)候,要傳結(jié)構(gòu)體的地址。

    以上是“怎么用C語言玩轉(zhuǎn)結(jié)構(gòu)體”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI