zoukankan      html  css  js  c++  java
  • 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;//移动指针到下一个节点
    
              }       
    }

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

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

  • 相关阅读:
    OSI安全体系结构
    PHP 二维数组根据相同的值进行合并
    Java实现 LeetCode 17 电话号码的字母组合
    Java实现 LeetCode 16 最接近的三数之和
    Java实现 LeetCode 16 最接近的三数之和
    Java实现 LeetCode 16 最接近的三数之和
    Java实现 LeetCode 15 三数之和
    Java实现 LeetCode 15 三数之和
    Java实现 LeetCode 15 三数之和
    Java实现 LeetCode 14 最长公共前缀
  • 原文地址:https://www.cnblogs.com/ligongzi/p/2654448.html
Copyright © 2011-2022 走看看