<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
初學C語言
我們先接觸的都是內建的型別
比如說int char short float double long等等
這一期就來聊一聊自定義型別的知識
首先我們要知道什麼是結構體
結構體就是各種值集合
這些值被稱作結構體成員,這些成員可包括各種不同的型別
struct tag //這裡的struct是結構體的關鍵字,tag是結構體標籤,也就是結構體的名稱 { number - list; //結構體成員列表 }veriable-list; //結構體的變數
如果結構體的標籤是student,我拿student來舉例子
結構體的完整宣告
struct Student { char name[20];//姓名 char sex;//性別 int age;//年齡 int num;//學號 }; //這裡的分號不能丟
結構體的不完全宣告(匿名結構體型別)
struct { int a; char b; double c; }s; //這s不能省略
匿名結構體的特點就是沒有結構體標籤
但這樣寫使用者使用時只能使用一次,也就是說只能在結構體宣告時就定義變數
因為你找不到結構體標籤,就相當於找不到門牌號一樣,無法再對其定義一個變數
結構體的定義大致分為三種情況
<1>結構體宣告的同時定義
struct Student { char name[20];//姓名 char sex[20];//性別 int age;//年齡 }s={"zhangsan","nan",20};
<2>結構體先宣告,再定義
#include<stdio.h> struct Student { char name[20];//姓名 char sex;//性別 int age;//年齡 int num;//學號 }; int main() { struct Student s = { "zhangsan",'w',20,111 }; return 0; }
<3>匿名結構體定義
struct { char name[20];//姓名 char sex[20];//性別 int age;//年齡 } s = { "zhangsan","nan",20};
注意:結構體初始化與陣列相同,都必須整體進行賦值。
struct Node //初始話連結串列 { int a; struct Node next; };
結構體的自參照就是結構體再套用自己
學過資料結構的朋友應該知道這是初始化連結串列
不過這一個程式碼有問題的
問題在於無法求出這個結構體的大小,不清楚這個結構體有多大,因為無法求出自參照的結構體有多大
所有自參照的結構體要用指標來存取
struct Node //初始話連結串列 { int a; struct Node* next; };
故就可以通過指標來存取每一個結點
當結構體定義且變數初始化完成後,就可以通過操作符來存取變數中的成員
當然,這裡給出了兩個操作符
分別是 .操作符和 -> 操作符
當使用結構體變數時,就用點操作符,當存取結構體指標變數就用箭頭操作符
(1)通過結構體變數進行存取:
printf("%sn",s.name);
(2)通過結構體指標進行存取:
printf("%sn",ps->name);
函數的呼叫有時候需要傳一些引數
引數的型別可以是不同的型別,可以是陣列,也可以是指標
同樣結構體的傳參也可通過傳結構體或者傳指標
#include<stdio.h> struct tag { int a; char b[20]; }s1 = { 100,"abcdef" }; void print() { printf("%d", s1.a); } int main() { print(s1); return 0; }
#include<stdio.h> struct tag { int a; char b[20]; }s2 = { 100,"abcdef" }; void print(struct tag*s2) { printf("%d", s2->a); } int main() { print(&s2); return 0; }
我們要知道函數傳參是形參就是實參的臨時拷貝
引數是要壓棧的(向系統申請空間),既然是臨時拷貝,就會再次再棧上開闢空間,當實參足夠大時,顯然會浪費一定的空間和時間
相比較與傳結構體,傳指標會更好
在另外一篇文章詳細講過——C語言結構體中記憶體對齊的問題理解
可能有人沒有聽過什麼是位元欄
位元欄的結構型別跟結構體有些類似可以類似結構體去學習
也可以說
位元欄是結構體特殊的實現
相較於結構體,位元欄的宣告有兩點不同
<1>規定位元欄的成員的必須是int,unsigned int ,signed int (但是寫成char型別也沒什麼大的問題)
<2>位元欄的成員後面有一個冒號和一個數位
struct A //位元欄的宣告 { int _a : 2; int _b : 5; int _c : 10; int _d : 30; };
#include<stdio.h> struct A { int a : 2; int b : 5; int c : 10; int d : 30; }; int main() { printf("大小是%d位元組", sizeof(struct A)); return 0; }
為什麼位元欄的大小是八個位元組呢?
成員內包含的數位代表的是這個成員需要利用的記憶體,單位是bit。
位元欄成員申請記憶體時都是以四個位元組或者一個位元組單位(當成員是char型別時)
int a : 2; //申請4個位元組,也就是32個bit位,利用兩個還剩30個
int b : 5; //利用5個,還剩25個
int c : 10; //利用10個,還剩15個
int d : 30; //這裡的十五不夠,所以再申請了4個位元組
最終的結果就是八位元組
但問題是,變數d利用的空間是留下的15個bit加上重新申請的空間呢
這個結果在不同的環境的結果是不同的,所以位元欄的跨平臺性比較差
位元欄使用的前提是你知道儲存的記憶體大概有多大
就比如說年齡
十個bit位0111111111,最大值就可以達到1023
就不需要再申請一次利用一個int型別的空間大小
這就達到了節省記憶體的作用,存在即合理
位元欄的應用
struct A { char a : 3; char b : 4; char c : 5; }; main() { struct A s = { 0 }; s.a = 10; s.b = 12; s.c = 3; return 0; }
1.int位元欄被當成有符號數還是無符號數是不確定的,有時候系統會自動轉化為無符號整形。
2.位元欄中最大位的數目不能確定。(因為在早期的16位元機器int最大16,而32位元機器int最大32)
3.位元欄中的成員在記憶體中從左向右分配,還是從右向左分配標準尚未定義。
意思當記憶體一個位元組00000000,存入01010,可能會出現00001010或者01010000
4.當一個結構包含兩個位元欄,第二個位元欄成員比較大,無法容納於第一個位元欄剩餘的位時,是 捨棄剩餘的位還是利用,這是不確定的。
列舉型別適用於可以一一列舉的型別
比如說星期、性別
enum Day //星期 { //列舉的可能取值 Mon, Tues, Wed, Thir, Fri, Sta, Sun };
enum Sex //性別 { MALE,//0 FEMALE,//1 SECRET//2 };
列舉型別是有初始值的
如果你沒賦予它初始值,就會預設從零開始,依次加一
#include<stdio.h> enum Sex //性別 { MALE = 4, FEMALE=10, SECRET// }; main() { printf("%d %d %d", MALE,FEMALE,SECRET); return 0; }
可以看到,其實預設的值是可以改的
當某個成員被賦予某個值的時候,後續的成員就在此基礎上加一
1.相較於數位,列舉增加程式碼的可讀性和可維護性
2.和#define定義的識別符號比較列舉有型別檢查,更加嚴謹。
3.防止了命名汙染(封裝)
4.便於偵錯
5.使用方便,一次可以定義多個常數
聯合體型別也叫共用體
union Un { int a; char b; };
union是聯合體關鍵字,Un是聯合體的標籤
共用體,顧名思義,這裡的共用就是公用記憶體
記憶體的也可被摺疊
#include<stdio.h> union Un { char c; int i; }; int main() { union Un u = {0}; printf("%dn", sizeof(u)); printf("%pn", &u); printf("%pn", &(u.c)); printf("%pn", &(u.i)); return 0; }
他們有相同的地址
c和i存放在同一塊記憶體空間上,修改c或者i都會影響到另一個成員。
<1>聯合體記憶體大小是最大成員的大小
<2>最大成員的大小如果不是最大對齊數的整數倍,就會對齊到最大對齊數的整數倍
(聯合體也存在記憶體對齊)
#include<stdio.h> union Un1 { char c[5]; int i; }; //Un1成員最大成員大小5,最大對齊數是4,所以Un1的大小是8; union Un2 { char c[7]; int i; }; //Un2成員最大成員大小7,最大對齊數是4,所以Un2的大小是8; int main() { printf("%dn", sizeof(union Un1)); printf("%dn", sizeof(union Un2)); return 0; }
到此這篇關於C語言自定義型別全解析的文章就介紹到這了,更多相關C語言 自定義型別內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45