嘉明的C学习之Day13--结构体与结构体指针

递归的作业讲解

假如有n个台阶,一次只能上1个台阶或2个台阶,请问走到第n个台阶有几种走法?为便于读者理解题意,这里举例说明如下:假如有3个台阶,那么总计就有3种走法:第一种为每次上1个台阶,上3次;第二种为先上2个台阶,再上1个台阶;第三种为先上1个台阶,再上2个台阶。输入为n,输出为走到第n个台阶有几种走法
思路:
1层台阶 1种走法 (1)
2层台阶 2种走法 (11 2)
3层台阶 3种走法 (111 12 21)
4层台阶 5种走法 (1111 22 112 211 121)
因为我们一次只可以走两层或者一层,所以就有一层和两层混合的走法
得出step(n)=step(n - 1)+step(n - 2)

#include<stdio.h>
//函数自己调用自己就是递归
int step(int n) {
	if (1 == n) {
		return 1;
	}
	if (2 == n) {
		return 2;
	}
	return  step(n - 1)+step(n - 2);//递归
}
int main() {
	int n;
	scanf("%d", &n);
	int ret = step(n);
	printf("%d\n",ret);
}

在这里插入图片描述

结构体与结构体指针

结构体的定义

C语言结构体(Struct)从本质上讲是一种自定义的数据类型,只不过这种数据类型比较复杂,是由 int、char、float 等基本类型组成的。你可以认为结构体是一种聚合类型。

在实际开发中,我们可以将一组类型不同的、但是用来描述同一件事物的变量放到结构体中。例如,在校学生有姓名、年龄、身高、成绩等属性,学了结构体后,我们就不需要再定义多个变量了,将它们都放到结构体中即可。

下面我们写一段程序,来让大家理解一下结构体。

#include<stdio.h>

struct student {
	int num;
	char name[20];
	char sex;
	int age;
	float score;
	char addr[30];
};//一定要加分号

int main() {
	struct student s = { 1001,"XiaoMing",'M',18,99.5,"Guangzhou"};
	printf("%d,%s,%c,%d,%5.2f,%s", s.num, s.name,s.sex,s.age,s.score,s.addr);
	return 0;
}

需要注意的点:
1.结构体始定义在方法外的,定义结束时一定要加分号。
2.使用结构体的时候需要为给一个变量名,然后变量名.元素(注意:.是一个运算符)。访问结构体特定的元素。
在这里插入图片描述
输出结果如下:
在这里插入图片描述

那么问题来了?这个结构体所占的字节大小是多少
在这里插入图片描述
按照上面的图片算的化是占63个字节,有的人就会说:“都算出来了还看啥。”我只能说格局小了

接下来我们看看监视,显示的是68个字节
在这里插入图片描述
再看看内存,我们不难发现刚好是显色区域的数量17行一行4列 17*4=68。
在这里插入图片描述
那为什么会多出来的如下图的5个字节呢?
在这里插入图片描述
解答:
其实多出来的5个字节就是为了为了加快数据传输的效率
结构体这样是比较特殊的,因为我们的现在使用的是32位就是一次可以接收8个字节的数据。
结构体内的数据都是以8个字节为一组(如果64位的话就是16个字节为一组)传输的。所以像char这种占一个字节的,后面的cc cc cc也会传跟char组成4个字节一并传输。其目的就是为了加快传输效率

结构体数组

既然我们定义了一个结构体,如果这个结构体只能存储一条数组那不是很累赘吗?比如你班里有48人。有一张统计表,但是只有一个填写位置只能填一名同学的信息,那岂不是没意义
所以结构体数组就它就来了,具体的定义如下
输入
1001 XiaoMing M 18 99.5 Guangzhou
1002 XiaoLi F 20 95.5 BeiJing
1003 XiaoHong M 19 90.5 ShangHai

#include<stdio.h>
//
struct student {
	int num;
	char name[20];
	char sex;
	int age;
	float score;
	char addr[30];//一定要加分号
};

int main() {
	struct student s = { 1001,"XiaoMing",'M',18,99.5,"Guangzhou"};
	printf("%d,%s,%c,%d,%5.2f,%s\n", s.num, s.name, s.sex, s.age, s.score, s.addr);
	//定义结构体数组
	struct student sarry[3];
	int i;
	printf("输入:\n");
	for (i = 0; i < 3; i++) {
		scanf("%d %s %c %d %f %s", &sarry[i].num, &sarry[i].name, &sarry[i].sex, &sarry[i].age, &sarry[i].score, &sarry[i].addr);
	}
	printf("输出:\n");
	for (i = 0; i < 3; i++) {
		printf("%d %s %c %d %f %s\n", sarry[i].num, sarry[i].name, sarry[i].sex, sarry[i].age, sarry[i].score, sarry[i].addr);
	}
	return 0;
}

在这里插入图片描述

结构体指针

结构体指针的使用

结构体也有指针变量,下面就让我们写一段程序来了解一下
利用指针输出结构体元素的方式
有两种。
在这里插入图片描述
对象就是✳p
指针就是p

#include<stdio.h>
struct student {
	int num;
	char name[20];
	char sex;
};//一定要加分号

int main() {
	struct student s = { 1001,"XiaoMing",'M'};
	//定义结构体指针
	struct student* p;
	p = &s;//指针指向s
	printf("指针指向s的输出方式一:num=%d,name=%s,sex=%c\n", (*p).num, (*p).name, (*p).sex);
	printf("\n指针指向s的输出方式二:num=%d,name=%s,sex=%c\n", p->num,p->name,p->sex);
	return 0;
}

它们的输出结果都是一样的。
在这里插入图片描述

结构体指针的偏移

接下来我们看下面这个程序猜一下结果

#include<stdio.h>
struct student {
	int num;
	char name[20];
	char sex;
};//一定要加分号

int main() {
	//定义结构体数组
	struct student sarry[3] = { 1001,"XiaoMing",'M',1005,"XiaoLi",'F',1006,"XiaoHong",'M'};//直接按照个数赋值即可
	//定义结构体指针
	struct student* p;
	p = sarry;//指针指向s
	int num;

	num = p->num++;//拆分为num=p->num;p->num=(p->num)+1,因为->优先级比++高,所以要把p->num算上
	printf("num=%d,p->num=%d\n", num,p->num);
	num = p++->num;//拆分为num=p->num;p=p+1,因为++是右到左顺序运算的
	printf("num=%d,p->num=%d\n", num, p->num);
	return 0;
}

在这里插入图片描述
过程分析:
num = p->num++;
拆分为num=p->num;p->num=(p->num)+1,因为->优先级比++高,所以要把p->num算上
因此num=p->num就是1001
p->num=(p->num)+1就是1002
所以第一次输出的是1001 1002。

num = p+±>num;
拆分为num=p->num;p=p+1,因为++是右到左顺序运算的
因为上面的p->num被重新赋值成了1002所以num=p->num为1002
p=p+1指针向右偏移指向sarry[1].num值为1005
所以第二次的输出是1002 1005。

其实主要就是看++左边的运算符谁的运算符优先级高,比++高就带上优先级高的运算符一起。平级或者低就不用带上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值