C语言变长数组实现(利用 struct中char data[0] )

1、结构体内存布局(padding)

为了让CPU能够更舒服地访问到变量,struct中的各成员变量的存储地址有一套对齐的机制。这个机制概括起来有两点:第一,每个成员变量的首地址,必须是它的类型的对齐值的整数倍,如果不满足,它与前一个成员变量之间要填充(padding)一些无意义的字节来满足;第二,整个struct的大小,必须是该struct中所有成员的类型中对齐值最大者的整数倍,如果不满足,在最后一个成员后面填充。

The following typical alignments are valid for compilers from MicrosoftBorland, and GNU when compiling for 32-bit x86:

  • char (one byte) will be 1-byte aligned.
  • short (two bytes) will be 2-byte aligned.
  • An int (four bytes) will be 4-byte aligned.
  • float (four bytes) will be 4-byte aligned.
  • double (eight bytes) will be 8-byte aligned on Windows and 4-byte aligned on Linux.
  • long double (twelve bytes) will be 4-byte aligned on Linux.
  • Any pointer (four bytes) will be 4-byte aligned on Linux. (eg: char*, int*)

The only notable difference in alignment for a 64-bit linux system when compared to a 32 bit is:

  • double (eight bytes) will be 8-byte aligned.
  • long double (Sixteen bytes) will be 16-byte aligned.
  • Any pointer (eight bytes) will be 8-byte aligned.
例子:
比如这个结构体,占用的并不是5个字节,而是8个字节。因为number成员的偏移量是4,其前面偏移了3个字节的偏移量
struct arr_data
{
	char h;
	int number;
};


2.变长数组

摘要:在实际的编程中,我们经常需要使用变长数组,但是C语言并不支持变长的数组。此时,我们可以使用结构体的方法实现C语言变长数组。

struct MyData   
{  
   int nLen;  
   char data[0];  
};   

在结构中, data是一个数组名;但该数组没有元素 该数组的真实地址紧随结构体MyData之后,而这个地址就是结构体后面数据的地址(如果给这个结构体分配的内容大于这个结构体实际大小,后面多余的部分就是这个data的内容) ;这种声明方法可以巧妙的实现C语言里的数组扩展。

实际用时采取这样:
struct MyData *p = (struct MyData *)malloc(sizeof(struct MyData )+strlen(str))
这样就可以通过p->data 来操作这个str。

这样就可以通过p->data 来操作这个str。

struct MyData   
{  
int nLen;  
char data[0];  
};  
  
int main()  
{  
 int nLen = 10;  
char str[10] = "123456789";  
  
cout << "Size of MyData: " <<sizeof(MyData) << endl;  
  
MyData *myData = (MyData*)malloc(sizeof(MyData) +10);  
memcpy(myData->data, str, 10);  
  
cout << "myData's Data is: " << myData->data << endl;  
  
free(myData);  
  
return 0;  
}  

//output:

Size of MyData:4

myData"s Data is: 123456789



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
C语言,定义结构体数组可以通过以下方式进行: 1. 先声明结构体类型,然后定义数组: ```c struct 结构体标识符{ 数据类型1 成员名1; ... 数据类型n 成员n; }; struct 结构体标识符 数组名\[数组长度\]; ``` 2. 定义结构体变量的同时定义结构体数组: ```c struct 结构体标识符{ 数据类型1 成员名1; ... 数据类型n 成员n; } 结构体标识符 数组名\[数组长度\]; ``` 3. 直接定义结构体数组: ```c struct 结构体标识符{ 数据类型1 成员名1; ... 数据类型n 成员n; } 数组名\[数组长度\]; ``` 4. 结构体数组的初始化可以通过以下两种方法进行: 方法1: ```c struct 结构体标识符{ 数据类型1 成员名1; ... 数据类型n 成员n; }; struct 结构体标识符 数组名\[数组长度\] = {初始列表}; ``` 方法2: ```c struct 结构体标识符{ 数据类型1 成员名1; ... 数据类型n 成员n; } 数组名\[数组长度\] = {初始列表}; ``` 在以上的定义和初始化方法,结构体标识符代表结构体的名称,成员名1到成员n代表结构体的成员名称和数据类型。数组长度表示结构体数组的长度,初始列表表示每个结构体元素的初始值。 例如,下面的代码定义了一个名为array的结构体数组,其包含了五个学生的姓名和成绩: ```c struct{ char *name; //姓名 float score; //成绩 } array\[\] = { {"张三", 145.0}, {"李四", 130.5}, {"王五", 148.5}, {"赵六", 139.0}, {"小林", 150.0} }; ``` 通过循环遍历结构体数组,可以计算出这五个学生的平均成绩。例如: ```c float sum = 0; for(int i = 0; i < 5; i++){ sum += array\[i\].score; } printf("平均成绩:%.2f\n", sum/5); ``` 这样就可以得到平均成绩。 #### 引用[.reference_title] - *1* [C语言 | 结构体数组](https://blog.csdn.net/weixin_48669767/article/details/116291224)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [C语言 结构体数组](https://blog.csdn.net/weixin_45020839/article/details/120224285)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [C语言结构体数组](https://blog.csdn.net/liubing8609/article/details/82624182)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值