由于近期項目需求,需使用到大量的指針與結構體,為更好的完成項目,故對結構體與指針的內容進行回顧,同時撰寫本博客,方便后續查閱。
本博客涉及的結構體知識有:
1.0:結構體的創建和使用
2.0:? typedef 關鍵字與#define 關鍵字的區別
3.0:? 結構體成員的訪問【地址訪問與成員訪問】
4.0: 結構體嵌套調用
......
1.0:結構體的創建和使用
結構體類型和枚舉類型一樣,是一種用戶自定義的數據類型,它可以使用一個變量來描述事物的多種屬性,便于數據的管理,數據類型聲明的語法格式:
// 結構體的聲明格式
typedef struct
{成員列表
}structName_t;注:成員列表中的成員并不是變量在什么的時候并不會開辟內存空間內存空間的開辟要在創建結構體變量之后************************************ 結構體: 創建結構體案例* 參數 : 結構體成員 char name[20]; char tel[12];* 返回值: 無* 時間 : 2024/7/13 * 作者 : _滄浪之水_************************************
**/
typedef struct
{char name[20];char tel[12];char sex[5];int high;
}People_t;
結構體變量的定義
/************************************** 結構體: 結構體變量定義后同時進行賦值* 參數 : 無參數* 返回值: 無返回值* 時間 : 2024/7/13 * 作者 : _滄浪之水_************************************
**/
People_t peo = { "張三","15863310892","男",181 };
2.0 typedef 關鍵字的使用
typedef關鍵關鍵字:用于定義一個已有關鍵字的別名,具體創建格式如下所示
/************************************** 結構體: typedef 關鍵字的用法* 參數 : 無參數* 返回值: 無返回值* 時間 : 2024/7/13 * 作者 : _滄浪之水_************************************
**/
typedef 數據類 名字typedef uint8_t uint;typedef unsigned char uchar;
typedef 關鍵字和define關鍵字的區別,兩者都是給對象取一個別名增強程序的可讀性【盡量防止程序中魔鬼數字的出現】,兩者有如下的區別
1: 使用場景不同
typedef 關鍵字用于給數據類型定義別名
#define關鍵字又稱為(宏定義) 用于給數字,表達式(寫表達式時注意帶上括號防止異常問題的出現),代碼語句定義別名。
2:執行時機不同
typedef在編譯階段執行;
#define在預編譯階段執行;
3:定義方法不同
#define別名在替換對象的前面,并且定義后面不用加分號;
#define PI 3.14#define MAX_NUM_LIST 9
typedef的別名在替換對象的后面,并且定義后面需要加分號;
typedef unsigned char uchar;
3.0:? 結構體成員的訪問
注:有指針訪問和圓點運算符訪問兩種訪問方式
使用圓點運算符并打印輸出
/************************************** 結構體: 結構體成員變量訪問* 參數 : 結構體成員訪問* 返回值: 無* 時間 : 2024/7/13 * 作者 : _滄浪之水_**************************************/// peo 是結構體變量,結構體變量創建后才會開辟內存控制,結構體變量初始化People_t peo = { "張三","15863310892","男",181 };// 浮點數在內存中不能精確的存儲,結構體嵌套初始化recallStruct_t recal = { {"李四","15863310892","男",181},100, 88.8f };printf("%s %s %s %d\n", peo.name, peo.tel, peo.sex, peo.high);printf("%s %s %s %d %d %f\n", recal.p.name,recal.p.tel,recal.p.sex, recal.p.high,recal.num,recal.f);
使用指針訪問【地址訪問】
/************************************** 結構體: 結構體傳遞地址調用* 參數 : *p 指針地址* 返回值: 無* 時間 : 2024/7/13 * 作者 : _滄浪之水_************************************
**/
void Print(People_t *p)
{// 左邊的是結構體指針 “結構體指針->成員變量”printf("%s %s %s %d\n", p->name, p->tel, p->sex, p->high);
}
注:以上的這種寫法需要在主函數中進行調用
4.0: 結構體嵌套調用
#define _CRT_SECURE_NO_WARNINGS
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include <string.h>
#include "add.h"
#include <stdint.h>/************************************** 結構體: 創建結構體* 參數 : 結構體成員 char name[20]; char tel[12];* 返回值: 無* 時間 : 2024/7/13* 作者 : _滄浪之水_************************************
**/
typedef struct
{char name[20];char tel[12];char sex[5];int high;
}People_t;/************************************** 結構體: 創建結構體* 參數 : 結構體成員,內部包含結構體【順帶變量初始化,結構體初始化】* 返回值: 無* 時間 : 2024/7/13* 作者 : _滄浪之水_************************************
**/
typedef struct
{People_t p;int num;float f;
}recallStruct_t;/************************************** 結構體: 結構體傳遞地址調用* 參數 : *p 指針地址* 返回值: 無* 時間 : 2024/7/13* 作者 : _滄浪之水_************************************
**/
void Print(People_t *p)
{// 左邊的是結構體指針 “結構體指針->成員變量”printf("%s %s %s %d\n", p->name, p->tel, p->sex, p->high);
}/************************************** 結構體: 結構體成員變量訪問* 參數 : 結構體成員訪問* 返回值: 無* 時間 : 2024/7/13* 作者 : _滄浪之水_************************************
**/
void PrintTwo(People_t input)
{// 左邊的是結構體變量 “結構體變量.成員變量”printf("%s %s %s %d\n", input.name, input.tel, input.sex, input.high);
}int main()
{// peo 是結構體變量,結構體變量創建后才會開辟內存控制,結構體變量初始化People_t peo = { "張三","15863310892","男",181 };// 浮點數在內存中不能精確的存儲,結構體嵌套初始化recallStruct_t recal = { {"李四","15863310892","男",181},100, 88.8f };printf("%s %s %s %d\n", peo.name, peo.tel, peo.sex, peo.high);printf("%s %s %s %d %d %f\n", recal.p.name, recal.p.tel, recal.p.sex, recal.p.high, recal.num, recal.f);Print(&peo);PrintTwo(peo);return 0;
}
注:以上的注釋編寫方式僅限于更好的理解知識,實際的開發過程會更為規范,推薦書籍《高質量 C C++ 編程指南 》。
?注:上面的兩種打印輸出方式哪一種打印方式更好,結構體傳遞參數吧 “對象” 進行結構體傳參的時PrintTwo() 這種參數傳遞方式方式時PrintTwo(peo),peo實際是一個對象已經在內存中開辟了一塊內存空間,如果把對象作為實際參數傳遞給形參的時候“形參里面的內容實際上是實際參數的一份拷貝” 打印peo的時候打印輸出的數據是一樣的,空間和時間的浪費會降低程序的性能。【推薦使用地址傳遞的方式把參數的地址傳遞進去(地址的大小就是4-8字節)通過地址找到數據】參數傳遞的時候會壓棧,結構體傳遞參數的時候盡量傳遞結構體的地址節省時間和空間。
5.0 數組方式給結構體成員賦值
#define _CRT_SECURE_NO_WARNINGS
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include <string.h>
#include "add.h"
#include <stdint.h>#define MAX_LIST_NUM (sizeof(arrList) / sizeof(arrList[0]))/************************************** 結構體: 創建結構體* 參數 : 結構體成員 char name[20]; char tel[12];* 返回值: 無* 時間 : 2024/7/13* 作者 : _滄浪之水_************************************
**/
typedef struct
{char name[20];char tel[12];char sex[5];int high;
}People_t;static People_t arrList[] =
{{"Keil","122345625","男",180},{"Ling","122345625","女",185}
};int main()
{uint8_t i = 0;for (i = 0; i < MAX_LIST_NUM; i++) {printf("%s %s %s %d\n", arrList[i].name, arrList[i].tel, arrList[i].sex, arrList[i].high);}return 0;
}
?......