HeadFirstC笔记_5  结构、联合与位字段:创建自己的结构

有时要传很多数据
C语言可以处理很多不同类型的数据:小数字、大数字、浮 点数、字符与文本。但现实世界中的事物往往需要一条以上
的数据来记录。比如:
     
     
     
  1. /* 打印目录项 */
  2. void catalog(const char *name, const char *species, int teeth, int age)
  3. {
  4. printf("%s is a %s with %i teeth. He is %i\n",
  5. name, species, teeth, age);
  6. }
  7. /* 打印贴在水缸上的标签 */
  8. void label(const char *name, const char *species, int teeth, int age)
  9. {
  10. printf("Name:%s\nSpecies:%s\n%i years old, %i teeth\n",
  11. name, species, teeth, age);
  12. }
  13. int main()
  14. {
  15. catalog("Snappy", "Piranha", 69, 4);
  16. label("Snappy", "Piranha", 69, 4);
  17. return 0;
  18. }
两个不同的函数都传了 相同的4条 数据,显然这种方式是累赘的。怎么才能解决这个问题?

用结构创建结构化数据类型
如果需要把一批数据打包成一样东西,就可以使用结构 (struct)。 struct 是structured data type(结构化数据类型)
的缩写。有了结构,就可以像下面这样把不同类型的数据写 在一起,封装成一个新的大数据类型:
    
    
    
  1. struct fish {
  2. const char *name;
  3. const char *species;
  4. int teeth;
  5. int age;
  6. };
结构与数组有些相似,除了以下两点:
1.结构的大小固定。
2.结构中的数据都有名字。

给结构赋值
和新建数组很像,你只需 要保证每条数据按照它们在结构中定义的顺序出现即可:
     
     
     
  1. struct fish snappy = { "Snappy", "Piranha", 69, 4};

问: fish结构会保存字符串吗?
答: 在这个例子中不会,这里的 fish结构中只保存了字符串指针,也 就是字符串的地址,字符串保存在存 储器中其他位置。

问: 但还是可以把整个字符串保存在结构中吧?
答: 对,只要把字符串定义成字 符数组就行了,像char name[20];。

只要把“鱼”给函数就行了
现在,你只要把新的自定义数据传给函数就行了,而不必传 递一大批零散的数据。
      
      
      
  1. /* 打印目录项 */
  2. void catalog(struct fish f)
  3. {
  4. ...
  5. }
  6. /* 打印贴在水缸上的标签 */
  7. void label(struct fish f)
  8. {
  9. ...
  10. }
  11. int main(){
  12. struct fish snappy = { "Snappy", "Piranha", 69, 4};
  13. catalog(snappy);
  14. label(snappy);
  15. }

把参数封装在结构中,代码会更稳定。
把数据放在结构中传 递有一个好处,就是 修改结构的内容时, 不必修改使用它的函数。比如 要在fish中多加一个字段:
         
         
         
  1. struct fish {
  2. const char *name;
  3. const char *species;
  4. int teeth;
  5. int age;
  6. // 新增字段
  7. int favorite_music;
  8. };
catalog()和label()知道有 人会给它们一条fish,但却不 知道fish中现在有了更多的数 据,它们也不关心,只要fish 有它们需要的所有字段就行了。
这就意味着,使用结构,不但 代码更好读,而且能够更好地 应对变化------>早期的面向对象思想体现。

使用“.”运算符读取结构字段
         
         
         
  1. struct fish snappy = { "Snappy", "piranha", 69, 4};
  2. printf("Name = %s\n", snappy.name); // snappy.name这是snappy中的name属性

问: 数组变量就是一个指向数组的指针,那么结构变量是一个指向结构的指针吗?
答: 不是,结构变量是结构本身的名字。

问: 结构就相当于其他语言中的类?
答: 它们很相似,但在结构中添加方法可就没那么 容易了。

存储器中的结构
在定义结构时,你并没有让计算机在存储器中创建任何东西,
只是给了计算机一个模板,告诉它你希望新的数据类型长什
么样子。
          
          
          
  1. struct fish {
  2. const char *name;
  3. const char *species;
  4. int teeth;
  5. int age;
  6. };
当定义新变量时,计算机则需要在存储器中为结构的实例创建 空间,这块空间必须足够大,以装下结构中的所有字段:
           
           
           
  1. struct fish snappy = { "Snappy", "Piranha", 69, 4};
那么当把一个结构变量赋给另一个结构变量时会发生什么?
计算 机会创建一个全新的结构副本,也就是说,计算机需要再分配一 块存储器空间,大小和原来相同,然后把每个字段都复制过去。
            
            
            
  1. struct fish snappy = { "Snappy", "Piranha", 69, 4};
  2. struct fish gnasher = snappy;
切记:为结构变量赋值相当于叫计算机复制数据。
注意:字符串字段复制的是指向字符串的
指针,而非字符串本身。
当把一个结构变量赋给
另一个结构变量,计算
机会复制结构的内容。如果结构中
含有指针,那么复制的仅仅是指针
的值,像这里,gnasher和snappy
的name和species字段指向相同字
符串。

结构中的结构
既然结构可以用现有数据类型创建数据类型,也就能用其他
结构创建结构。举个例子:
                     
                     
                     
  1. struct preferences {
  2. const char *food;
  3. float exercise_hours;
  4. };
  5. struct fish {
  6. const char *name;
  7. const char *species;
  8. int teeth;
  9. int age;
  10. struct preferences care; //结构中的结构,即嵌套
  11. };
上述代码向计算机描述了一个结构中的结构。你可以像之前 一样用数组语法创建变量,但现在可以在数据中包含结构中 的结构。
                      
                      
                      
  1. struct f
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值