【C语言入门必看】结构体

结构体
本章浅入了解结构体,在后面的自定义类型进阶会重点讲这部分内容。

一、结构体类型的声明

结构体:用于描述属性不止一个的复杂对象

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

我们已经学习过:intcharfloatdouble等单一变量类型,但这些只能描述单一属性,所以C语言创造了包含多种单一变量结构体,方便描述复杂对象。比如一本书有书名、作者、价格等属性。
结构体的声明语法:

	struct tag//struct - 结构体关键字;tag - 结构体标签;struct tag - 结构体类型名
	{
    
    
		member-list;//成员列表
	}variable-list;//变量列表

int类型本身不占据空间,当用int类型创建int整型变量时才会在内存中开辟空间。
同理,struct tag结构体类型本身不占据空间,当用结构体类型创建结构体变量才会在内存中开辟空间

如要声明一个学生类型,它的成员变量包括:名字、年龄、性别、学号。

struct Stu
{
    
    
  //成员变量
 char name[20];//名字
 int age;//年龄
 char sex[5];//性别
 char id[20];//学号
}

当觉得上述struct Stu结构体类型名太长,这时候需要用到类型重定义typedef

typedef struct Stu
{
    
    
  //成员变量
 char name[20];//名字
 int age;//年龄
 char sex[5];//性别
 char id[20];//学号
}Stu;

这样,struct Stu就等效于Stu

结构体成员的类型:
结构的成员可以是标量、数组、指针,甚至是其他结构体(内嵌)。

二、结构体初始化

有了结构体类型,定义结构体变量就简单啦!

struct Stu
{
    
    
	//成员变量
	char name[20];//名字
	int age;//年龄
	char sex[5];//性别
	char id[20];//学号
}s1;//①声明类型的同时定义变量s1
struct Stu s2;//定义全局变量s2
int main()
{
    
    
	struct Stu s3;//③定义局部变量s3
	struct Stu s4 = {
    
     "张三",17,"男","20200360318" };//④定义结构体变量s4的同时可初始化
	return 0;
}

以上是创建结构体变量的方式。当执行类型重定义typedef struct {...} Stu;后代码中的struct Stu可替换成Stu

注:在main函数内创建的结构体变量是局部变量,在栈区开辟空间;在main函数外,则为全局变量,在静态区开辟空间。

结构体内可嵌套结构体:

struct S 
{
    
    
	int a;
	char c;
	double d;
};
struct T 
{
    
    
	struct S s;
	char name[20];
	int num;
};
int main() 
{
    
    
	struct T t = {
    
     {
    
    100, 'w', 3.14}, "张三", 17 };
	return 0;
}

结构体变量t内含有用结构体类型S创建的s。在给s初始化时,得用{}

三、结构体成员访问

  1. . 操作符
    结构体变量成员可通过 . 操作符访问,它有两个操作数,左边为结构体变量名,右边为结构体成员变量名。
    借用上面结构体嵌套的例子:
    在这里插入图片描述

st的成员变量,abcs的成员变量,访问abc则为t.s.at.s.bt.s.c

  1. -> 操作符
    结构体变量成员也可通过 -> 操作符访问,它有两个操作数,左边为结构体指针变量,右边为结构体成员变量。
struct T t = {
    
     {
    
    100, 'w', 3.14}, "张三", 17 };
struct T* pt = &t;//结构体指针变量pt
//1.对结构体指针解引用找到指针所指向的结构体
printf("%d %c %lf %s %d\n", (*pt).s.a, (*pt).s.c, (*pt).s.d, (*pt).name, (*pt).num);
//2.通过结构体指针直接获得成员变量
printf("%d %c %lf %s %d\n", pt->s.a, pt->s.c, pt->s.d, pt->name, pt->num);

四、结构体传参

#include<stdio.h>
struct S
{
    
    
	int data[1000];
	int num;
};//结构体类型的声明

//结构体传参
void print1(struct S s)
{
    
    
	printf("%d\n", s.num);
}
//结构体地址传参
void print2(struct S* ps)
{
    
    
	printf("%d\n", ps->num);
}
int main()
{
    
    
	struct S s = {
    
     {
    
    1,2,3,4}, 1000 };
	print1(s);  //传结构体
	print2(&s); //传地址
	return 0;
}

上面的 print1print2 函数哪个好些?
答案是:首选print2函数。
原因:

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

结论:

结构体传参的时候,建议传结构体的地址。

猜你喜欢

转载自blog.csdn.net/weixin_50614301/article/details/120357820
今日推荐