C语言结构体(struct)一些常见问题 ⎛⎝≥⏝⏝≤⎛⎝

本文详细介绍了C语言中的结构体,包括结构体的定义与初始化、内存分配和字节大小计算、结构体指针的使用及结构体变量与指针的区别。通过实例解析了结构体指针的访问方式以及运算顺序,帮助读者深入理解结构体在C语言中的应用。
摘要由CSDN通过智能技术生成

文章目录

1、结构体的定义以及初始化

①定义结构体

 ②对结构体变量进行初始化

2、结构体在内存中的分配以及字节大小

①存储空间如何分配?

 ②结构体所占字节大小如何计算?

3、结构体指针和结构体变量的区别

①结构体指针如何进行访问?

 ②结构体指针和结构体变量的区别

4、易搞混的结构体指针运算顺序举例


1、结构体的定义以及初始化

①定义结构体

首先简单定义一个结构体:

struct point {
	int x;
	int y;
};
//当然你可以写成struct point{int x; int y;}; 都是一样的,缩进不同罢了

以上代码中,关键字 struct 引入结构声明,结构声明由包含在花括号内的一系列声明组成。

struct后面的名字是可选的,被称为 结构标记 (这里是point)。 结构标记用于为结构命名,在定义之后,结构标记就代表花括号内的声明,可以用它作为该声明的简写形式。比如在后面定义结构体变量的时候,就可以写成:

struct point pt;     //定义了一个结构体变量pt

如果你不想使用结构标记,那么定义变量时你需要把花括号内的声明也写上,写成:

struct{
	int x;
	int y;
}pt;
//当然你可以写成struct{int x; int y;}pt; 都是一样的,缩进不同罢了

 ②对结构体变量进行初始化

 接下来对结构体变量进行初始化,比如将x赋值为10,y赋值为20:

struct{
	int x = 10;
	int y = 20;
}pt;

也可以这样写:

struct point pt = {10, 20};

2、结构体在内存中的分配以及字节大小

①存储空间如何分配?

当你定义了一个结构体,且未定义结构体变量时:

struct{
	int x;
	int y;
};

则不需要为它分配存储空间,因为它仅仅描述了一个结构的模板或轮廓。结构体变量才包含了实实在在的数据、需要存储空间。

像下面那样,其中的 struct point pt 就表示声明了一个结构体变量: 

 ②结构体所占字节大小如何计算?

关于结构体所占的字节大小,需要注意,千万不要认为结构体的长度等于各成员长度的和,因为不同的对象有不同的对齐要求(可以查下关于字节对齐的资料,这里不展开),因此,结构中可能会出现未命名的“空穴”(hole)。例如以下代码:

#include<stdio.h>

struct point
{
	char x;   //char占1个字节
	int y;    //int占4个字节
};

int main() {
	struct point pt;
	printf("%d", sizeof pt); //输出8而不是5
	return 0;
}

这里的存储空间需要8个字节而不是5个。

3、结构体指针和结构体变量的区别

①结构体指针如何进行访问?

如果传递给函数的结构很大,使用指针方式的效率通常比复制整个结构的效率要高。结构体指针类似于普通变量指针:

struct point *pp

以上一句,将pp定义为一个指向struct point类型对象的指针,注意上述定义只说明了pp指针指向的对象类型是struct point类型,并未指向point这个结构,所以还访问不了point结构里的成员。那么想要正确访问point中的成员,得记得让指针指向point结构,比如下面这样:

#include<stdio.h>

struct point
{
	int x = 10;
	int y = 20;
};

int main() {
	struct point pt;  //声明一个结构体变量
	struct point *pp;	//声明一个结构体指针
	pp = &pt;   //让指针指向point结构,这样才能进行后续对结构体成员的访问
	printf("%d", (*pp).x);  //输出10

	return 0;
}

下面来解释下访问方式 (*pp).x ,其中圆括号是必需的,因为结构成员运算符“.”的优先级比“*”的优先级高,表达式*pp.x的含义等价于*(pp.x),因为x不是指针,所以该表达式是非法的。

当然还有其它访问方式,如下:

//p->结构成员
printf("%d", pp->x);  //输出10

②结构体指针和结构体变量的区别

现在来说下结构体指针和结构体变量的区别:

1.内存空间上面的差别

假设有如下代码:

struct Stu
{
    int age;
}*p, q;

结构体指针p是指向一个结构体的,如果需要使用这个结构体就必须malloc一个空间出来或者将一个具有空间的结构体的首地址赋予它;如果你不给它分配空间代表这是一个野指针,访问的时候会出错;而结构体变量q,在定义变量的时候,编译器就自动给变量分配了合适的储存空间。

2.访问上的差别
结构体指针访问成员变量的操作符是 “->”,结构体变量访问成员变量的操作符是“.”
指针想用“.”操作符,得写成(*p).age <=> p->age;

4、易搞混的结构体指针运算顺序举例

比如以下代码,重点关注下其中的 ++pp->x 的输出:

#include<stdio.h>

struct point
{
	int x = 10;
	int y = 20;
} *pp;

int main() {
	struct point pt;
	pp = &pt;
	printf("%d", ++pp->x);  //输出11

	return 0;
}

表达式

++pp->x;

将增加x的值,而不是增加pp的值,这是因为,“->”的优先级比自增“++”更高!所以这里的隐含关系相当于++(pp->x)

补充一张运算符优先级参考截图(1级比2级先执行):

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值