C语言:结构

结构的定义

其中结构名可以省略

struct 结构名{

    类型 成员1;

    类型 成员2;

    ...

    类型 成员n;

}

结构体类型定义只描述结构的组织形式,不分配内存

结构体类型定义的作用域与变量的作用域类似,若将类型定义放在某个函数中,则只能在该函数内定义这种结构体类型的变量

typedef struct和sturct定义的区别

typedef struct [结构名] {

}结构体别名;

所以两者的区别是typedef struct是给结构体定义别名,而struct是给结构体定义变量。因为前者使用起来语法更简洁,实际使用更多。

结构体变量的定义

定义结构体相当于定义了二维表的表头,定义结构体变量相当于向表中添加了数据

1. 先定义结构体类型,再定义结构体变量

struct 结构体名 {

    类型标识符 变量名;

    类型标识符 变量名;

    ...

};

struct 结构体名 变量名列表;

#include <stdio.h>

struct student {
	int num;
	char name[20];
	int age;
	float score;
	char addr[30];
}; 

int main(int argc, char *argv[]) { 
	struct student stu1, stu2;
	return 0;
}

2. 定义结构体型同时定义结构体变量

struct 结构体名 {

    类型标识符 成员变量名;

    类型标识符 成员变量名;

    ...

} 变量名列表;

#include <stdio.h>

int main(int argc, char *argv[]) { 
	struct student {
		int num;
		char name[20];
		int age;
		float score;
		char addr[30];
	} stu1, stu2; 
	return 0;
}

3.直接定义结构体变量

因为没有定义结构体名,所以也无法给该结构体再定义结构体变量

struct {

    类型标识符 成员名;

    类型标识符 成员名;

    ...

} 变量名列表;

#include <stdio.h>

int main(int argc, char *argv[]) { 
	struct {
		int num;
		char name[20];
		int age;
		float score;
		char addr[30];
	} stu1, stu2; 
	return 0;
}

结构体类型和结构体变量类型概念理解

结构体类型不分配内存,而变量分配内存

结构体类型不能赋值、存取、运算,而变量可以

结构体类型可以嵌套定义

结构体成员名与程序中变量名可以相同,不会混淆

一个结构体变量所占内存空间是所有成员所占空间之和

结构体变量的初始化

有三种方式定义结构体,所以对应的也有三种方式初始化结构体变量

#include <stdio.h>

int main(int argc, char *argv[]) { 
	struct student {
		int num;
		char name[20];
		int age;
		float score;
		char addr[30];
	};
	struct student stu1 = {1, "xia", 12, 99, "wuhan"};
	return 0;
}
#include <stdio.h>

int main(int argc, char *argv[]) { 
	struct student {
		int num;
		char name[20];
		int age;
		float score;
		char addr[30];
	} stu1 = {1, "xia", 12, 99, "wuhan"};
	return 0;
}
#include <stdio.h>

int main(int argc, char *argv[]) { 
	struct {
		int num;
		char name[20];
		int age;
		float score;
		char addr[30];
	} stu1 = {1, "xia", 12, 99, "wuhan"};
	return 0;
}

结构体空间占用讨论

结构体占用内存空间大小为所有成员变量占用空间大小之和。

所以上面student结构的生成的变量大小为:2 + 20 + 2 + 30 = 54个字节

但是由于在不同的系统中相同的类型占用空间大小可能不一致,所以可以使用sizeof函数来判断当前系统的内存分配规则

sizeof(变量或类型说明符);

 例子:sizeof使用

#include <stdio.h>

int main(int argc, char *argv[]) { 
	char str[20];
	struct date {
		int year, mouth, day;
	} todate;
	struct address {
		char name[30], street[40], city[20], state[2];
		unsigned long int zip;    // unsigned表示无负数
	} wang;
	printf("char: %d\n", sizeof(char));
	printf("int: %d\n", sizeof(int));
	printf("long: %d\n", sizeof(long));
	printf("float: %d\n", sizeof(float));
	printf("double: %d\n", sizeof(double));
	printf("str: %d\n", sizeof(str));
	printf("date: %d\n", sizeof(struct date));
	printf("wang: %d\n", sizeof(wang));
	return 0;
}
/* 打印
char: 1
int: 4
long: 4
float: 4
double: 8
str: 20
date: 12
wang: 96 
*/

例子:结构体变量的定义和访问

#include <stdio.h>

int main(int argc, char *argv[]) { 
	struct {
		char initial;	// 姓 
		int age;	// 年龄 
		int grade;	// 考分 
	} boy, girl;
	boy.initial = 'R';
	boy.age = 17;
	boy.grade = 75;
	girl.initial = 'H';
	girl.age = boy.age - 1;
	girl.grade = 82;
	printf("%c is %d years old and got a grade of %d\n", girl.initial, girl.age, girl.grade);;
	printf("%c is %d years old and got a grade of %d\n", boy.initial, boy.age, boy.grade);
	return 0;
}

结构体数组

数组可以作为结构体的成员,结构体变量也可以组成数组,这就是结构体数组

和结构体定义三种方式相对应,结构体数组也有三种定义方式

struct student {
    int num;
    char name[20];
    char sex;
    int age;
};
struct student stu[2];
struct student {
    int num;
    char name[20];
    char sex;
    int age;
} stu[2];
struct {
    int num;
    char name[20];
    char sex;
    int age;
} stu[2];

结构体数组的初始化

和结构体变量的初始化类似,也有三种方法,分别将多组值用花括号括住一起赋值即可

struct student {
    int num;
    char name[20];
    char sex;
    int age;
};
struct student stu[] = {{100, "wangwu", 'm', 20}
                         {101, "zhaosi", 'm', 21}};

结构体数组的遍历

#include <stdio.h>

struct xscj {	// 学生成绩结构体 
	char xh[100];	// 学号 
	float cj[2];	// 两门课成绩 
	float av;	// 平均分 
};

int main(int argc, char *argv[]) { 
	struct xscj xs[4] = {{"01",70,80}, 
						 {"02",78,67},
						 {"03",56,78},
						 {"04",90,80}};
	int i;
	for (i = 0; i < 4; i++) {
		xs[i].av = (xs[i].cj[0] + xs[i].cj[1]) / 2.0;
		printf("%s, %5.1f, %5.1f, %5.1f\n", 
				xs[i].xh,
				xs[i].cj[0],
				xs[i].cj[1],
				xs[i].av); 
	}
	return 0;
}

结构指针

指向结构体指针就是结构指针

结构指针声明

struct 结构类型名称 *结构指针变量名

struct date *pdate, today;

通过指针访问结构中的成员

结构指针访问成员有一个专门的运算符->

结构指针->成员名

struct date *pdate, today;

pdate = &today;

pdate->year = 2021;    // 相当于 *(pdate).year = 2021

#include <stdio.h>

struct s {
	int x, *y;	// 结构中成员是指向整形的指针 
} *p;	// p是指向结构的指针 

int main(int argc, char *argv[]) { 
	int data[5] = {10,20,30,40,50}; 
	// 结构数组,自动将接受的两个参数组成一个结构体 
	struct s array[5] = {100, &data[0],		
						200, &data[1],
						300, &data[2],
						400, &data[3],
						500, &data[4]};
	p = array;	// 指针p指向指针数组的首地址
	printf("%d\n", p->x); 
	printf("%d\n", (*p).x);	// .运算符优先级比*高,所以才需要括号 
	printf("%d\n", *p->y);	// ->运算符优先级比*高 
	printf("%d\n", *(*p).y);
	printf("%d\n", ++p->x);	// ->运算符优先级比++高 
	return 0;
}

例子:一个类似sql查询的例子

因为一条记录有多种数据类型,比如字符数组、整形、实型,所以需要用结构来表示一条记录,需要用结构数组来表示整个表。

而在排序的时候,可以使用指向结构的指针数组来表示排序后的数据,则在排序过程中,只需要改变指针数组中元素指向,即可实现排序

/*
 用结构表示学生的学号和成绩,编写程序,对班中30名学生
 按成绩进行排序,并输出排序后的学号、成绩和全班平均分 
*/ 
#include <stdio.h>
#define STNUM 5	// 定义宏表示学生数量

struct stuinf {
	int stid;	// 学生学号
	int score;	// 学生成绩 
} stu[STNUM];	// 定义结构体时声明结构数组 

struct stuinf *p[STNUM];	// 声明指向结构的指针的数组 

int main(int argc, char *argv[]) { 
	struct stuinf *ptemp, *p[STNUM];
	int i, j, k, sum=0;
	for (i = 0; i < STNUM; i++) {
		scanf("%d %d", &stu[i].stid, &stu[i].score);	// 为结构数组赋值 
		p[i] = &stu[i];	// 为指向结构的指针数组赋值 
		sum += stu[i].score; 	// 统计总分 
	} 
	for (i = 0; i < STNUM - 1; i++) {
		k = i;	// 记录当前分数最大的指针在p中的位置 
		for (j = i; j < STNUM; j++) {
			if (p[k]->score < p[j]->score)
				k = j;
		}
		if (k != i) {	//  改变指针的值,使其指向当前分数最大的结构 
			ptemp = p[i];
			p[i] = p[k];
			p[k] = ptemp;
		}
	} 
	for (i = 0; i < STNUM; i++) {
		printf("%d, %d\n", p[i]->stid, (*p[i]).score);
	} 
	printf("average score = %d\n", sum / STNUM);
	return 0;
}

结构在函数间传递

1.向函数传递结构的成员和普通的变量的传递一样

2.向函数传递整个结构: 定义函数时声明对应结构的形参

void func(struct xscj tj){...}

3.向函数传递结构的地址:定义函数时声明形参为指向结构的指针

void func(struct xscj *tj){...}

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值