结构体中的指针

结构体中可以包含指针成员。一旦结构体中包含了指针成员,那么结构体的赋值运算就会变得复杂一些。请参考本章的10.5节的具体介绍。

typedef struct _student

{

    int age;

    char sex;

    char *name;

}student,*pstudent;

上面的结构体中,name成员是一个字符指针,如果要利用name来表示一个人的名字信息,那么需要单独为name指定内存。

比如:

student s1={30,’M’,”tom”};

上面的定义与初始化结构体变量s1的时候,将s1.name指向了静态常量区中的”tom”字符串首地址。

student s2;

s2.age=25;

s2.sex=’F’;

s2.name=(char *)malloc(16);

strcpy_s(s2.name,16,”susan”);

上面再定义了结构体变量s2之后,为s2.name在堆上分配了16个字节的内存,然后把名字拷贝进内存。

结构体中的指针,可以指向同一个类型的结构体地址。比如下面的定义方法:

 

typedef struct _node

{

    int value;

    struct _node *next;

}node,*pnode;

按照这种定义方法,next指针指向了同样类型的结构体地址。这正是数据结构中链表结点的定义方法。

如下图所示,在链表中,链表的头结点中的next指针指向下一个结点,下一个结点中的next指针又指向下下一个结点,最后一个结点的next指针为NULL。这样,只要知道了链表的头结点,就可以将链表中的所有结点遍历一次。

 

结构体的定义中,经常会出现下面3种不同的成员定义方法:

第一种定义方法中,name[]是一个包含1个元素的字符数组,与length成员一起用来存放一个变长的数据,即在name后面还有length-1个字节的变长数据。此种结构体经常用于存放变长数据。

第二种定义方法中,name[]是一个64个元素的字符数组,因此name[]在结构体中占用的内存空间是定长的。此种结构体用来存放数据的时候,数据不能超过指定的长度,而且容易造成部分内存空间的浪费,

第三种定义方法中,name是一个字符指针,在结构体中占4个字节(X86)或者8个字节(X64),必须为name指定新的内存空间,才能保存相应的数据。

现在我们用3种结构体来存放”lucy Clinton”782个数据,程序示例如下:

#include <string.h>

#include <malloc.h>

 

typedef struct _INFO1

{

       int value;

       size_t length;

       char name[1];

}INFO1,*PINFO1;

 

typedef struct _INFO2

{

       int value;

       char name[64];

}INFO2,*PINFO2;

 

typedef struct _INFO3

{

       int value;

       char *name;

}INFO3,*PINFO3;

 

int _tmain(int argc, _TCHAR* argv[])

{

       //计算变长空间大小

       INFO1 *pi1 =(INFO1 *)malloc(sizeof(INFO1)+strlen("lucy cliton"));

       if(pi1==NULL)

       {

              return -1;

       }

       memset(pi1,0,sizeof(INFO1)+strlen("lucy cliton"));

       pi1->value=78;

       pi1->length = strlen("lucy cliton")+1;

       strcpy_s(pi1->name,pi1->length,"lucy cliton");

 

       printf("value:%d,name:%s\n",pi1->value,pi1->name);

 

       free(pi1);

       pi1=NULL;

 

       INFO2 *pi2 = (INFO2 *)malloc(sizeof(INFO2));

       if(pi2==NULL)

       {

              return -1;

       }

       memset(pi2,0,sizeof(INFO2));

       pi2->value = 78;

       //因为name是定长的64个字节,在存放”lucy clinton”的时候

       //有部分空间被浪费了。

       strcpy_s(pi2->name,64,"lucy cliton");

      

       printf("value:%d,name:%s\n",pi2->value,pi2->name);

       free(pi2);

       pi2 = NULL;

 

       INFO3 *pi3 = (INFO3*)malloc(sizeof(INFO3));

       if(pi3==NULL)

       {

              return -1;

       }

       memset(pi3,0,sizeof(INFO3));

 

       pi3->value = 78;

 

       //需要为name指定新的内存空间,这里从堆上分配

       pi3->name = (char *)malloc(strlen("lucy cliton")+1);

       if(pi3->name ==NULL)

       {

              free(pi3);

              return -1;

       }

       memset(pi3->name,0,strlen("lucy cliton")+1);

       strcpy_s(pi3->name,strlen("lucy cliton")+1,

              "lucy cliton");

 

       printf("value:%d,name:%s\n",pi3->value,pi3->name);

       free(pi3->name);

       free(pi3);

       pi3=NULL;

       return 0;

}

周哥教IT,分享编程知识,提高编程技能,程序员的充电站。跟着周哥一起学习,每天都有进步。

通俗易懂,深入浅出,一篇文章只讲一个知识点。

当你决定关注「周哥教IT」,你已然超越了90%的程序员!

IT黄埔-周哥教IT技术交流QQ群:213774841,期待您的加入!

二维码
微信扫描二维码关注