进击的KFC第七节:C语言:结构体篇

结构体:  结构体是一种自定义的数据类型

不同于enum, struct各成员名是用分号’;’ 分隔, 而不是逗号’,’.

结构体需要先声明和定义, 然后再声明和定义其结构体变量, 才可进行访问.

结构体本身不能被直接赋值定义.

定义结构体变量方法:   
     struct 结构体名 变量名 = {初值};

例如: 先声明并实现结构体的内容
struct  student{     // 这是结构体, 叫student
     char  name[ 20 ];      // 注意 中间用分号分离
    
char  sex;
    
int  age;
    
double  studentID;
    float score;
//    void printName();     注意, 在结构体中不可以声明一个函数. 函数不能作为结构体的成员
};
结构体本身不能在声明成员变量时赋值, 只能通过它的变量给它赋值, 不同的变量会开辟不同的空间, 各变量的值不会冲突
然后在main函数中声明结构体变量并赋初值
     struct student  stu = { "xiaoming" , 'm' , 21 , 20151016, 88 };
                    // 注意, 初值的赋值时得注意数据类型一致 不同成员之间用逗号’,而不是;'隔开
                     // stu 叫结构体student 的结构体变量
结构体变量的取值
通过 变量名. 成员名   的方式进行取值
比如我现在要获得并打印结构体变量 stu 的名字
     printf ( "%s\n" , stu. name );// 即可

如果要修改结构体变量名的某个值, 如将stu的age改成23,stu的name改成 "longjiang"
    stu. age  = 23 ;
对于基本类型, 可通过直接访问的方法改变结构体变量对应成员的值.

但要注意的是, 如成员变量是数组的时候, 不能够直接进行赋值, 得通过访问数组的具体地址进行赋值
所以要改变name不能直接通过 stu.name = "longjiang ;
而是得通过strcpy(stu.name,"longjiang); 方法进行修改

如何通过一个函数打印整个stu的值呢?
刚才提过, 结构体是自定义的数据类型      函数的形式参数写法是 (数据类型 变量名)  同理 可将结构体的变量当成参数传给函数
不同的是结构体的数据类型是自定义的   写法是  struct 结构体名 结构体变量名
void  printStudent( struct student  stu) { // 形参的数据类型是 struct student
   printf("%s\n", stu.name);
    printf("%c\n", stu.sex);
    printf("%d\n", stu.age);
    printf("%.2lf\n", stu.studentID);
    printf("%.2f\n", stu.score);
}

   printStudent(stu);    // 将stu的所有信息打印出来





匿名结构体


通过上面的信息 我们可以知道 :   
     1. 结构体内不能定义函数 
     2. 结构体不能给自己赋值
     3. 结构体只能通过定义结构体变量, 来对结构体内的数据进行操作

如果结构体是匿名的 也就是没有名字的,  那我们要怎么定义这个匿名结构体的结构体变量呢?
struct  {
    
char  name[ 20 ];
    
char  sex;
    
int  age;
}
student1 = {
"123" , 'a' , 22 }
;
可以在声明结构体的同时, 声明结构体变量

也可以这么声明:
struct  {
    
char  name[ 20 ];
    
char  sex;
    
int  age;
} student1, student2;

然后通过student1.sex = ‘m’ 的方法, 对其进行赋值





别名: 
          关键字  typedef
用法: typedef existing new;
          即 typedef oldName newName;

比如给int起别名
   typedefint XiaoMing;
    int a = 10;
    XiaoMing b =10;
    printf("%d", a == b);
结果为1, 即表示 a == b

特殊的
给数组起名
    typedef int  MyArray[ 5 ];
表示 MyArray 是一个int型 容量为5的数组类型名
   MyArray array = {1,2,3,4,5};
    for (int i =0; i <5; i++) {
        printf("%d ",array[i]);
    }
当然这种写法想来是没人会选择去用的 看不懂可无视


但是下面这种用法是很常用的:
使用typedef定义结构体


第一种方法是常规方法, 值得注意的是可以把别名取成结构体名
第二种方法则比较简洁, 但是得注意的是, 用这种方法的时候 就不能在结构体声明定义的同时声明结构体变量, 写原来结构体变量的地方被替换成了结构体的别名, 此时可以同时定义多个别名, 每个别名用逗号隔开即可

使用别名的好处
     Student  st = { "xiaoming" , 'm' , 21 , 20151016 , 88.0 };
书写上: 不需要再写成  struct student st = { "xiaoming" , 'm' , 21 , 20151016 , 88.0 };
相比之下用别名定义简洁了许多








结构体数组
将多个结构体变量放到数组中, 构成结构体数组
形式如下:
struct student students[10] = {0};
students[0].name; // 访问第一个学生的姓名

代码如下:
   Student stu1 = {"xiaoming",99,25}, stu2 = {"xiaohong",80,22}, stu3 = {"xiaogang",70,23};
   Student studentArray[3] = {stu1, stu2, stu3};  // studentArray[0] == stu1 ...
                                                  // studentArray[1].age == stu2.age...
结构体数组通过将多个同一个结构体声明的结构体变量放在一个数组里, 就可以通过数组遍历的方法, 查询每个结构体变量的值
结构体数组的优点在于可以批量处理多个相同结构体的结构体变量 的某个成员


根据对比5个学生的成绩, 将成绩最高的学生的所有信息打印
     Student  stu1 = { "xiaoming" , 99 , 25 }, stu2 = { "xiaohong" , 80 , 22 }, stu3 = { "xiaogang" , 70 , 23 }, stu4 = { "zhaoc" , 60 , 23 }, stu5 = { "jinggang" , 70 , 22 };
    
    
Student  studentArray[ 5 ] = {stu1, stu2, stu3, stu4, stu5};
    
    
int  score = studentArray[ 0 ]. score ;
    
for  ( int  i =  0 ; i < 5 ; i++) {
        
if  (score < studentArray[i]. score ) {
            score = studentArray[i].
score ;
        }
    }
    
for  ( int  i =  0 ; i < 5 ; i++) {
        
if  (score == studentArray[i]. score ) {
            
printStudent (studentArray[i]);   // 打印出结构体的所有成员信息
        }
    }



按照5个学生的成绩, 对五个学生进行排序:
     for  ( int  i =  0 ; i < 5  - 1 ; i++) {
        
for  ( int  j =  0 ; j < 5  - 1  - i; j++) {
            
if  (studentArray[j]. score  > studentArray[j +  1 ]. score ) {
                
Student  temp = studentArray[j];
                studentArray[j] = studentArray[j + 
1 ];
                studentArray[j + 
1 ] = temp;
            }
        }
    }
   
    for (int i =0; i <5; i++) {
        printStudent(studentArray[i]);   //打印出结构体的所有成员信息
    }


打印结构体成员信息的函数代码:
void printStudent(Student stu) {
    printf("%s\n", stu.name);
    printf("%d\n", stu.age);
    printf("%d\n", stu.score);
}



结构体的字节对齐
以最大成员变量类型所占空间为分配单位,
按结构体成员声明顺序自上而下分配.

计算顺序 由上至下依次计算  一个成员变量一个成员变量的计算
并且自动补齐为 该结构体中所占最大字节的变量的字节数来进行补齐
例: 如果结构体中 最大的是float 就按 4的倍数补齐 最大的是double 就按8的倍数补齐



注: 分配空间不足以储存成员变量时, 分配新的空间单位
在结构体声明的文件添加#pragma pack(1) 取消自动字节补齐功能




结构体的嵌套使用

描述一个人与出生年月日和家庭成员
typedef struct  dateDes {
    
int  year;
    
int  month;
    
int  day;
}DateDes;

typedefstruct HomePerson {
    char mother[20];
    char father[20];
}HomePerson;

typedef struct  Person{
     char  name[ 20 ];
    DateDes date;
   HomePerson home;
Person;

在结构中  可以有其他结构体当作成员变量  结构体中可以嵌套结构体
不过值得注意的是, 结构体中出现的其他结构体必须得是本结构体出现之前就已经声明定义过的结构体
创建这个嵌套结构体的结构体变量 代码如下:
     DateDes  date = { 2015 , 10 , 18 };
    
HomePerson  home = { "mama"  , "baba" };
    Person person = {"xiaoming", date, home};

获得其本身名字,  获得其家人名字
     printf ( "%s\n" , person. name );
    printf("%s\n", person.home.father);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值