C语言 结构体的使用

#include <stdio.h>
#include <string.h>

#define NUMBER 5
#define NAME_LEN 64

void swap_int (int *x, int *y){
	int temp = *x;
	*x = *y;
	*y = temp;
} 

void swap_str(char *sx, char *sy){
	char temp[NAME_LEN];
	
	strcpy(temp, sx);
	strcpy(sx, sy);
	strcpy(sy, temp);
}

void sort(int num[],char str[][NAME_LEN], int n){
	int i, j;
	
	for(i = 0; i < n - 1; i++){
		for(j = n - 1; j > i; j--){
			if (num[j - 1] > num[j]){
				swap_int(&num[j - 1], & num[j]);
				swap_str(str[j - 1], str[j]);
			}
		}
	}
}

int main(void){
	int i;
	int height[] = {178, 175, 170, 165, 189};
	char name[][NAME_LEN] = {"陈二", "张三", "李四", "王五", "赵六"};
	
	for(i = 0; i < NUMBER; i++){
		printf("%2d : %-8s%4d\n", i + 1, name[i], height[i]);
	}
	
	sort(height, name, NUMBER);
	
	puts("\n按身高进行升序排列。");
	
	for(i = 0; i < NUMBER; i++){
		printf("%2d : %-8s%4d\n", i + 1, name[i], height[i]);
	}
	
	return 0;
}

运行结果:
在这里插入图片描述

使用结构体简化代码:

#include <stdio.h>
#include <string.h>

#define NUMBER 5
#define NAME_LEN 64

typedef struct {
	char name[NAME_LEN];
	int height;
	float weight;
	long score; 
} Student;

void swap_Student (Student *x, Student *y){
	Student temp = *x;
	*x = *y;
	*y = temp;
} 


void sort_by_height(Student a[], int n){
	int i, j;
	
	for(i = 0; i < n - 1; i++){
		for(j = n - 1; j > i; j--){
			if (a[j - 1].height > a[j].height){
				swap_Student (&a[j - 1], &a[j]);
			}
		}
	}
}

int main(void){
	int i;
	
	Student std[] = {
		{"陈二", 178, 61.2, 80},
		{"张三", 175, 62.5, 73},
		{"李四", 170, 86.2, 60},
		{"王五", 165, 72.2, 99},
		{"赵六", 189, 77.5, 100},
	}; 
		
	puts("姓名        身高  体重  分数"); 
	for(i = 0; i < NUMBER; i++){
		printf("%-8s %6d %6.1f %5ld\n", std[i].name, std[i].height, std[i].weight, std[i].score);
	}
	
	sort_by_height(std, NUMBER);
	
	puts("\n按身高进行升序排列。");
	puts("姓名        身高  体重   分数"); 
	for(i = 0; i < NUMBER; i++){
		printf("%-8s %6d %6.1f %5ld\n", std[i].name, std[i].height, std[i].weight, std[i].score);
	}
	
	return 0;
}

运行结果
在这里插入图片描述
注:

  • 可以使用 typedef 声明为结构体赋上简洁的 typedef 名。
  • Student 为结构名。
  • {}中声明的 name、height、weight、schols等成为结构体成员。
  • 访问结构体对象的各个成员时使用 . 运算符,该运算符称为句点运算符。
    例如:
    a . b 表示结构体 a 的成员 b (对象名 . 成员名)
结构体的命名空间

只要命名空间不同,就可以使用拼写相同的标识符(名字)。命名空间的分类有以下四种。

  1. (标签)名
  2. 小标签 名
  3. 成员 名
  4. 一般性标识符
int main(void){
	struct x {    // 小标签名
		int x;    // 成员名
		int y;
	} x;          // 变量名
x:                // 标签名
	x.x = 1;      // 变量名.成员名
	x.y = 2;      // 变量名.成员名

	return 0;
}

注:
只要不属于同一个命名空间,即使在同一有效范围内使用相同的名字,也不会产生任何问题。


typedef struct {
	char name[NAME_LEN];
	int height;
	float weight;
	long schols; 
} Student;

上述结构体可以写成如下形式:

struct student{
	char name[NAME_LEN];
	int height;
	float weight;
	long schols; 
};

该结构体形式的使用:

#include <stdio.h>
#include <string.h>

#define NAME_LEN 64

struct students {
	char name[NAME_LEN];
	int height;
	float weight;
	long score; 
}; 

int main(void){
	struct students stu;
	
	strcpy(stu.name, "vvcat");  // 直接复制会报错
	stu.height = 175;
	stu.weight = 62.5;
	stu.score = 88;
	
	printf("姓名 = %s\n", stu.name);  
	printf("身高 = %d\n", stu.height);  
	printf("体重 = %.1f\n", stu.weight);  
	printf("分数= %ld\n", stu.score);  
	
	return 0; 
}

运行结果:
在这里插入图片描述

strcpy(stu.name, "vvcat");  // 直接赋值会报错

如果写成

stu.name = "vvcat"; //初始化错误

相当于

char str[5];
str = "vvcat"; // 初始化错误

初始化也可以进行简写:

	struct students stu;
	strcpy(stu.name, "vvcat");  // 直接复制会报错
	stu.height = 175;
	stu.weight = 62.5;
	stu.score = 88;

简写方式:

struct students stu = { "vvcat", 175, 62.5, 88};

这样一行就完成了多行的代码赋值操作,使代码更加简洁。

如果不对结构体进行初始化:

#include <stdio.h>
#include <string.h>

#define NAME_LEN 64

struct students {
	char name[NAME_LEN];
	int height;
	float weight;
	long score; 
}; 

int main(void){
	struct students stu = { "vvcat", 175};
	
	printf("姓名 = %s\n", stu.name);  
	printf("身高 = %d\n", stu.height);  
	printf("体重 = %.1f\n", stu.weight);  
	printf("分数= %ld\n", stu.score);  
	
	return 0; 
}

运行结果:
在这里插入图片描述

注:
结构体对象 o 中的成员 m 可以通过o.m来访问。
声明结构体时所赋的初始值的形式是,将各个结构体成员的初始值依次排列在{}里面,并用逗号分割。未赋初始值的成员被初始化为0。

结构体成员和 -> 运算符
#include <stdio.h>

#define NAME_LEN 64

struct student{
	char name[NAME_LEN];
	int height;
	float weight;
	long score;
};

void update_height_weight(struct student *std){
	if((*std).height < 180){
	 	(*std).height = 180;
	 } 
	if((*std).weight > 80){
		(*std).weight = 80;
	} 
}

void update_score(struct student *std){
	if(std -> score < 90){
	 	std -> score = 90;
	 } 
}

int main(void){
	struct student stu = {"vvcat", 175, 62.5, 89};
	
	update_height_weight(&stu);
	update_score(&stu);
	
	printf("姓名 = %s\n", stu.name);  
	printf("身高 = %d\n", stu.height);  
	printf("体重 = %.1f\n", stu.weight);  
	printf("分数 = %ld\n", stu.score);  
	
	return 0; 
}

运行结果:
在这里插入图片描述

在函数中,身高和体重可以通过以下表达式来访问。

(*std).height
(*std).weight

也可以通过 -> 运算符进行访问

std -> height
std -> weight

在指针变量前加上指针运算符*,就表示该指针指向的对象实体。通过(*std).height 或 std -> height 等表达式可以表示std 指向的对象的成员。

注:

  • 不能用 *std.height来表示 *std的身高成员。因为 . 运算符的优先级比指针运算符 * 高,表达式会被解释成 *(std .height),产生语法错误。
  • -> 运算符 a->b
    用指针访问结构体a 中的成员b。 -> 称为箭头运算符。
  • 在表示指针 p 指向的结构体成员 m 时,推荐使用 -> 运算符将(*p)**.**m 简写为 p->m。
  • . 运算符和 ->运算符统称为访问运算符。
返回结构体的函数
#include <stdio.h>

struct xyz{
	int x;
	long y;
	double z;
};

struct xyz xyz_of(int x, long y ,double z){
	struct xyz temp;
	
	temp.x = x;
	temp.y = y;
	temp.z = z;
	
	return temp;  // 将结构体返回
}

int main(void){
	struct xyz s ={0, 0, 0}; // 结构体初始化
	
	s = xyz_of(123, 123456, 12.34);   // 为结构体赋值
	
	printf("xyz.x = %d\n", s.x);
	printf("xyz.y = %ld\n", s.y);
	printf("xyz.z = %f\n", s.z);
	
	return 0;
}

数组和结构体在处理多个对象的集合方面具有诸多相同点,他们统称为聚合类型。

  • 元素类型:
    数组用于高效地操作“相同类型”数据的集合。二结构体这种数据结构通常用于高效地操作“不同类型”数据的集合(偶尔会有成员类型全部相同的情况)。
  • 可否赋值
    两个数组的元素个数相同,也不能相互赋值。但是,相同类型的结构体可以相互赋值。
int a[5], b[5];
a = b; // 赋值错误
struct student x, y;
x = y; // 赋值成功
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值