C语言学习——结构体

目录

十一、结构体与共用体

11.1概述

11.2定义结构体类型变量的方法

1、先声明结构体类型再定义变量

2、在声明类型的同时定义变量

3、直接定义结构体类型变量

11.3结构体变量的引用

11.4结构体变量的初始化

11.5结构体数组

定义结构体数组

结构体数组的初始化


十一、结构体与共用体

11.1概述

不同类型的数据组合成一个有机的整体,以便于引用。在一个组合项中包含若干个类型不同(当然也可以相同)的数据项。C语言允许用户自己指定这样一种数据结构,它称为“结构体”

声明一个结构体类型的一般形式为:

struct 结构体名

{ 成员表列 };

“结构体名”用作结构体类型的标志,它又称为“结构体标记”。花括号内室该结构体中的各个成员,又它们组成一个结构体。对各个成员都应进行类型声明,例如:

类型名 成员名

也可以把“成员表列”称为“域表”。每一个成员也称为结构体中的一个域。成员名命名规则与变量名相同。

小例子:

struct student{   //结构体名为student
    int num;         //占2个字节
    char name[20];   //占20个字节
    char sex;        //占1个字节
    int age;         //占2个字节
    float score;     //占4个字节
    char address[30];//占30个字节
};   //注意不要忽略最后这个分号

11.2定义结构体类型变量的方法

为了能在程序中使用结构体类型的数据,应当定义结构体类型的变量,并在其中存放具体的数据。

可以采用以下3种方法定义结构体类型变量。

1、先声明结构体类型再定义变量

如上面已经定义了一个结构体类型struct student,可以用它来定义变量。例如:

struct student student1,student2;
//结构体类型名     这两是结构体变量名

定义了student1和student2为struct student类型的变量,它们具有与struct student类型的数据结构。

在定义了结构体变量后,系统会为之分配内存单元。例如student1和student2在内存中各占59个字节。(各成员所占内存之和)

2、在声明类型的同时定义变量

例如:

struct student{
     int num;        
    char name[20];   
    char sex;       
    int age;         
    float score;     
    char address[30];
}student1,student2;

作用与前一种方法相同。这种形式定义的一般形式为:

struct 结构体名

{

成员表列

}变量名表列;

3、直接定义结构体类型变量

其一般形式为:

struct

{

成员表列

}变量名表列;

即不出现结构体名。

关于结构体类型,有几点需要说明:

(1)类型与变量是不同的概念,不要混同。只能对变量赋值、存取或运算,而不能对一个类型赋值、存取或运算。在编译时,对类型是不分配空间的,只对变量分配空间。

(2)对结构体中的成员(即“域”),可以单独使用,它的作用与地位相当于普通变量。(关于对成员的引用方法,下面会讲到)

(3)成员也可以是一个结构体变量。例如:

struct date{   //声明一个结构体类型
    int month;
    int day;
    int year;
}
​
struct student{
     int num;        
    char name[20];   
    char sex;       
    int age;         
    struct date birthday;  //birthday是struct date类型     
    char address[30];
}student1,student2;

(4)成员名可以与程序中变量名相同,二者不代表同一对象。

11.3结构体变量的引用

引用结构体变量应当遵循以下原则:

(1)不能将一个结构体变量作为一个整体进行输入和输出。例如:已定义student1和student2为结构体变量并且它们已有值。不能这样引用:

printf("%d,%s,%c,%d,%f,%s\n",student1);

只能对结构体变量中各个成员分别进行输入和输出。引用结构体变量中成员的方式为:

结构体变量名.成员名

例如:

student1.num = 10010;  //对student1变量中的num成员赋值

. "是成员(分量)运算符,它在所有的运算符中优先级最高,因此可以把student1.num作为一个整体看待。

(2)如果成员本身又属于一个结构体类型,则要若干个成员运算符,一级一级地找到最低的一级的成员。只能对最低级的成员进行赋值或存取以及运算。例如对上面定义的结构体变量student1,可以这样访问各成员:

student1.num
student1.birthday.month

注意,不能用student1.birthday来访问student1变量中的成员birthday,因为birthday本身就是一个结构体变量。

(3)对结构体变量的成员可以像普通变量一样进行各种运算(根据其类型决定可以进行的运算)。例如,

student2.score = student1.score;
sum = student2.score + student1.score;
student1.age++;
++student1.age;

由于" . " 运算符的优先级最高,因此student1.age++是对student1.age进行自加运算,而不是先对age进行自加运算。

(4)可以引用结构体变量成员的地址,也可以引用结构体变量的地址。例如:

scanf("%d",&student1.num);  //输入student1.num的值
printf("%o",&student1);   //输出student1的首地址

不能用以下语句整体读入结构体变量,例如:

scanf("%d%s%c%d%f%s",&student1);

结构体变量的地址主要用作函数参数,传递结构体变量的地址。

11.4结构体变量的初始化

和其他类型变量一样,对结构体变量可以在定义时指定初始值。

对结构体变量初始化。

#include<stdio.h>
​
int main()
{
    struct student{
        long int num;
        char name[20];
        char sex;
        char address[20];
    }a{10101,"Li Hua",'M',"123 Guangxi Road"};  //对结构体变量a赋值 
    printf("No.%ld\nname=:%s\nsex:%c\naddress:%s\n",a.num,a.name,a.sex,a.address);
    return 0;
 } 
 
//输出:
No.10101
name=:Li Hua
sex:M
address:123 Guangxi Road 

11.5结构体数组

一个结构体可以存放一组数据。

定义结构体数组

和定义结构体变量的方法相仿,只需要说明其为数据即可。例如:

struct student{
     int num;        
    char name[20];   
    char sex;       
    int age;         
    float score;     
    char address[30];
};
struct student stu[3]; //定义了一个数组stu,数组有3个元素,均为struct student类型数据。

也可以直接定义一个结构体数组。

struct student{
     int num;        
    char name[20];   
    char sex;       
    int age;         
    float score;     
    char address[30];
}stu[3];
struct{
     int num;        
    char name[20];   
    char sex;       
    int age;         
    float score;     
    char address[30];
}stu[3];

数组各元素在内存中连续存放。

结构体数组的初始化
struct student{
     int num;        
    char name[20];   
    char sex;       
    int age;         
    float score;     
    char address[30];
}stu[3] = {{...},{...},{...}}; //具体内容 这里就不写了

定义数组stu时,元素个数可以不指定,即可以写成以下形式:

stu[] = {{...},{...},{...}};
//或者
struct student stu[] = {{...},{...},{...}}

编译时,系统会根据给出初值的结构体常量的个数来确定数组元素的个数。一个结构体常量包括结构体中全部成员的值。

从以上的例子可以看出,结构体数组初始化的一般形式是在定义数组的后面加上“={初值表列};

这里举一个简单的例子来说明结构体数组的定义和引用。

对候选人得票的统计程序。设有3个候选人,每次输入一个得票的候选人的名字,要求输出最后输出各人得票结果。

#include<stdio.h>
#include<string.h>
​
struct person{
    char name[20];
    int count;
}leader[3] = {{"Li",0},{"Zhang",0},{"Fun",0}};
​
int main()
{
    char leader_name[20];
    printf("请输入你要投票的人的name:(有三人,分别是Li、Zhang、Fun)\n");
    for(int i=1;i<=10;i++)
    {
        printf("第%d票投给:",i); 
        scanf("%s",leader_name);
        for(int j=0;j<3;j++)
        {
            if(strcmp(leader_name,leader[j].name)==0) leader[j].count++;
        }
    }
    printf("\n统计结果如下:\n");
    for(int i=0;i<3;i++)
    {
        printf("%5s:%d\n",leader[i].name,leader[i].count);
    }
    return 0;
 } 

运行结果:

声明:本文章为个人学习笔记,资料整理参考谭浩强《C程序设计(第三版)》如有错误,欢迎大家指正! 

  • 19
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值