C语言——结构体知识点总结
目錄
1.結構體的定義與使用
2.結構體數組
3.結構體指針
4.結構體然后計算大小
5.typedef關鍵字
6.結構體常見問題
1.結構體的定義與使用
結構體跟我們之前接觸的數組的概念很相似,數組是類型相同的一組變量的集合,而結構體類型不同的一組變量的集合。這樣就會使數據更多,類型更豐富,數據量更大。
結構體在定義的時候我們不關心這個結構體里面變量的值,它就類似于模板一樣,至于變量的大小或內容我們再編程的時候會給它們補充完整,哪怕定義的變量沒有用到也是可以的。
如何定義結構體
在給結構體中的賦值的時候,可以類比我們平時給普通變量賦值的情況。
struct student //struct關鍵字+結構體名字 {int score;char name[128]; }; //記得有分號int main() { //類型 變量名 初始值int a = 10;struct student stu = {98,"jhsad"}; //struct student可以看作是我們自定義的一種類型return 0; }如何訪問結構體
上面我們已經定義好了一個結構體,現在我們把結構體里面的值拿出來訪問。同樣類比普通變量的訪問方式。
#include <stdio.h> #include <string.h> struct student {int score;char name[128]; };int main() { int a = 10;//第一種訪問方式struct student stu = {98,"jhsad"};printf("a=%d\n",a); //普通變量的訪問方式printf("score=%d\n",stu.score);//訪問結構體用.運算符printf("name=%s\n",stu.name);//第二種訪問方式struct student text;text.score = 20;strcpy(text.name,"李四");printf("score=%d\n",text.score);printf("name=%s\n",text.name);return 0; }2.結構體數組
結構體數組的定義方式跟上面都一樣的,還是通過類比普通數組的定義方式。
#include <stdio.h>struct student {int sorce;char *name; };int main() { // 類型 變量 大小 int a [3];struct student stu[3];return 0; }練習:通過結構體數組操作學生成績
#include <stdio.h> #include <string.h> #include <stdlib.h>struct student {int sorce;char *name; };int main() { int i;struct student stu[3];for(i=0;i<sizeof(stu)/sizeof(stu[0]);i++){printf("請輸入第%d個學生的名字\n",i+1);stu[i].name = (char *)malloc(128);memset(stu[i].name,'\0',128);scanf("%s",stu[i].name);printf("請輸入第%d個學生的成績\n",i+1);scanf("%d",&stu[i].sorce);}for(i=0;i<sizeof(stu)/sizeof(stu[0]);i++){printf("第%d個學生的名字和成績\n",i+1);printf("%s:%d\n",stu[i].name,stu[i].sorce); }return 0; }3.結構體指針
定義結構體指針的時候要注意兩點:
1.如果用結構體指針,就不能用點運算符,訪問結構體中的變量要用->
2.指針要注意是否是野指針或者NULL。
#include <stdio.h> #include <string.h> #include <stdlib.h>struct student {int sorce;char *name; }; int main() { struct student *p; //定義結構體指針p = (struct student *)malloc(sizeof(struct student)); p->name = (char *)malloc(sizeof(128)); //用->訪問結構體中的內容p->sorce = 100;strcpy(p->name,"張三");printf("%s的成績是%d\n",p->name,p->sorce);free(p); //釋放空間,防止內存泄漏return 0; }4.結構體然后計算大小
結構體計算大小由于要遵循計算機的訪問規則,所以我們引入了內存對齊和偏移量的概念。
內存對齊簡單的可以理解為跟蓋章差不多,比如一張紙有12個字節,一個印章有四個字節,那么剛好印章蓋三次可以蓋完,假設這個印章有5個字節,那么怎么改都不可能剛好蓋滿12個字節。所以紙的大小一定要和章的大小成整數倍的關系,這樣才可以做到對齊。
對齊的方式很浪費空間,但根據計算機的訪問規則,大大提高了運行效率。
偏移量可以這樣理解,現在我連續定義幾個變量,第一個變量成員的大小就是下一個變量成員的偏移量大小。比如第一個成員是一個int型的變量,那么第二個變量成員的偏移量就是四個字節。
因此計算結構體大小的規則:
1.每一個成員的偏移量都必須是該成員的倍數。
2.結構體的大小必須是該結構體字節數最大成員的倍數(數組除外,結構體除外)。
再看下面這段代碼,我們將解釋第二條規則。
下面這段代碼如果只遵循第一條規則的話所計算出的大小是9個字節,但是我們還有一個規則結構體的大小必須是該結構體字節數最大成員的倍數。9不是int型大小的整數倍,int型是4個字節,不是9的整數倍。因此我們還需再偏移3個字節,所以改結構體的大小為12個字節。
struct s2 {char ch1; int ch3;char ch2; };結構體中包含數組
struct s3 {char ch1; //1個字節int ch3; //4+3個字節(多偏移3個字節)char ch2[12]; //12個字節 }; //共20個字節struct s4 {char ch1; //1個字節int ch3; //4+3個字節(多偏移3個字節)char ch2[10]; //10個字節 }; //多偏移兩個字節,共20個字節結構體中包含結構體
下面的代碼不同之處就是一個是聲明了結構體且定義了結構體變量,一個是聲明了結構體且沒有定義了結構體變量,計算出的結果大不相同。
struct s2 {char ch1; //1個字節int ch2; //4+3個字節(多偏移3個字節)struct s{char ch3; int ch4; //結構體中8個字節}stmp; //聲明結構體且定義了結構體變量float f; //4個字節 }; //8+8+4,共20個字節struct s2 {char ch1; //1個字節int ch2; //4+3個字節(多偏移3個字節)struct s{char ch3; int ch4; //結構體中8個字節}; //聲明結構體且沒有定義了結構體變量,不占內存空間float f; //4個字節 }; //8+4,共12個字節指定對齊方式(向4對齊)
#pragma pack(4) //指定向4對齊 最大是8 struct s5 {char ch1; //1個字節int ch3; //4+3個字節float b; //4個字節double b; //8個字節 }; //共20個字節指定對齊方式(向10對齊)
如果結構體成員大小超過了pack的要求,就按pack來對齊。
如果最大成員大小沒有超過pack,就按最大的成員大小來對齊。
#pragma pack(10) //指定向10對齊 struct s6 {char ch1; //1個字節int ch3; //4+3個字節float b; //4個字節double b; //8個字節 }; //共24個字節5.typedef關鍵字
typedef作為c語言關鍵字,作用是為一種數據類型定義一種新名字。這里的數據類型包括內部數據類型(int,char等),也包含自定義的數據類型(struct等)。
和struct匹配為了代碼編寫簡潔。
和普通變量匹配,通過名字來獲取一些信息。
在單片機開發中,經常會看到typedef unsigned char u_int8這樣的寫法,這樣表示就相當于給unsigned char起了一個名字叫做u_int8,能表示的范圍是0~255。
和結構體結合通常這樣使用:
#include <stdio.h> #include <string.h> #include <stdlib.h>typedef struct s2 {char *ch1; int ch2; }STU; int main() { STU student;student.ch2 = 10;student.ch1 = (char *)malloc(128);strcpy(student.ch1,"uyuiy");printf("%d\n",student.ch2);printf("%s\n",student.ch1);return 0; }6.結構體常見問題
在定義結構體的時候最容易犯的錯誤就是定義了一個野指針,然后訪問的時候造成段錯誤。就比如下面這段代碼:
#include <stdio.h> #include <string.h> #include <stdlib.h>struct student {char *p; };int main() { /*struct student stu;strcpy(stu.p,"sagdh"); 這種寫法是錯誤的,p在這里是一個野指針,內存空間沒有申請printf("%s\n"); 所以應該使用malloc給它安排空間,一定要有空間!*/struct student stu;stu.p=(char *)malloc(128);memset(stu.p,'\0',128); //把里面每一項都初始化成0strcpy(stu.p,"sagdh");printf("%s\n",stu.p);return 0; }總結
以上是生活随笔為你收集整理的C语言——结构体知识点总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Matplotlib数据可视化之堆叠图、
- 下一篇: 同位语