網站首頁 編程語言 正文
一、什么是結構體
為了更好地模擬現實,需要把各種基本數據類型組合在一起構成一種新的復合數據類型,我們把這種自定義的數據類型稱為結構體。結構體是程序員根據實際需求,把各種基本數據類型組合在一起構成的一種新的復合數據類型。
二、結構體的定義
結構體的定義方式共有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 %c\n", 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 %c\n", 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 %c\n", 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 %s\n", (*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 %s\n", (*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("姓名:%s\n", (p + i)->name); printf("年齡:%d\n", (*(p + i)).age); printf("成績:%f\n", p[i].score); printf("\n"); } }
十、關鍵字typedef
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++中的引用。
傳輸普通變量
C語言實現普通變量的傳輸:
#include <stdio.h> void modify(int* p) { (*p)++; } int main() { int i = 10; modify(&i); printf("%d\n", i); return 0; }
C++語言實現普通變量的傳輸:
#include <stdio.h> void modify(int& i) { i++; } int main() { int i = 10; modify(i); printf("%d\n", 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; }
原文鏈接:https://blog.csdn.net/weixin_65334260/article/details/125607089
相關推薦
- 2022-11-13 ASP.NET?MVC使用Session會話保持表單狀態_實用技巧
- 2022-06-21 Android基于Sqlite實現注冊和登錄功能_Android
- 2022-09-15 Python實現圖形用戶界面計算器_python
- 2022-12-09 Python曲線擬合多項式深入詳解_python
- 2022-11-14 Python?prettytable模塊應用詳解_python
- 2022-10-03 React如何實現全屏監聽Esc鍵_React
- 2022-06-15 go語言方法集為類型添加方法示例解析_Golang
- 2022-11-03 Apache安裝配置避坑指南_Linux
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支