結(jié)構(gòu)體使用與指針的理解
關(guān)注、星標(biāo)公眾號,直達(dá)精彩內(nèi)容
來源|整理:技術(shù)讓夢想更偉大
以前總有一種疑惑。為什么結(jié)構(gòu)體的指針有的需要用分配空間?有的不需要分配空間呢?現(xiàn)在總結(jié)一下思路:
一:關(guān)于結(jié)構(gòu)體的定義問題:使用結(jié)構(gòu)體一般會使用變量或者定義指針
typedef struct{
int a;
int b;
}data;
使用這個結(jié)構(gòu)體的兩種方式:
data datas直接引用。這樣使用類似于int a這種模式。data類似于一個類型(如:int)這樣的話,在使用的時候,系統(tǒng)自動會為這個類型分配空間。在棧上進(jìn)行分配,在使用完成后會自動釋放。data *dates指針調(diào)用。定義一個data類型的指針。使用這種指針需要做的是分配空間和釋放空間以及初始化。人為的進(jìn)行分配和釋放,這部分空間一般會位于堆的位置。你也可以讓指針直接指向已經(jīng)存在的空間。
二:關(guān)于結(jié)構(gòu)體指針的傳遞和調(diào)用的用法:
typedef struct{
int a;
int b;
}date;
static int intcms(void *para){
int c = ((date *)para)->a;
printf("c is %d\n",c);
}
int main(int argc, char **argv)
{
date dates;
dates.a = 9;
dates.b = 2;
intcms(&dates);
}
上述調(diào)用中采用的結(jié)構(gòu)體變量。在傳入函數(shù)時通過指針void *para指針傳遞過去。需要注意的是不能直接使用para->a來訪問結(jié)構(gòu)體的成員。為什么呢。這是因?yàn)閜ara只是接收過來的地址。para雖然指向的結(jié)構(gòu)體的首地址。但是這個指針并不知道自己指向的是什么內(nèi)容和有多少成員。需要(date *)para強(qiáng)制轉(zhuǎn)化一下。這樣para就可以知道自己是什么類型的指針。有多少成員。
typedef struct{
int a;
int b;
}date;
static int intcms(void *para){
int c = ((date *)para)->a;
printf("c is %d\n",c);
}
int main(int argc, char **argv)
{
date *dates = (date *)malloc(sizeof(date));
dates->a = 9;
dates-> = 2;
intcms(dates);
free(dates);
}
上述代碼使用結(jié)構(gòu)體指針需要分配空間和釋放空間。這是堆的使用。如果你不釋放。在整個進(jìn)程結(jié)束的時候。系統(tǒng)有會自動回收。簡單的程序沒什么問題。但是在需要分配大量的空間就可能導(dǎo)致出資源浪費(fèi)或者內(nèi)存耗盡的情況
三:結(jié)構(gòu)體定義的幾種方法
#include <stdio.h>
#include <string.h>
#include <malloc.h>
/*先定義幾類結(jié)構(gòu)體*/
struct str{
int a;
int b;
}str1;
/*這是第一類結(jié)構(gòu)體的形式,有結(jié)構(gòu)體名,有結(jié)構(gòu)體變量*/
struct str2{
int a;
int b;
};
/* 這是第二類結(jié)構(gòu)體的形式,有結(jié)構(gòu)體名,無結(jié)構(gòu)體變量 */
typedef struct {
int a;
int b;
}STR3;
/* 這是第三類結(jié)構(gòu)體的形式,把結(jié)構(gòu)體重定義為STR3 */
typedef struct str4{
int a;
int b;
}STR4;
/*這是第四類結(jié)構(gòu)體的形式,把結(jié)構(gòu)體重定義為STR4,還有結(jié)構(gòu)體名稱*/
void main()
{
/*定義各類的指針*/
struct str *p;
struct str2 *p2;
STR3 *p3;
struct str4 *p4;
STR4 *p5;
/*-----------------------------------------------*/
p = &str1; /*結(jié)構(gòu)體指針指向結(jié)構(gòu)體變量的地址首地址*/
p->a=1;
p->b=2;
printf("p->a=%d,p->b=%d\n",p->a,p->b);
/*-----------------------------------------------*/
p2 = (struct str2 *)malloc(sizeof(struct str2)); /*為結(jié)構(gòu)體指針分配對應(yīng)結(jié)構(gòu)體類型的大小的首地址*/
p2->a=1;
p2->b=2;
printf("p2->a=%d,p2->b=%d\n",p2->a,p2->b);
/*-----------------------------------------------*/
p3 = (STR3 *)malloc(sizeof(STR3)); /*為結(jié)構(gòu)體指針分配對應(yīng)結(jié)構(gòu)體類型的大小的首地址*/
p3->a=1;
p3->b=2;
printf("p3->a=%d,p3->b=%d\n",p3->a,p3->b);
/*-----------------------------------------------*/
p4 = (struct str4 *)malloc(sizeof(struct str4));/*為結(jié)構(gòu)體指針分配對應(yīng)結(jié)構(gòu)體類型的大小的首地址*/
p4->a=1;
p4->b=2;
printf("p4->a=%d,p4->b=%d\n",p4->a,p4->b);
struct str4 str4a;
p4 = &str4a;/*結(jié)構(gòu)體指針指向結(jié)構(gòu)體變量的地址的首地址*/
p4->a=1;
p4->b=2;
printf("p4->a=%d,p4->b=%d\n",p4->a,p4->b);
/*--------------------------------------------------*/
/*-----------------------------------------------*/
p5 = (STR4 *)malloc(sizeof(STR4));/*為結(jié)構(gòu)體指針分配對應(yīng)結(jié)構(gòu)體類型的大小的首地址*/
p5->a=1;
p5->b=2;
printf("p5->a=%d,p5->b=%d\n",p5->a,p5->b);
p5 = &str4a;/*結(jié)構(gòu)體指針指向結(jié)構(gòu)體變量的地址的首地址*/
p5->a=1;
p5->b=2;
printf("p5->a=%d,p5->b=%d\n",p5->a,p5->b);
/*--------------------------------------------------*/
}
運(yùn)行結(jié)果如下:

本文參考:
https://blog.csdn.net/weixin_36209467/article/details/82261286
嵌入式編程專輯 Linux 學(xué)習(xí)專輯 C/C++編程專輯 Qt進(jìn)階學(xué)習(xí)專輯
關(guān)注公眾號『技術(shù)讓夢想更偉大』,后臺回復(fù)關(guān)鍵字:『Qt』『C語言基礎(chǔ)』『C語言難點(diǎn)』『C++』『Linux』『freertos』『指針』『數(shù)據(jù)結(jié)構(gòu)與算法』『經(jīng)驗(yàn)技巧篇』『疑問篇』『基礎(chǔ)理論篇』『實(shí)戰(zhàn)篇』『架構(gòu)篇』『模塊化編程』『狀態(tài)機(jī)』『實(shí)用工具』『心聲社區(qū)』『期刊』『視頻』······等,查看更多精選內(nèi)容。
關(guān)注我的微信公眾號,回復(fù)“加群”按規(guī)則加入技術(shù)交流群。
這是我另一個技術(shù)號,程序員的編程學(xué)習(xí)基地,注重編程思想,歡迎關(guān)注!
點(diǎn)擊“閱讀原文”查看更多分享。
