c语言初阶学习笔记——结构体

目录

  • 一、结构体的声明
    • 1.结构的声明
    • 2.结构成员的类型
    • 3.结构体变量的定义和初始化
  • 二、结构体成员的访问
  • 三、结构体传参

一、结构体的声明

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

1.结构的声明

struct tag
{
   member-list;
}variable-list;

struct关键字 tag是结构体的标签名 struct tag合起来是结构体类型
大括号 {} 里放的是成员变量的列表,括号后面是变量列表

三种常见结构体的声明:

1:声明类型的同时可以不定义变量
struct Book
{
	char name[20];
	int price;
};

2:可以在括号后面创建结构体变量,注意这是全局变量
struct Book
{
	char name[20];
	int price;
}b3, b4, b5;

3typedef类型重命名可以更方便我们使用结构体
typedef struct Book
{
	char name[20];
	int price;
}Book;
/ typedef之后想创建全局变量直接写在外面,而不是写在Book后面
Book b3;
Book b4;

2.结构成员的类型

结构的成员可以是标量、数组、指针,甚至是其他结构体。

struct S
{
	char c;
	char arr[10];
	int* p;
}s1, s2;

struct S s3;

struct B
{
	int a;
	struct S s;
	double d;
};

3.结构体变量的定义和初始化

struct Book
{
	char name[20];
	int price;
}b3, b4, b5;

int main()
{
	struct Book b1;
	struct Book b2;

	return 0;
}

int a; 拿int类型创建一个a变量
拿结构体类型创建了一个b1变量就是struct Book b1;
也可以在创建类型的同时直接后面给名字
b3,b4,b5在大括号外部创建的,没有在函数内部,所以是全局的
c语言初阶学习笔记——结构体_第1张图片
初始化:定义变量的同时赋初值。

struct S
{
	char c;
	char arr[10];
	int* p;
}s1, s2;

struct S s3;

struct B
{
	int a;
	struct S s;
	double d;
}sb1, sb2;

struct B sb3;

int main()
{
	struct S s4 = {'c', "zhangsan", NULL};/ 初始化

	int a = 10;
	struct B sb4 = { 100, {'q', "lisi", &a}, 3.14};/ 初始化

	return 0;
}

struct Node
{
 int data;
 struct Point p;
 struct Node* next; 
}n1 = {10, {4,5}, NULL}; / 结构体嵌套初始化
struct Node n2 = {20, {5, 6}, NULL};/ 结构体嵌套初始化

二、结构体成员的访问

结构体变量.结构体成员 或者 结构体指针->结构体成员

struct Book
{
	char name[20];
	int price;
};

void print(struct Book* p)
{
	printf("%s %d\n", p->name, p->price);
}

int main()
{
	struct Book b1 = {"12345", 66};
	struct Book b2 = { .price = 80, .name = "abcde"};
	//结构体变量.结构体成员
	printf("%s %d\n", b1.name, b1.price);
	printf("%s %d\n", b2.name, b2.price);
	//结构体指针->结构体成员
	//struct Book* p1 = &b1;
	print(&b1);
	return 0;
}

三、结构体传参

struct S
{
	int arr[1000];
	int n;
};

void print1(struct S ss)
{
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", ss.arr[i]);
	}
	printf("\n%d\n", ss.n);
}

void print2(struct S* ps)
{
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", ps->arr[i]);
	}
	printf("\n%d\n", ps->n);
}

int main()
{
	struct S s = { {1,2,3,4,5}, 100 };
	print1(s);
	print2(&s);

	return 0;
}

上面的 print1 和 print2 函数哪个好些?
答案:print2函数。

原因:函数传参的时候,形参是实参的一份临时拷贝,参数是需要压栈的。 如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降。
传结构体相当于传过去4004大小的数据,还要创建一模一样大小的空间,传递的数据量大,存储又得浪费空间,值传递空间和时间上都是浪费。
而指针也就4/8字节,指针变量接收,能用指针找到s就可以了,效率更高,指针还可以改数据,值传递只是使用无法更改原数据,想要指针不能修改原数据就用加const的指针接收

所以:结构体传参的时候,要传结构体的地址。

你可能感兴趣的:(c语言初阶学习笔记,c语言,学习)