黑马程序员------C语言基础 结构体、枚举及关键字 typedef

时间:2021-09-12 00:22:57

 ------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

构造类型 结构体、枚举和关键字typedef

     构造类型 由多个或者已经定义的类型元素用构造的方法,构造新的类型

    构造类型:数组 结构体

一、结构体

    1.结构体概念:

        由相同类型或者不同类型的数据用构造方法,构造的类型

    结构体的定义

        struct 结构体名{

        成员列表

    }

     定义一个汽车结构体

     struct Car{

        char*color;

        int lunzi;

        int speed;

        };

    定义结构体三种方法 

    1)先定义结构体,然后在定义结构体变量

       struct Student{

     //学生学号

    int sno ;

    //学生姓名

    char [10];

    //学生年龄

    int age;

     //学生成绩

    float score;

    };

    注意:

       结构体定义完以后,计算机并不会给结构体分配内存空间,会在定义结构体变量后分配变量

    结构体变量定义格式  struct 结构体 结构体变量名;

    struct Student stu1; 这句话表示定义一个Student结构体变量,变量名为 stu1

    //stu1 Student类型,stu1可以存放学生的信息。成绩,姓名...

     struct Student stu1,stu2,stu3;可以定义多个结构体变量

    2)定一结构体的同时,定义结构体变量

     格式

    struct 结构体名{

  

   }结构体变量1,结构体变量2。。。;

    

    struct Student{

    //学生学号

    int sno ;

    //学生姓名

    char [10];

    //学生年龄

    int age;

    //学生成绩

    float score;

    }stu3,stu4,....;

    3)匿名结构体定义结构体变量

      struct {

    

    }结构体变量1,结构体变量2...;

       struct {

         int lunzi;

    int speed;

     char*color;

    }car1,car2,car3;

   2结构体变量中成员访问方法

     结构体变量名.成员变量

      //定义一个Car类型的结构体

    struct Car{

        char*pp;

        int lunzi;

        int speed;

    

    };

    //用结构体类型,定义结构体变量

        struct Car car1;

      用 car1.pp ;

        car1.lunzi;

        car1.speed;

    3结构体变量的初始化

  struct  Student{

        //学号

        int sno;

        //学生姓名

        char name[21];

        //学生年龄

        int age ;

        //学生成绩

        float score;

        

    };

    struct Student stu1;

    //结构体变量的初始化

    stu1.sno = 28;

    stu1.age = 18;

    stu1.score= 36.88f;

    //stu1.name="abc"; 这里是错的

    char name1[21]="张三丰";

    //这里是用字符串拷贝函数,将 char name1 拷贝到stu1.name,覆盖掉stu1.name

    strcpy(stu1.name,name1);

    printf("学号 %d\n年龄 %d\n分数%.2f\n姓名%s\n",stu1.sno,stu1.age,stu1.score,stu1.name);

    //stu1.name 字符长度是多少

    printf("stu1.name %ld\n",sizeof(stu1.name));

  //stu1.name 字符串的长度是多少

//汉字的编码问题

//UTF-8 xcode中默认的中文的编码是utf8格式

//         国际通用编码 一个汉字占用3个字节

//GB2312 GBK 国标 一个汉字占用2个字节

     printf("stu1.name 长度:%ld\n",strlen(stu1.name));

   //2定义结构体的同时,进行初始化

    

//    初始化值的顺序要和定义结构体的顺序一致

    struct Student stu2={8,"豆比",16,57.99};

    printf("学号 %d\n姓名%s\n年龄%d\n分数%.2f",stu2.sno,stu2.name,stu2.age,stu2.score);

     //3.定义结构体的同时,还可以制定元素的初始化

    struct Student stu3={.name = "lady Gaga"};

结构体变量的存储原理

    结构体占用到内存空间时每个成员占用的字节数之和(对齐考虑)

    结构体对齐的含义:1)结构体总长度

                  2)结构体内部个数据的成员的内存对齐,即数据成员相对结构体的起始位置

    结构体大小计算方法和步骤

       1)先找对齐模数:对齐模数事基本数据类型中占用字节数最大的那个

        2)在计算结构体变量的中个成员占用到字节和

         struct A{

            short a;//2

            char b;//1

            float c//4

    };  

    这里可以看到 模数是4,然后先分配4个字节。 锕占两个自己。还多两个,b一个字节补到 a的后面 。c这时是4个自己 。先分配到不够用了。于是就再开辟一个4个自己的内存来直接存储c。所以得到 这个结构体的内存是8个字节。

5.结构体作用域

            定义在函数外部的结构体是全局变量

            定义在函数体内部的位局部变量。函数退出结构体消失

    

二、结构体数组

     结构体数组用来存放大量的结构体相同的结构变量

    1.结构体数组的定义

    

    定义的第一种方法

    1)定义结构体数组的同时定义结构体变量

    strcut Student{

            int age;

            char*name;

         float score;

    }stu[5];

    

    2)先定义结构体,后定义数组

         struct Student boy[5];

    2.结构体数组的初始化方法

     1)定义结构体的同时初始化

        strcut Student{

            int name[21];

            int age;

      }boys[3]={{"zbx",18},{"ddf",34},{"tyu",23}};

    

     2)定义的同时进行初始化

        strcut Student girl[2]={{"zbz",18},{"lzl",23}};

     3)先定义后初始化 ,整体赋值

        struct Student ds[2];

            ds[0]=(struct Student){"xzmly",18}

            ds[1]=(struct Student){"bdjy",1}

    4)定义结构体数组,后初始化

        strcut Student stu[2];

       //stu[0].name={"zbz"}; 错误的写不进去

    //可以用 strcpy(stu[0].name "zzl");

        //或者

     scanf("%s",stu[0].name);

       stu[0].age = 18;

     结构体数组的遍历 

      for(int i =0;i<3;i++){

            printf("name:%s,age:%d\n",boys[i].name,boys[i].age);

      }

3.代码实现
利用结构体计算不及格到人数,和成绩在80到100点人的名字,成绩

#include <stdio.h>

int main(int argc, const char * argv[]) {
//结构体
struct Student {
int num;
char*name;
char sex;
float score;
};
//1定义结构体数组
struct Student boy[5]={
{101,"li ping",'f',45},
{102,"zhang ping",'m',62.5},
{103,"he fang",'f',92.5},
{104,"cheng ling",'m',87},
{105,"wang ming",'m',58}
};

float sum=0;
float avg=0;
int count=0; //计算不及格人数
for (int i=0; i<5; i++) {
sum += boy[i].score;
if (boy[i].score<60) {
count++;
}else if(boy[i].score >=80 && boy[i].score <= 100){ //判断成绩
printf("姓名%s 成绩%.2f\n",boy[i].name,boy[i].score);

}
}

printf("平均分是%.2f 不及格的人数%d",avg = sum/5.0,count);

return 0;
}


 

用结构体数组实现通讯录
思路 :
定义一个结构体数组,姓名电话和电话号码
输入完成打印下来。

#include <stdio.h>
#define LEN 5
struct Person{
char name[21];
char number[18];
};
int main(int argc, const char * argv[]) {
struct Person people[LEN];//定义结构体数组
//利用循环输入联系人信息
for(int i=0;i<LEN;i++){
printf("请输入第%d个人的姓名:电话:\n",i+1);
scanf("%s %s",people[i].name,people[i].number);

}
//打印联系人信息
for (int i =0;i<LEN;i++){
printf("姓名:%s 电话 :%s\n",people[i].name,people[i].number);
}
return 0;
}


 

三、结构体指针

     结构体指针就是用来存放结构体变量地址的指针变量

    1结构体指针的定义 

    struct 结构体名 *变量名

     struct Car{

        int lunzi;

        int speed;

    }car1;

        struct Car *p = NULL;//定义一个结构体指针变量

        p=&car1;//正确 。这里是结构体变量的地址

    2结构体指针间接访问成员值

    格式(*结构体指针变量).成员 或者结构体指针变量->成员变量

     //定义一个结构体

    struct Student{

            int age;

            char*name;

    }

    //定义一个结构体变量

            struct Student stu1 ={18,"三丰"}

    //结构体变量访问成员变量

     stu1.age 值时18

        stu.name 值 张三丰

    用结构体指针间接访问 

        struct Stdent *p=&stu1;

        (*p).name 访问年龄

        (*p).age  访问姓名

    或者 p->name ;

        p->age; //p事一个结构体指针

    //这里不能用结构体变量stu1->name是错误的。

    3,结构体的嵌套

      结构体定义中,结构体的成员又是另外一个结构体体变量

    结构体的嵌套使用注意:

       1)结构体定义可以嵌套其他结构类型的变量

            不可以嵌套自己

 

    struct Date{

        int year;

        int month;

        int day;

    

    };

    

    struct Student {

        char *name ;

        int age ;

        float score;

        //struct Student stu; 这是错误的 。。

    //        struct Student *stu;//这是对的。指针调用自己

        struct Date birthday;

    };

    //2)初始化

    struct Student stu1={"zhangsanf",25,45.66f,{2015,12,12}};

    //结构体嵌套访问

    printf("姓名 %s,年龄%d,分数%.2f 生日(%d-%02d-%02d\n",stu1.name,stu1.age,stu1.score,stu1.birthday.year,stu1.birthday.month,stu1.birthday.day);

       

    4结构体变量作为函数参数

       1)用结构体变量成员值作为函数参数,实质是值传递

       2)用结构体变量作为函数参数。也是值传递

 

#include <stdio.h>

    struct Car {

    int lunzi ;

    int speed;

    };

    void xiuche(struct Car c1){

    c1.lunzi =2;

    

    }

    void xiuche2(struct Car *car1){

        (*car1).lunzi =2

    }

   int main(int argc , const char *argv[]){

        struct Car car1 ={4,100};

            xiuche(car1);    printf("car1lunzi%d\n",car1.lunzi);

      //这也是值传递所以car1的*数还是4

    //结构体指针作为函数的参数

      xiuche2(&car1);//结构体的地址传递给函数 可以理解为结构体指针作为函数参数

    printf("car1lunzi个数%d\n");

      //这样lunzi数改为2.实质是地址传递

    return 0

 

    }

四、枚举类型

    枚举类型: c语言提供了一种类型,这种类型的变量值呗限定在一定的范围之内。

    枚举的定义:

        enum 枚举类型{枚举值1,枚举值2,枚举值3//枚举变量列表};

    enum Weekday {zhouyi,zhouer,zhousan,zhouri,};

    

    enum Sex{SexMan,SexWomen}; 

    //全局变量,局部变量的定义和结构体一样。

    枚举类型的变量的定义

        1)先定义枚举类型 再定义枚举变量

    enum iColor{iColorWhite,iColorbBlock,iColorTHJ}

         enum icolor iPhoneColor;

     // 这里iPhoneColor的取值有要求 只能取,iColorWhite,iColorbBlock,iColorTHJ

    2)定义枚举类型的同时,定义枚举变量

      enum iColor{

        iColorWhite,

        iColorbBlock,

        iColorTHJ

        }iPhoneColor;

    枚举类型变量的初始化

       iPhoneColor = iColorBlock;

   枚举变量的值

    枚举类型定义完成以后,系统会自己给枚举的每一个元素都会赋值一个整型的初值,

    默认的初值 从第一个元素开始值为0,以后每个在前一个的基础上+1

五、typedef 关键字的介绍

    typede 就是给别人起外号

    typedef 原类型名 新类型名

   typedef 的用法

    1.基本数据类型起别名

      int a =4;

    typedef int  LD;

      则 可以 用LD c=4 ; LD就相当与是int

   2 用在数组名上

       int a[5];

     typedef  int ARRAY[5];

      ARRAY c ={1,2,3,4,5}; 数组长度为 5

    3给结构体起别名

       strcut Student stu1;

    typedef struct Srudent P;//表示给结构体起别名

    可以用 p stu2 ={12,"zbz"};

        或者 tyedef strcut Car {

                int lunzi;

                int speed;

    }MYCAR;

       MYCAR  car1={4,200};

    4给枚举起别名 

      typedef enum Sex{SexWomen ,Sexman} ISEX;

     ISEX 就是这个枚举类型的别名

    ISEX s1,s2;  s1=SexWomen;  s2=SexMan;

    5给函数指针起别名

      int(*p)(int,int);

    typedef int(*FUN)(int,int); //FUN是个别名

      FUN f1,f2; 都是函数的指针

       f1 sum; f2 jian;