目录
一、试题:开发C代码时,经常见到如下类型的结构体定义:
二、请分析下面的程序,看一看如何使用柔性数组。
三、结构体中使用指针实现柔性数组功能
《横扫Offer:程序员招聘真题详解700题》著者:开点工作室编著 P51
typedef struct list_t {
struct list_t *next;
struct list_t *prev;
char data[0];
} list_t;
最后一行char data[0];的作用是( )。
A.方便管理内存缓冲区。 B.减少内存碎片化。 C.标识结构体结束。 D.没有作用。
答案:B。
在C语言中,将结构体类型中的最后一个成员定义为数组且大小定义为0的用法,可以巧妙的实现数组扩展。
柔性数组成员不仅可以是字符数组,还可以是其它类型的数组或指针。
#include
#include
#include
#define NUM 3
typedef struct list_t {
struct list_t* next;
struct list_t* prev;
char data[0]; //柔性数组
} list_t;
int main(void)
{
char buf[][20] = {"This is a string.","abc","123456789"};
list_t* head, * p;
int i;
printf("sizeof(list_t)=%d\n",sizeof(list_t));
head = (list_t*)malloc(sizeof(list_t));
head->next = NULL;
head->prev = NULL;
for (i = 0; i < NUM; i++)//反向建立单链表
{
p = (list_t*)malloc(sizeof(list_t)+strlen(buf[i])+1);
strcpy_s(p->data, strlen(buf[i]) + 1,buf[i]);
printf("p=%p,p->data=%p,size *p=%d,size data=%d\n",
p,p->data,sizeof(*p),sizeof(p->data));
printf("p->data=%s\n",p->data);
p->next = head->next;
head->next = p;
}
i = 1;
p = head->next;
while (p!=NULL)//输出链表中的节点
{
printf("List:%d,%p,%2d,%s\n",i++,p,strlen(p->data),p->data);
p = p->next;
}
while (head!=NULL)
{
p = head->next;
free(head);
head = p;
}
return 0;
}
//32位机器运行结果:(64位sizeof(地址)等于8)
sizeof(list_t)=8
p=001C5108,p->data=001C5110,size *p=8,size data=0
p->data=This is a string.
p=001C4F88,p->data=001C4F90,size *p=8,size data=0
p->data=abc
p=001C4FC0,p->data=001C4FC8,size *p=8,size data=0
p->data=123456789
List:1,001C4FC0, 9,123456789
List:2,001C4F88, 3,abc
List:3,001C5108,17,This is a string.
//32位机器运行结果:(64位sizeof(地址)等于8)
sizeof(list_t)=8
p=001C5108,p->data=001C5110,size *p=8,size data=0
p->data=This is a string.
p=001C4F88,p->data=001C4F90,size *p=8,size data=0
p->data=abc
p=001C4FC0,p->data=001C4FC8,size *p=8,size data=0
p->data=123456789
List:1,001C4FC0, 9,123456789
List:2,001C4F88, 3,abc
List:3,001C5108,17,This is a string.
#include
#include
#include
#define NUM 3
typedef struct list_t {
struct list_t* next;
struct list_t* prev;
char *data; //柔性数组
} list_t;
int main(void)
{
char buf[][20] = {"This is a string.","abc","123456789"};
list_t* head, * p;
int i;
printf("sizeof(list_t)=%d\n",sizeof(list_t));
head = (list_t*)malloc(sizeof(list_t));
head->next = NULL;
head->prev = NULL;
for (i = 0; i < NUM; i++)//反向建立单链表
{
p = (list_t*)malloc(sizeof(list_t));
p->data = (char*)malloc(strlen(buf[i])+1); //分别申请空间
strcpy_s(p->data, strlen(buf[i]) + 1,buf[i]);
printf("p=%p,p->data=%p,size *p=%d,size data=%d\n",
p,p->data,sizeof(*p),sizeof(p->data));
printf("p->data=%s\n",p->data);
p->next = head->next;
head->next = p;
}
i = 1;
p = head->next;
while (p!=NULL)//输出链表中的节点
{
printf("List:%d,%p,%2d,%s\n",i++,p,strlen(p->data),p->data);
p = p->next;
}
while (head!=NULL)
{
p = head->next;
free(head);
head = p;
}
return 0;
}
//结果
sizeof(list_t)=12
p=00F950D0,p->data=00F95108,size *p=12,size data=4
p->data=This is a string.
p=00F94F88,p->data=00F94FC0,size *p=12,size data=4
p->data=abc
p=00F9C580,p->data=00F9C5B8,size *p=12,size data=4
p->data=123456789
List:1,00F9C580, 9,123456789
List:2,00F94F88, 3,abc
List:3,00F950D0,17,This is a string.
.//结果
sizeof(list_t)=12
p=00F950D0,p->data=00F95108,size *p=12,size data=4
p->data=This is a string.
p=00F94F88,p->data=00F94FC0,size *p=12,size data=4
p->data=abc
p=00F9C580,p->data=00F9C5B8,size *p=12,size data=4
p->data=123456789
List:1,00F9C580, 9,123456789
List:2,00F94F88, 3,abc
List:3,00F950D0,17,This is a string.