C语言结构体基础知识

  • Post author:
  • Post category:其他




一、什么是结构体?

结构体相当于一个类型,先在主函数前定义,之后才可使用此类型。

结构是一些值的集合,这些值成为成员变量。结构的每个成员可以是不同类型的变量。

结构体成员可以是 [标量(普通变量)、数组、指针、甚至是其他结构体]



二、结构体类型的声明



结构体声明格式

声明结构体类型的格式如下:

struct tag    //struct:结构体关键字  tag:结构体标签    struct tag:结构体类型
{
	member - list;//成员列表;
}variable - list;//变量列表;(在这里可以创建全局变量)但是写代码尽量不用全局变量

下面我们用具体例子来展示结构体类型声明:

e.g. 描述一个学生 – 一些数据

名字

年龄

电话

性别

//定义一个结构体类型(不占用空间)
struct stu   // struct-结构体关键字   stu-结构体标签   struct stu-新创建的结构体类型
{
	char name[20];//字符串,用于存汉字
	int age;
	char tele[12];//11位电话号+'\0'
	char sex[5];
}s1,s2,s3;    //s1,s2,s3;是三个[全局]的结构体变量
//结构体的[声明]是一条语句,结尾要加[;]

int main()
{
	struct stu s;//创建结构体变量(向内存申请了空间)
	return 0;
}



结构体的typedef

原本结构体类型名称太长,可以用typedef定义类型名字, typedef放开头 , 新名字放结尾分号前

(虽然定义了新名字但是原本的名字还是可以使用哦)

typedef struct stu
{
	char name[20];
	int age;
	char tele[12];
	char sex[5];
}stu;//新变量名

int main()
{
	stu s1;
	struct stu s2;
	return 0;
}



三、结构体变量的定义和初始化

定义结构体时,我们可以像定义数组那样,在花括号中用逗号隔开每个成员,为对应位置的成员赋值(对成员进行初始化操作)。

结构体的定义方法如下:

typedef struct stu
{
	char name[20];
	int age;
	char tele[12];
	char sex[5];
}stu1;

int main()
{
	struct stu s1 = { "张三",18,"11451419198","男" };
	stu1 s2 = { "李四",19,"14544191981","女" };
	return 0;
}



注:结构体类型里也可以包含结构体类型

具体例子如下

struct a
{
	int i;
	int j;
	char a[14];
};

struct b
{
	int num;
	struct a s;
	char* p;
};

int main()
{
	struct b S = { 12,{2,3,"张三"},NULL };//结构体类型嵌套的初始化方法
	printf("%d\n", S.num);
	printf("%d\n", S.s.i);
	printf("%d\n", S.s.j);
	printf("%s\n", S.s.a);//结构体类型的打印
	printf("%p\n", S.p);
	return 0;
}



四、结构体成员访问 (.)和(->)

结构体变量访问成员时,通过点操作符(.) 和 箭头操作符(->)进行访问

点操作符(.) 接受两个操作数 : 结构体变量 . 成员名

箭头操作符(->) 的两个操作数:结构体指针 ->成员名

typedef struct S
{
	char A;
	int B;
	char C[10];
}S;

void print1(S a)//传递结构体类型;(.)调用并打印结构体内的变量值
{
	printf("%c\n", a.A);
	printf("%d\n", a.B);
	printf("%s\n", a.C);
}

void print2(S* pa)//传递结构体指针;(->)调用并打印结构体内变量的值
{
	printf("%c\n", pa->A);
	printf("%d\n", pa->B);
	printf("%s\n", pa->C);
}

int main()
{
	S a = { '?',233,"伞兵" };
	S* pa = &a;
	print1(a);
	printf("\n");
	print2(&a);
	return 0;
}

print1 与 print2哪个好?

·print1传参,实参传递给形参时,形参是实参的一份临时拷贝,会新开辟一块空间,若结构体较大,形参占空间多,拷贝时间长

·print2传递指针,形参是地址,只传4/8字节,通过地址找到数据

·所以首选print2(传地址)

官方解释:函数传参时,参数需要压栈。如果传递一个结构体对象的时候,结构体过大,参数压栈的系统开销比较大,会导致性能下降

知识点补充:

内存:栈区+堆区+静态区

栈区:局部变量,函数的形式参数,函数调用也开辟空间

堆区:动态内存分配,malloc/free,ralloc,calloc

静态区:全局变量,静态变量



版权声明:本文为m0_74037140原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。