C语言学习笔记之结构体

主题:C语言
时间:2021年1月6日
作者:ybb
参考: C语言

10.3 C语言结构体指针

定义:当一个指针变量指向结构体时,我们就称它为结构体指针(指针变量指向的是结构体)
一般结构:struct 结构体标签名 *变量名
struct stu *pstu=&stu1;

注:结构体变量名和数组名不同,数组名在表达式中会被转换成指针,而结构体变量名不会,它时钟表示的是整个集合本身,要想取得结构体变量的地址,就需要用&

还应该注意,结构体和结构体变量是两个不同的概念:结构体是一种数据类型,是一种创建变量的模板,编译器不会为它分配内存空间,就像 int、float、char 这些关键字本身不占用内存一样;结构体变量才包含实实在在的数据,才需要内存来存储。下面的写法是错误的,不可能去取一个结构体名的地址,也不能将它赋值给其他变量:

struct stu *pstu = &stu;
struct stu *pstu = stu;

获取结构体成员采用:
(*pointer).Member
p->Member
注:结构体成员访问运算符.
结构体指针成员访问运算符

结构体数组指针的使用:

#include<stdio.h>
#include<stdlib.h>

struct stu
{
	char *name;
	int age;
	float score;
}
stus[] = {
	{"ybb",24,99.8},{"ld",25,88.9},{"zds",26,99.9}
}, *ps;

int main()
{
	int len;
	len = sizeof(stus) / sizeof(struct stu);

	printf("name\tage\tscore\t\n");
	for (ps = stus; ps <stus + len; ps++)//这个语句是什么意思???
	{
		printf("%s\t%d\t%.2f\t\n", ps->name, ps->age, ps->score);
	}
	return 0;
}

10.4 CC语言枚举类型(enum的使用)

先用最简单的宏定义实现:define A with B

#include<stdio.h>
#include<stdlib.h>

#define mon 1
#define tue 2
#define wed 3

int main()
{
	int day;
	scanf_s("%d",&day);
	switch (day)
	{
	default:printf("error");
		break;
	case mon:
		printf("monday");
		break;
	case tue:
		printf("tuesday");
		break;
	case wed:
		{
			printf("wednesday");
			break;
		}
	}
	return 0;

}

不拿发现,如果数量很多就很麻烦,而且数字的增长是有规律的,可以考虑利用enum实现。

printf()与puts()
scanf()与gets()

那么就来学习一下enum的使用:

enum 枚举类型名 {value1name,value2name} a,b,c;
枚举是一种类型,通过它可以定义枚举变量:
enum week a,b,c;

#include<stdio.h>
#include<stdlib.h>

int main()
{
	enum week
	{
		mon=1,tue,wed
	}day;
	scanf_s("%d",&day);
	switch (day)
	{
	default:printf("error\n");
		break;
	case mon:
		printf("monday");
		break;
	case tue:
		printf("tuesday");
		break;
	case wed:
		printf("wednesday");
		break;
	}
	return 0;
}

需要注意的两点是:

  1. 枚举列表中的 Mon、Tues、Wed 这些标识符的作用范围是全局的(严格来说是 main()
    函数内部),不能再定义与它们名字相同的变量。

  2. Mon、Tues、Wed 等都是常量,不能对它们赋值,只能将它们的值赋给其他的变量。

宏定义在预处理阶段将名字替换成对应的值;
枚举在编译阶段将名字替换成对应的值;
因此枚举可以理解为发生在编译阶段的宏。

case 关键字后面必须是一个整数,或者是结果为整数的表达式,但不能包含任何变量

谈到C语言最关键的指针、数组、结构体与内存管理,C语言执行的高效性需要对内存管理深入学习,这样才可以掌握C语言的精髓。

10.5 C语言共用体

结构体与共用体的区别:
结构体的各个成员占据不同的内存,当然为了内存对齐加快寻址效率,各个成员占据长度相同的内存空间;
共用体的所有成员占据同一段内存,修改其中的一个会影响其他的成员。

10.6 大端小端及判别方式

大端和小端是指数据在内存中的存储模式,它由 CPU 决定:

  1. 大端模式(Big-endian)是指将数据的低位(比如 1234 中的 34 就是低位)放在内存的高地址上,而数据的高位(比如 1234 中的 12 就是高位)放在内存的低地址上。这种存储模式有点儿类似于把数据当作字符串顺序处理,地址由小到大增加,而数据从高位往低位存放。

  2. 小端模式(Little-endian)是指将数据的低位放在内存的低地址上,而数据的高位放在内存的高地址上。这种存储模式将地址的高低和数据的大小结合起来,高地址存放数值较大的部分,低地址存放数值较小的部分,这和我们的思维习惯是一致,比较容易理解。

PC 机上使用的是 X86 结构的 CPU,它是小端模式(正常模式)
很多 ARM、DSP 也是小端模式(部分 ARM 处理器还可以由硬件来选择是大端模式还是小端模式)
51 单片机大端模式

10.7 C语言位域

C语言标准规定,位域的宽度不能超过它所依附的数据类型的长度。通俗地讲,成员变量都是有类型的,这个类型限制了成员变量的最大长度,:后面的数字不能超过这个长度

原则:超出部分被直接截去
结构体使用的不熟练,需要加强。
那些是数据类型、那些是变量、如何分开定义、如何在声明的时候就定义,这些都是需要掌握的。

什么是位域:
位域技术就是在成员变量所占用的内存中选出一部分位宽来存储数据。

我们发现位域成员往往不占用完整的字节,有时候也不处于字节的开头位置,因此使用&获取位域成员的地址是没有意义的,C语言也禁止这样做。地址是字节(Byte)的编号,而不是位(Bit)的编号。

无名位域:
无名位域一般用来作填充或者调整成员位置。因为没有名称,无名位域不能使用。

10.8 C语言位运算

C语言的六种位运算符;
C语言的六种位运算符
区分逻辑运算符与位运算符
区分原码 反码 补码
注:&是根据内存中的二进制位进行运算的,而不是数据的二进制形式。
再强调一遍,&是根据内存中的二进制位进行运算的,而不是数据的二进制形式;其他位运算符也一样。以-9&5为例,-9 的在内存中的存储和 -9 的二进制形式截然不同:
1111 1111 – 1111 1111 – 1111 1111 – 1111 0111 (-9 在内存中的存储)
-0000 0000 – 0000 0000 – 0000 0000 – 0000 1001 (-9 的二进制形式,前面多余的 0 可以抹掉)

  1. 整数在内存中是如何存储的?
  2. 小数在内存中是如何存储的?
  3. 正数和负数在内存中是如何存储的?
  4. 复数在内存中是如何存储的?
  5. 数据在内存中的存储方式?

10.9 使用位运算对数据进行加密

通过一次异或运算,生成密文,密文没有可读性,与原文风马牛不相及,这就是加密;
密文再经过一次异或运算,就会还原成原文,这就是解密的过程;
加密和解密需要相同的密钥,如果密钥不对,是无法成功解密的。

如果加密和解密的密钥不同,则称为非对称加密算法。在非对称算法中,加密的密钥称为公钥,解密的密钥称为私钥,只知道公钥是无法解密的,还必须知道私钥。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言中,计算一个结构体占用多大的内存可以根据以下规则进行计算。首先,结构体的大小是其成员变量所占内存大小的总和,但是要注意对齐规则。结构体内存对齐的基本原则是,结构体的起始地址要对齐到其最宽的成员变量的大小的倍数。也就是说,结构体的起始地址要能够同时满足所有成员变量的对齐要求。 例如,如果有一个结构体`struct example`,其中包含了不同类型的成员变量,比如`int`、`char`和`double`,那么根据对齐规则,编译器会在不同类型的成员变量之间插入一些空白字节,以满足对齐要求。 具体的对齐规则可能因编译器和操作系统的不同而有所差异,但通常情况下,对齐要求是按照成员变量的大小来确定的。比如,`char`类型一般对齐要求为1字节,`int`类型一般对齐要求为4字节,`double`类型一般对齐要求为8字节。 因此,计算结构体的内存大小时,需要按照对齐规则,将每个成员变量的大小上取整到其对齐要求的倍数,然后将这些大小相加。最后得到的结果就是结构体的大小。 需要注意的是,在某些情况下,可以通过使用`#pragma pack`指令来改变对齐规则。比如,`#pragma pack(4)`可以将对齐要求设置为4字节。但是在嵌入式开发中,为了节约内存使用,可能需要手动设置对齐规则。 总结起来,计算C语言结构体的内存大小,可以按照以下步骤进行: 1. 根据对齐规则,确定每个成员变量的对齐要求。 2. 将每个成员变量的大小上取整到其对齐要求的倍数。 3. 将这些大小相加,得到结构体的大小。 参考资料: C语言学习笔记-结构体占用内存大小的计算 结构体内存对其计算结构体大小 C语言数据类型占内存大小

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值