C语言结构体和联合体小结

原文链接:http://www.cnblogs.com/ligongzi/archive/2012/08/24/2654448.html

以下为复制内容

C 结构体小结

     看了三天结构体,是时候总结一下了。

  关于结构体的声明:

  

复制代码
struct Student
{
    char name[20];
    char sex;
    int age;
    char addr[40];
};
/*然后定义一个Student 类型的 student变量*/
struct Student student;
复制代码

  也许是我受了Java影响,我一度写成这样:

复制代码
struct man
{
    int age = 30;
    int score = 80;
};

int main()
{
    man man1  = {20,70};

}
    
复制代码

     结果是铁定编译通过不了的。因为这是我自创的声明带默认值的结构体,编译器没见过。结构体成员变量在声明中是不能赋值的。

  正确的写法是:

复制代码
struct Man
{
    int age; //这样就好了
    int score;
};

int main()
{
   struct Man man1 = {30,80};
}
复制代码

    定义结构体的时候每次都要写struct 显然是烦琐了,精炼的C语言用来typedef来方便定义使用:

复制代码
typedef struct Man
{
    int age;
    int score;
}man;

int main()
{
    man man1 = {20,80};
    man man2 = {30,70};
    man man3 = {40,99};
    printf("%d\n",man1.age);
    printf("%d\n",man3.score);
}
复制代码

  这样一来大家想召唤多少个“男人”都没有问题。另外有一个极端一点的问题,声明结构体名和定义结构体变量名能不能一样?我们可以试试看:

复制代码
typedef struct man
{
    int age;
    int score;
}man;  //还叫man,有意见么?

int main()
{
    man man = {40,50};//还叫man,有问题么?
    printf("%d\t%d\n",man.age,man.score);
}
复制代码

    编译运行都是没有问题的。不信自己去试试看。

   然后我们来讨论重点吧:

复制代码
struct Student
{
    char name[20];
    char sex;
    int age;
    char addr[40];
};
/*然后定义一个Student 类型的 student变量*/
struct Student student;
复制代码

     给定义的结构中name和age赋值, 可以用下面语句:

     strcpy(student->name, "jack");

     student->age=21;

     student->name就是(*student).name的缩写形式。

    需要指出的是结构指针是指向结构的一个指针, 是结构中第一个成员的首地址, 因此在使用之前应该对结构指针初始化, 即分配整个结构长度的字节空间, 这可用下面函数完成, 仍以上例来说明如下:

     student=(struct string*)malloc(size of (struct string));

    size of (struct string)自动求取string结构的字节长度, malloc() 函数定义了一个大小为结构长度的内存区域, 然后将其诈地址作为结构指针返回。  

    注意:

    结构变量名不是指向该结构的地址, 这与数组名的含义不同,  因此若需要求结构中第一个成员的首地址应该是&[结构变量名]。

 

联合体

联合体的结构定义和结构体大体相似。

当一个联合被说明时, 编译程序自动地产生一个变量, 其长度为联合中最大的变量长度。

联合既可以出现在结构内, 它的成员也可以是结构。

    例如:

     

复制代码
struct{
          int age;
          char *addr;
          union{
               int i;
               char *ch;
          }x;
     }y[10];  
复制代码

    若要访问结构变量y[1]中联合x的成员i, 可以写成:

      y[1].x.i;

    若要访问结构变量y[2]中联合x的字符串指针ch的第一个字符可写成:

      *y[2].x.ch;

若写成"y[2].x.*ch;"是错误的。值得指出的是此时的*y[2].x.ch是一个没有分配内存地址的野指针,直接赋值给它在运行时会崩溃。

 

    结构和联合都是由多个不同的数据类型成员组成, 但在任何同一时刻, 联合中只存放了一个被选中的成员, 而结构的所有成员都存在。

    对于联合的不同成员赋值, 将会对其它成员重写,  原来成员的值就不存在了, 而对于结构的不同成员赋值是互不影响的。

    下面举一个例了来加对深联合的理解。

    

复制代码
 int main()
     {
          union{                   /*定义一个联合*/
               int i;
              struct{             /*在联合中定义一个结构*/
                    char first;
                    char second;
               }half;
          }number;
          number.i=0x4241;         /*联合成员赋值*/
          printf("%c%c\n", number.half.first, mumber.half.second);
          number.half.first='a';   /*联合中结构成员赋值*/
          number.half.second='b';
          printf("%x\n", number.i);
     }
复制代码

 

    输出结果为:

     AB

     6261

 从上例结果可以看出: 当给i赋值后, 其低八位也就是first和second的值; 当给first和second赋字符后, 这两个字符的ASCII码也将作为i 的低八位。

 

用结构体写一个单链表的雏形

复制代码
#include <stdio.h>
struct node 
{
          struct node *link;
          int value;
};

void main()

{
          struct node node1, node2, node3;
          struct node *head;  //定义链表头指针
          node1.value = 5;       //定义各个节点的内部属性值
          node2.value = 10;
          node3.value = 15;
          head = &node1;                 //头指针指向第一个节点的地址

          node1.link = &node2;//第一个节点的指针指向第二个节点的地址
         node2.link = &node3;//第二个节点的指针链接到第三个节点的地址
          node3.link = NULL;  //第三个节点的地址为空

          /*打印输出*/

          struct node *p;
          p = head;
          while(p != NULL)
          {
                   printf("%d\n", p->value);
                   p = p->link;//移动指针到下一个节点

          }       
}
复制代码

之所以说它是一个单链表的雏形,因为他是在是太不完整了,但是至少他已经有单链表的影子了。我将慢慢完善改进它。

总结给自己看的,所以整理了我认为重要的部分。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值