初识结构体

2024-01-22 17:52:05 浏览数 (2)

1. 结构体类型的声明
1.1 结构的基础知识

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

注:

数组: 一组相同类型元素的集合

结构体: 其实是一组不一定相同类型元素的集合

1.2 结构的声明
代码语言:javascript复制
//描述一个学生
//名字 年龄 性别

//声明结构体类型
struct Stu
{
	//成员变量,是用来描述结构体对象的相关属性的
	char name[20];
	int age;
	char sex[5];//男 女 保密
}s2, s3, s4;//s2,s3,s4 就是结构体变量 - 全局变量

typedef struct Stu
{
	//成员变量,是用来描述结构体对象的相关属性的
	char name[20];
	int age;
	char sex[5];//男 女 保密
}Stu;

int main()
{
	//int a = 10;
	struct Stu s1;//局部变量
	Stu s2;
	
	return 0;
}

注:

代码语言:javascript复制
struct Stu
{
	//成员变量,是用来描述结构体对象的相关属性的
	char name[20];
	int age;
	char sex[5];//男 女 保密
};

int main()
{
	//int a = 10;
	struct Stu s1;//局部变量
	//Stu s2;//在C语言中,没有对结构体类型typedef,struct关键字不能省略

	return 0;
}
1.3 结构成员的类型

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

代码语言:javascript复制
struct S
{
	int a;
	char arr[5];
	int* p;
};

struct B
{
	char ch[10];
	struct S s;
	double d;
};

int main()
{

	return 0;
}
1.4 结构体变量的定义和初始化
代码语言:javascript复制
struct S
{
	int a;
	char arr[5];
	int* p;
}s1 = {100, "bit", NULL};

struct S s2 = {98, "hehe", NULL};

struct B
{
	char ch[10];
	struct S s;
	double d;
};

int main()
{
	struct S s3 = {.arr = "abc", .p = NULL, .a = 1};
	struct B sb = { "hello", {20, "qqq", NULL}, 3.14 };

	return 0;
}

2. 结构体成员的访问

  1. 结构体变量访问成员
代码语言:javascript复制
#include <stdio.h>

struct S
{
	int a;
	char arr[5];
	int* p;
}s1 = {100, "bit", NULL};

struct S s2 = {98, "hehe", NULL};

struct B
{
	char ch[10];
	struct S s;
	double d;
};

int main()
{
	struct S s3 = {.arr = "abc", .p = NULL, .a = 1};
	printf("%d %s %pn", s3.a, s3.arr, s3.p);//. 结构成员访问操作符
	struct B sb = { "hello", {20, "qqq", NULL}, 3.14 };
	printf("%s %d %s %p %.2lfn", sb.ch, sb.s.a, sb.s.arr, sb.s.p, sb.d);

	return 0;
}
  1. 结构体指针访问指向变量的成员

以下代码是有问题的:

代码语言:javascript复制
#include <string.h>

struct Stu
{
	char name[20];
	int age;
};

void set_Stu(struct Stu t)
{
	t.age = 20;
	//t.name = "张三";//err
	strcpy(t.name, "张三");//字符串拷贝
}

void print_Stu(struct Stu t)
{
	printf("%s %dn", t.name, t.age);
}

int main()
{
	struct Stu s = { 0 };
	set_Stu(s);
	print_Stu(s);

	return 0;
}

正确代码:

代码语言:javascript复制
#include <string.h>

struct Stu
{
	char name[20];
	int age;
};

//void set_Stu(struct Stu* ps)
//{
//	(*ps).age = 20;
//	strcpy((*ps).name, "张三");//字符串拷贝
//}

void set_Stu(struct Stu* ps)
{
	ps->age = 20;//结构体指针->结构体成员
	strcpy(ps->name, "张三");//字符串拷贝
}

void print_Stu(struct Stu t)
{
	printf("%s %dn", t.name, t.age);
}

int main()
{
	struct Stu s = { 0 };
	set_Stu(&s);
	print_Stu(s);

	return 0;
}

3. 结构体传参

代码语言:javascript复制
#include <stdio.h>

struct S
{
	int data[1000];
	int num;
};

struct S s = {{1,2,3,4}, 1000};

//结构体传参
void print1(struct S s)
{
	printf("%dn", s.num);
}

//结构体地址传参
void print2(struct S* ps)
{
	printf("%dn", ps->num);
}

int main()
{
	print1(s);  //传结构体
	print2(&s); //传地址
	
	return 0;
}

上面的 print1 和 print2 函数哪个好些?

答案是:首选print2函数。

原因:

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

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

0 人点赞