第八章 - 全面讲解c语言中的结构体

一、结构体的理解
  1. 结构体(structure)类型是一种允许程序员把一些数据分量聚合成一个整体的数据类型。
  2. 结构体类型由1个以上称为域(field)的信息项组成,域也可以称为属性(attribute)或成员
二、结构体的基本语法
  1. 结构体的定义:

    struct[结构体类型名]
    { 域定义表 };
    
    具体如下:
    struct 结构名{ 
        类型名  结构成员名1;
        类型名  结构成员名2;
        ...
        类型名  结构成员名n;
    };
    
  2. 结构体变量的初始化

    struct 结构名 结构体变量名 ={值1,值2,值3};
    注意:{}中的各数据需要使用逗号分开,{}中的数据必须和结构体中定义的结构成员顺序、数据类型一致
    
  3. 结构成员变量的访问

    结构体变量名.结构成员名
    
    对字符串类型的成员变量的赋值:strcpy(s1.name, "杨紫");
    
  4. 案例:

    #include<stdio.h>
    
    struct student{    // student为结构体类型名 
    	char no[7];    // 学号,最多6位数字 
    	char name[10]; // 姓名,最多4个汉字
    	char sex[3];   // 性别,汉字中的男女都是2个字节,加上结束标志是3字节 
    	int grade[4];  // 成绩,最后一位可以存储总分 
    }; 
    
    void main(){
    	struct student a = {"202405","张一山","男",{80,89,90}};
    	// 将各科分数计算总数存储在对应位置
    	int i,m;
    	for(i=0,m=0;i<3;i++){
    		m+=a.grade[i];
    	} 
    	a.grade[3]=m;  
    	printf("%-8s%-11s%-5s%-5s%-5s%-5s%-5s\n","学号","姓名","性别","语文","数学","英语","总分");
    	printf("%-8s%-11s%-5s",a.no,a.name,a.sex);
    	for(i=0;i<4;i++){
    		printf("%-5d",a.grade[i]);
    	} 
    } 
    
三、结构体的其他定义方式
  1. 混合定义:定义结构类型的同时定义结构变量

    struct 结构名{ 
        类型名  结构成员名1;
        类型名  结构成员名2;
        ...
        类型名  结构成员名n;
    }结构变量名1,结构变量名2={值1,值2,值3};
    
    案例:
    #include<stdio.h>
    
    struct student{    // student为结构体类型名 
    	char no[7];    // 学号,最多6位数字 
    	char name[10]; // 姓名,最多4个汉字
    	char sex[3];   // 性别,汉字中的男女都是2个字节,加上结束标志是3字节 
    }s1,s2={"202405","张一山","男"}; 
    
    void main(){
    	// 为结构体中的字符串成员赋值需要使用 strcpy 
    	strcpy(s1.no, "202406");
    	strcpy(s1.name, "杨紫");
    	strcpy(s1.sex, "女");
    	printf("%-8s%-11s%-5s\n","学号","姓名","性别","语文","数学","英语","总分");
    	printf("%-8s%-11s%-5s\n",s1.no,s1.name,s1.sex);
    	printf("%-8s%-11s%-5s\n",s2.no,s2.name,s2.sex);
    } 
    
  2. 无类型名定义(匿名的结构体类型)

    typedef struct{ 
        类型名  结构成员名1;
        类型名  结构成员名2;
        ...
        类型名  结构成员名n;
    }结构变量名表;
    
    注意:typedef命令定义的结构体类型使用时,不需要再写 struct
    
    案例:
    #include<stdio.h>
    
    typedef struct{    // student为结构体类型名 
    	char no[7];    // 学号,最多6位数字 
    	char name[10]; // 姓名,最多4个汉字
    	char sex[3];   // 性别,汉字中的男女都是2个字节,加上结束标志是3字节 
    }student; 
    
    void main(){
    	student s={"202405","张一山","男"};
    	printf("%-8s%-11s%-5s\n","学号","姓名","性别","语文","数学","英语","总分");
    	printf("%-8s%-11s%-5s\n",s.no,s.name,s.sex);
    } 
    
  3. 结构体的嵌套定义

    在定义结构成员时所用的数据类型也可以是结构类型,这种定义方式就形成了结构类型的嵌套。
    
    #include<stdio.h>
    
    struct birthday{
    	int year,month,day;// 出生日期的年月日 
    };
    struct student{    
    	char no[7];    // 学号,最多6位数字 
    	char name[10]; // 姓名,最多4个汉字
    	char sex[3];   // 性别,汉字中的男女都是2个字节,加上结束标志是3字节 
    	struct birthday birth; 
    }; 
    void main(){
    	// 为结构体中的字符串成员赋值需要使用 strcpy 
    	struct student s1={"12345","刘亦菲","女",{1990,9,18}};
    	printf("%-8s%-11s%-11s%-11s\n","学号","姓名","性别","生日");
    	printf("%-8s%-11s%-11s%-5d-%-d-%-d\n",s1.no,s1.name,s1.sex,s1.birth.year,s1.birth.month,s1.birth.day);
    } 
    
四、结构变量的使用
  1. 结构变量之间相互赋值

    (1) 同类型的两个结构变量之间可以相互赋值
        
    (2) 案例:
         #include<stdio.h>
    
    struct birthday{
    	int year,month,day;// 出生日期的年月日 
    };
    struct student{    
    	char no[7];    // 学号,最多6位数字 
    	char name[10]; // 姓名,最多4个汉字
    	char sex[3];   // 性别,汉字中的男女都是2个字节,加上结束标志是3字节 
    	struct birthday birth; 
    }; 
    void main(){
    	// 为结构体中的字符串成员赋值需要使用 strcpy 
    	struct student s2={"12345","刘亦菲","女",{1990,9,18}};
    	struct student s1=s2; // 同类型的结构体变量之间相互赋值
    	printf("%-8s%-11s%-11s%-11s\n","学号","姓名","性别","生日");
    	printf("%-8s%-11s%-11s%-5d-%-d-%-			
    	d\n",s1.no,s1.name,s1.sex,s1.birth.year,s1.birth.month,s1.birth.day);
    }
    
  2. 结构变量可以作为函数的参数进行传递

    #include<stdio.h>
    
    struct birthday{
    	int year,month,day;// 出生日期的年月日 
    };
    struct student{    
    	char no[7];    // 学号,最多6位数字 
    	char name[10]; // 姓名,最多4个汉字
    	char sex[3];   // 性别,汉字中的男女都是2个字节,加上结束标志是3字节 
    	struct birthday birth; 
    }; 
    void main(){
    	// 为结构体中的字符串成员赋值需要使用 strcpy 
    	struct student s2={"12345","刘亦菲","女",{1990,9,18}};
    	testStudent(s2);
    } 
    // 结构变量作为函数的参数
    void testStudent(struct student s1){
    	printf("%-8s%-11s%-11s%-11s\n","学号","姓名","性别","生日");
    	printf("%-8s%-11s%-11s%-5d-%-d-%-d\n",s1.no,s1.name,s1.sex,s1.birth.year,s1.birth.month,s1.birth.day);
    }
    
  3. 结构变量可以作为函数的返回值进行返回

    #include<stdio.h>
    struct student{    
    	char no[7];    // 学号,最多6位数字 
    	char name[10]; // 姓名,最多4个汉字
    	char sex[3];   // 性别,汉字中的男女都是2个字节,加上结束标志是3字节 
    }; 
    
    struct student getStudent(){
    	struct student s={"12345","刘亦菲","女"};
    	return s;
    }
    
    void main(){
    	struct student s=getStudent();
    	printf("%-8s%-11s%-11s\n","学号","姓名","性别");
    	printf("%-8s%-11s%-5s\n",s.no,s.name,s.sex);
    } 
    
  4. 结构变量可以应用在数组上:

    #include<stdio.h>
    
    struct student{    // student为结构体类型名 
    	char no[7];    // 学号,最多6位数字 
    	char name[10]; // 姓名,最多4个汉字
    	char sex[3];   // 性别,汉字中的男女都是2个字节,加上结束标志是3字节 
    }; 
    
    void main(){
    	// 为结构体中的字符串成员赋值需要使用 strcpy 
    	struct student stus[3]={
    		{"202405","张一山","男"},
    		{"202406","刘亦菲","女"},
    		{"202407","檀健次","男"}
    	};
    	int i;
    	printf("%-8s%-11s%-5s\n","学号","姓名","性别");
    	for(i=0;i<3;i++){	
    		printf("%-8s%-11s%-5s\n",stus[i].no,stus[i].name,stus[i].sex);
    	}	
    }
    
五、结构指针
  1. 理解:结构指针就是指向结构类型变量的指针

  2. 语法:

    (1) struct  结构体名  *结构指针名;
    (2) 案例:struct  student *p;
    (3) 结构指针的值实际上存储的是结构变量的首地址
    
  3. 使用:利用结构指针访问它所指向的结构变量中的各个成员

    (1) 第一种形式:用 *p 访问结构成员,(*结构指针).成员名
        a. 案例: (*p).num = 100;
        b. 注意:(*p)中的括号是不可少的,因为成员运算符 . 的优先级高于 "*"
    (2) 第二种形式:用指向运算符 -> 访问指针指向的结构成员
        a. 案例: p -> num = 100
        b. 注意:使用结构指针访问结构成员时,通常使用指向运算符 -> 
    
    #include<stdio.h>
    
    struct student{    // student为结构体类型名 
    	char no[7];    // 学号,最多6位数字 
    	char name[10]; // 姓名,最多4个汉字
    	char sex[3];   // 性别,汉字中的男女都是2个字节,加上结束标志是3字节 
    }; 
    void main(){
    	struct student s={"202405","张一山","男"},*p;
    	p=&s;
    	
    	printf("%-8s%-11s%-5s\n","学号","姓名","性别","语文","数学","英语","总分");
    	printf("%-8s%-11s%-5s\n",(*p).no,p->name,p->sex);
    } 
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值