<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
為了更好地模擬現實,需要把各種基本資料型別組合在一起構成一種新的複合資料型別,我們把這種自定義的資料型別稱為結構體。結構體是程式設計師根據實際需求,把各種基本資料型別組合在一起構成的一種新的複合資料型別。
結構體的定義方式共有3種,這裡只用最常見也最常用的一種方式定義,即:
struct 結構體名
{
成員列表;
}; // 注意這裡的分號不能省略
舉個例子:
struct Student { int age; float score; char gender; };
結構體與我們經常使用的基本資料型別一樣,它也是一種資料型別,所以我們可以用這一資料型別定義其對應的變數,我們把用結構體型別定義的變數稱為結構體變數。定義結構體變數的方式如下所示:
#include <stdio.h> struct Student // 定義結構體 { int age; float score; char gender; }; int main() { struct Student stu; // 定義結構體變數 return 0; }
#include <stdio.h> struct Student // 定義結構體 { int age; float score; char gender; }; int main() { struct Student stu = { 15, 66.5, 'M' }; // 初始化結構體變數 return 0; }
定義結構體變數後,我們可以對其中的成員進行賦值操作,但與初始化不同的是,需要通過結構體變數名.成員名
的方式對結構體變數中的每個成員單獨賦值。程式碼如下所示
#include <stdio.h> struct Student // 定義結構體 { int age; float score; char gender; }; int main() { struct Student stu; // 定義結構體變數 stu.age = 15; // 對結構體變數中的age成員賦值 stu.score = 66.5; // 對結構體變數中的score成員賦值 stu.gender = 'M'; // 對結構體變數中的gender成員賦值 return 0; }
方法1:結構體變數名.成員名
#include <stdio.h> struct Student // 定義結構體 { int age; float score; char gender; }; int main() { struct Student stu; // 定義結構體變數 // 對各成員賦值 stu.age = 15; stu.score = 66.5; stu.gender = 'M'; printf("%d %f %cn", stu.age, stu.score, stu.gender); // 輸出各成員的內容 return 0; }
方法2:結構體指標變數名->成員名
#include <stdio.h> struct Student // 定義結構體 { int age; float score; char gender; }; int main() { struct Student stu; // 定義結構體變數 struct Student * pStu = &stu; //定義結構體指標變數 // 對各成員賦值 pStu->age = 15; pStu->score = 66.5; pStu->gender = 'M'; printf("%d %f %cn", stu.age, stu.score, stu.gender); // 輸出各成員的內容 return 0; }
方法3:(*結構體指標變數名).成員名
#include <stdio.h> struct Student // 定義結構體 { int age; float score; char gender; }; int main() { struct Student stu; //定義結構體變數 struct Student * pStu = &stu; //定義結構體指標變數 // 對各成員賦值 (*pStu).age = 15; (*pStu).score = 66.5; (*pStu).gender = 'M'; printf("%d %f %cn", stu.age, stu.score, stu.gender); // 輸出各成員的內容 return 0; }
當我們在一個函數中定義了結構體變數,而想要在另外一個函數中對該結構體變數進行操作時,則需要向被呼叫的函數傳遞引數,那傳遞結構體變數作為引數還是應該傳遞結構體指標變數作為引數呢?這是一個必須要搞清楚的問題。我以下面的程式為例闡述不同情況下的傳參問題:
#include <stdio.h> #include <string.h> struct Student // 定義結構體 { int age; float score; char name[100]; }; // 函數宣告 void input_student(struct Student* pStu); void output_student(struct Student* pStu); int main() { struct Student stu; // 定義結構體變數 input_student(&stu); // 傳遞地址的原因詳見該程式下方 output_student(&stu); // 傳遞地址的原因詳見該程式下方 return 0; } // 賦值函數 void input_student(struct Student * pStu) { (*pStu).age = 10; pStu->score = 66.5; strcpy(pStu->name, "南森"); /* 注意這裡不能寫成 pStu->name = "南森"; 這是因為一維陣列名是指標常數,不能對常數進行賦值操作 */ } // 輸出函數 void output_student(struct Student* pStu) { printf("%d %f %sn", (*pStu).age, pStu->score, pStu->name); }
為什麼要傳遞地址?由於input_student
函數要修改主函數中結構體變數stu
各個成員的值,所以只能傳輸地址,不能傳輸變數stu
,我已經在《C語言之指標知識大總結》這篇文章中詳細敘述了其中的原因。而output_student
函數並不需要修改主函數中結構體變數stu
各個成員的值,所以此時是可以傳輸變數stu
的,但由於變數stu
的型別是結構體型別,其所佔位元組數較多,而所有的指標變數都只有四個位元組,所以為了減少記憶體耗用並提高資料傳輸的效率,往往傳輸對應的結構體指標變數。
向一個函數傳入某個變數的地址不僅可以修改該變數的值,而且可以提高資料傳輸效率,但這樣做也會有一定的風險。例如上一小結中的程式,其中的output_student
函數作為輸出函數並不需要在其內部修改變數的值,而一旦傳入變數的地址,那就意味著output_student
函數也可以對該地址所對應的變數進行修改,這樣就導致output_student
這個函數非常不安全,那怎麼樣才能實現既可以快速傳輸資料,又可以在不需要修改變數值的函數中禁止該函數修改資料呢?答案很簡單,只需要在形參的指標變數前加上關鍵字const
就可以達到這樣的目的。如下所示:
void output_student(const struct Student* pStu) { pStu->score = 88; // 錯誤,因為指標變數pStu前有const修飾,無法修改其對應的普通變數的值 (*pStu).age = 10; // 錯誤,因為指標變數pStu前有const修飾,無法修改其對應的普通變數的值 printf("%d %f %sn", (*pStu).age, pStu->score, pStu->name); }
#include <stdio.h> #include <malloc.h> // 定義結構體 struct Student { char name[100]; int age; float score; }; // 函數宣告 int create_array(struct Student**); void input_array(struct Student*, int); void bubble_sort(struct Student*, int); void print(struct Student*, int); int main() { int length; struct Student* pStu; length = create_array(&pStu); // 由於要對指標變數pStu的內容進行修改,所以只能傳輸其地址 input_array(pStu, length); bubble_sort(pStu, length); print(pStu, length); return 0; } // 該函數的作用是分配記憶體並構造陣列 int create_array(struct Student** q) // 由於需要接收一級指標變數,所以這裡需要使用二級指標 { int length; printf("請輸入學生人數:"); scanf("%d", &length); printf("n"); *q = (struct Student*)malloc(sizeof(struct Student) * length); // 動態分配記憶體構造結構體陣列 return length; } // 該函數的作用是對結構體陣列中的各元素進行賦值 void input_array(struct Student* p, int length) { int i; for (i = 0; i < length; i++) { printf("請輸入第%d個學生的資訊:n", i + 1); printf("姓名:"); scanf("%s", (p + i)->name); printf("年齡:"); scanf("%d", &(*(p + i)).age); printf("成績:"); scanf("%f", &p[i].score); printf("n"); } } // 該函數的作用是按照結構體陣列中的score成員從低到高進行氣泡排序 void bubble_sort(struct Student* p, int length) { int i, j; struct Student t; for (i = 1; i < length; i++) for (j = 0; j < length - i; j++) if (p[j].score > p[j + 1].score) { // 注意:比較的是score的大小,但是需要交換的是結構體陣列中元素的位置,而不是隻交換成員score t = p[j]; p[j] = p[j + 1]; p[j + 1] = t; } } // 該函數的作用是輸出結構體陣列中各元素的內容 void print(struct Student* p, int length) { int i; printf("按照分數由低到高排序的結果為:n"); for (i = 0; i < length; i++) { printf("姓名:%sn", (p + i)->name); printf("年齡:%dn", (*(p + i)).age); printf("成績:%fn", p[i].score); printf("n"); } }
typedef關鍵字的作用是對資料型別起別名。例如:
#include <stdio.h> typedef int INTEGER; // 給int取了個別名叫INTEGER,故INTEGER就等同於int int main() { INTEGER i = 10; // 等同於 int i = 10; return 0; }
#include <stdio.h> typedef struct Student { char name[100]; int age; float score; }ST, * PST; // 給 struct Student 起了個別名ST,給 struct Student * 起了個別名叫PST int main() { ST stu; // 等同於 struct Student stu; PST pStu; // 等同於 ST * pStu; 也等同於 struct Student * pStu; return 0; }
使用C++中的參照在向其它函數傳參時可以幫助我們提高編碼效率,嚴蔚敏老師在《資料結構》這本書中也多次使用了C++中的參照。
傳輸普通變數
C語言實現普通變數的傳輸:
#include <stdio.h> void modify(int* p) { (*p)++; } int main() { int i = 10; modify(&i); printf("%dn", i); return 0; }
C++語言實現普通變數的傳輸:
#include <stdio.h> void modify(int& i) { i++; } int main() { int i = 10; modify(i); printf("%dn", i); return 0; }
傳輸指標變數
C語言實現指標變數的傳輸:
#include <stdio.h> #include <malloc.h> void modify(int** q) { *q = (int *)malloc(sizeof(int)); } int main() { int * p; modify(&p); return 0; }
C++語言實現指標變數的傳輸:
#include <stdio.h> #include <malloc.h> void modify(int*& p) { p = (int *)malloc(sizeof(int)); } int main() { int * p; modify(p); 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