結構體知識進階
總所周知,結構體是C語言中重要的數據類型,可以存放多種不同類型的數據
結構體的一般用於存放類型不同但是又相互關聯的數據,例如:一個人的身份信息包括姓名、性別、年齡和身份證號,這些數據需要由不同的數據類型存放,但是又都表示一個人的信息,這時一般會使用到結構體對該數據進行存儲,但是結構體所能夠支持的不止如此
接下來,我將介紹幾種開發中常用的結構體的高級操作
位域
我們都知道,C語言中不包含bool類型,需要表示true或false時一般使用1和0表示
如果我們的結構體中有大量的bool類型的數據需要存放,我們就需要聲明大量的int類型來存放這些數據,這樣操作就會造成資源浪費,而位域可以很好的解決這個問題
概念
位域,C語言允許在一個結構體中以位爲單位來指定其成員所佔內存長度,這種以位爲單位的成員稱爲“位段”或稱“位域”( bit field)
使用實例如下:
#include <stdio.h>
typedef struct
{
int true;
int false;
}res;
typedef struct
{
unsigned int true : 1;
unsigned int false : 1;
}bool;
int main()
{
res RES;
RES.true = 1;
RES.false = 0;
bool result;
result.true = 1;
result.false = 0;
printf("The size of RES is: %d\n",sizeof(res));
printf("The RES.true is: %d\n",RES.true);
printf("The RES.false is: %d\n",RES.false);
printf("The size result is: %d\n",sizeof(bool));
printf("The result.true is: %d\n",result.true);
printf("The result.false is: %d\n",result.false);
return 0;
}
程序運行結果如下:
The size of RES is: 8
The RES.true is: 1
The RES.false is: 0
The size result is: 4
The result.true is: 1
The result.false is: 0
這裏涉及到一些計算機底層存儲機制,例如數據的符號位等存儲細節,導致bool類型的長度並不是2,這裏就不再深究,畢竟筆者能力有限
存放函數指針
結構體中可以聲明函數指針,將函數的返回值直接保存在結構體中
結構體中聲明函數指針的類型,但是函數的具體實現需要自行編寫,更重要的是,結構體中的類型並不是固定的,而是可以動態改變的
使用實例如下:
#include <stdio.h>
typedef struct
{
int(*func)(int a,int b);
}test;
int add(int x,int y)
{
return x+y;
}
int mul(int x,int y)
{
return x*y;
}
int main()
{
test T;
T.func = add;
printf("The res is: %d\n",T.func(1,1));
T.func = mul;
printf("The res is: %d\n",T.func(2,3));
return 0;
}
程序運行結果如下:
The res is: 2
The res is: 6
動態結構體的使用
結構體在編程開發中,是經常被使用的數據類型。在實際的開發中,有些結構體在聲明的時候總是需要聲明多種變量,但實際使用時並不總是需要全部使用
但是結構體的聲明是靜態的,即使結構體爲空,它也仍要佔據大量的空間,造成資源浪費。如果是發送數據且發送數據頻率過高,就會佔用大量帶寬,影響系統的性能
問題示例
例如:一個客戶端和服務器需要使用TCP進行數據交互,客戶端向服務器發送點雲數據;正常情況下,客戶端只會發送一小部分的點雲數據(少量的點的位置發生變化),只有在極少的情況下,才需要發送全部的數據(所有點的位置信息都更新)
但是在項目開發中,存放點雲數據的結構體的大小是能夠存放所有點數據的,這樣就會造成每次發送給服務器的數據包的大小都是最大尺寸的,造成網絡帶寬佔用極大
參考鏈接:https://blog.csdn.net/zhanshen112/article/details/80791622
動態結構體實例:
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#define LEN sizeof(Data)
typedef struct
{
int val;
}test;
typedef struct
{
int num;
test t[];
} Data;
int main()
{
int len, i;
Data *pData;
printf("請輸入test結構體的個數:\n");
scanf("%d", &len);
pData = (Data*)malloc(LEN+sizeof(test)*(len-1));
printf("請輸入Data結構體的值:");
scanf("%d",&(pData->num));
for (i = 0; i<len; i++)
{
printf("請輸入pData->t[%d].val 的值\n",i);
scanf("%d", &pData->t[i].val);
}
printf("The Data.num is %d\n",pData->num);
for (i = 0; i<len; i++)
{
printf("The pData[%d].val is %d\n",i,pData->t[i].val);
}
return 0;
}