zoukankan      html  css  js  c++  java
  • 黑马程序员-C语言结构体

    实际问题中的数据中往往有着不同类型的数据类型,例如在校的学生,年龄(int型)、身高(float型)、体重(float型)、姓名(字符串类型)、性别(char)等等这些都是每一个学生应有的属性,我们肯定不能用之前学过的数据类型将这些数据表达出来,结构体这种新的数据类型就应运而生,不管是C语言还是OC语言都有它的用武之地。

    • 结构体是一种构造数据类型,也就是说在用之前我们必须先定义(构造)它,那么结构体的一般形式为:
    1     struct 结构体名{
    2         类型1 成员名1
    3         类型2 成员名2
    4         ...  ...
    5     }
    6     

    其中struct为关键字,是结构体类型的标志,结构体名一般首字母大写

    比如定义一个学生的结构体:(注意大括号和末尾的分号

    1     struct Student{
    2         int age;
    3         float weight;
    4         char *name;
    5     };
    • 结构体类型定义完,要想使用结构体还要定义结构体变量,有些人就被这几个概念搞晕了,其实很好理解的,结构体的定义好比说明int型的数据具有哪些特点,而结构体变量的定义就类似以下语句:
    1 int a;

    (沿用上面的结构体)

    struct Student stu;

    其中stu为结构体变量名,struct Student表明stu变量为学生类型的结构体,结构体类型的定义和结构体变量的定义我们可以一步完成:

    1     struct Student{
    2         int age;
    3         float weight;
    4         char *name;
    5     }stu;

    我们也可以定义多个结构体变量:

    1     struct Student{
    2         int age;
    3         float weight;
    4         char *name;
    5     }stu1, stu2, stu3;

    这里的stu1、stu2、stu3都是Student类型的结构体变量

    • 结构体类型变量的初始化
    1     //错误代码
    2     struct Student{
    3         int age;
    4         float weight;
    5         char *name;
    6     }stu1;
    7     
    8     stu1 = {16,58.4,"ZhangSan"};

    这是初学者容易犯的错误,那么对于结构体变量的整体初始化只能是下列四种方式之一:

     1     //第一种方式
     2     struct Student{
     3         int age;
     4         float weight;
     5         char *name;
     6     }stu1= {16,58.4,"ZhangSan"};
     7     
     8     //第二种方式
     9     struct Student{
    10         int age;
    11         float weight;
    12         char *name;
    13     };
    14     
    15     struct Student stu1 = {16,58.4,"ZhangSan"};
    16     
    17     //第三种方式
    18     struct Student{
    19         int age;
    20         float weight;
    21         char *name;
    22     }stu1 = {.weight = 58.4,.age = 16,.name = "ZhangSan"};
    23     
    24     //第四种方式
    25     struct Student{
    26         int age;
    27         float weight;
    28         char *name;
    29     };
    30     
    31     struct Student stu1 = {.weight = 58.4,.age = 16,.name = "ZhangSan"};

    第一种和第二种方式要注意每个数据的先后顺序,要一一对应起来,至于第三种和第四种方式用到了访问结构体成员变量的点('.')方法,这两种方法对成语变量的赋值是可以不按顺序来

    • 访问结构体的成元变量的一般形式为:结构体变量名.成员变量名(中间连接的是点号)
     1 #include<stdio.h>
     2 
     3 int main(){
     4     
     5     //定义一个结构体类型
     6     struct Student{
     7         int age;
     8         float weight;
     9         char *name;
    10     };
    11     //定义一个结构体变量并初始化
    12     struct Student stu1 = {16,58.4,"ZhangSan"};
    13     //修改成员变量的值
    14     stu1.age = 14;
    15     //输出修改后的值
    16     printf("%d
    ", stu1.age);
    17     return 0;
    18 }
    • 结构体数组的定义和初始化
     1 #include<stdio.h>
     2 
     3 int main(){
     4     
     5     //定义一个结构体类型
     6     struct Student{
     7         int age;
     8         float weight;
     9         char *name;
    10     };
    11     //定义一个结构体数组并初始化
    12     struct Student stu[3] = {{16,58.4,"ZhangSan"},
    13                              {15,54.3,"LiSi"},
    14                              {17,55.0,"LiMing"}};
    15     //输出每个结构体数组中age的成员变量值
    16     printf("%d---%d---%d
    ", stu[0].age,stu[1].age,stu[2].age);
    17     return 0;
    18 }
    • 结构体指针,因为结构体变量在内存中也有各自的存储地址,所以肯定能用指针操作

    结构体变量指针的定义

    1     struct Student{
    2         int age;
    3         float weight;
    4         char *name;
    5     }*p_stu;

    也可以是这样

    1     struct Student{
    2         int age;
    3         float weight;
    4         char *name;
    5     };
    6     
    7     struct Student *p_stu;

    那么指针式如何访问成员变量的呢?有两种方式

    1. (*指针变量名).成员名
    2. 指针变量名->成员名

    代码实现:

     1 #include<stdio.h>
     2 
     3 int main(){
     4     
     5     //定义一个结构体类型此时内存还没有分配空间给结构体
     6     struct Student{
     7         int age;
     8         float weight;
     9         char *name;
    10     };
    11     //定义一个结构体指针,此时系统会分配相应大小的空间给指针变量
    12     struct Student *p_stu;
    13     
    14     p_stu->age = 10;
    15     p_stu->name = "ZhangSan";
    16 
    17     printf("%d---%s
    ", p_stu->age,(*p_stu).name);
    18     return 0;
    19 }
    • 结构体的使用注意
    1. 结构体类型定义里可以有其他结构体类型,比如:
       1 #include<stdio.h>
       2 //定义一个Class类型的结构体
       3 struct Class{
       4     int cla; //班级
       5     int gra; //年级
       6 };
       7 
       8 //定义一个Student类型的结构体
       9 struct Student{
      10     int age; //年龄
      11     float weight; //体重
      12     char *name; //姓名
      13     struct Class class; //Class结构体类型的变量
      14 }stu;
      15 
      16 
      17 //但是要注意
      18 int main(){
      19     
      20     stu.class.cla = 7; //赋值给Class类型的成员变量cla
      21     printf("%d
      ",stu.class.cla);
      22 
      23     return 0;
      24 }

      其中需要注意的是被嵌套的结构体(比如上面的Class结构体)定义一定要放在嵌套结构体(比如上面的Student)的前面,另外结构体的定义是可以放在main函数的前面的,这种情况下要是想访问嵌套里的成语变量,依然还是用点('.')语法,正如上面的第20行代码

    2. 结构体类型名是可以省略的(不推荐使用),不过一般这种情况下结构体变量一起定义的,否则没法使用该类型的结构体,比如:
      1 //定义一个Student类型的结构体
      2 struct {
      3     int age; //年龄
      4     float weight; //体重
      5     char *name; //姓名
      6 } stu; //结构体变量名为stu

      第2行代码struct后面没有跟上类型名,第6行代码stu为结构体变量名,如果没有这个变量名,下次想用这种结构体类型的话,还得重新写一遍结构体类型定义,是非常麻烦的,所以一般不建议这样用

    3. 结构体初始化整体赋值时是不能和定义分开的:
       1 //定义一个Student类型的结构体
       2 struct Student{
       3     int age; //年龄
       4     float weight; //体重
       5     char *name; //姓名
       6 };
       7 
       8 //正确写法
       9 struct Student stu = {14,56.3,"ZhangSan"};
      10 
      11 //错误写法
      12 struct Student stu;
      13 stu = {14,56.3,"ZhangSan"};

      结构体的整体赋值只能是这样,或者单个进行赋值:

       1 //定义一个Student类型的结构体
       2 struct Student{
       3     int age; //年龄
       4     float weight; //体重
       5     char *name; //姓名
       6 };
       7 
       8 struct Student stu;
       9 stu.age = 14;
      10 stu.weight = 56.3;
      11 stu.name = "ZhangSan";
    4. 结构体变量的分配空间问题:首先只定义结构体类型,系统是不会分配内存空间的,只有出现了结构体变量的时候,系统才会分配一定大小的内存空间给变量,分配的原则是按照内存对齐原则,具体细节请参照:结构体的内存空间分配原理
  • 相关阅读:
    centos 安装 谷歌BBR
    centos上mailx通过465端口发送邮件
    centos 6的LAMP一键安装包(可选择/升级版本)
    Linux 一键安装最新内核并开启 BBR 脚本
    CentOS 7安装Xfce和VNC
    重构手法之简化函数调用【4】
    重构手法之简化函数调用【3】
    重构手法之简化函数调用【2】
    重构手法之简化函数调用【1】
    重构手法之简化条件表达式【4】
  • 原文地址:https://www.cnblogs.com/oucding/p/4403422.html
Copyright © 2011-2022 走看看