C语言----初始结构体详解

此文是作者初次学习C语言的时候,写的笔记博文,如有错误请及时指正,谢谢!!!


目录

1,什么是结构体

2. 结构体的声明

2,1结构体声明

2,2结构体成员的类型

2,3结构体变量的定义的初始化

3. 结构体成员的访问

4. 结构体传参

5,拓展




1,什么是结构体

我们已经学过的数据类型有 char, int,long, short, long long, float, double,这些类型只能描述单一的对象,不能描述复杂的对象。 比如现在我们要描述一个学生类型的复杂对象,需要描述他的名字, 年龄, 性别, 成绩----。 我们就需要吧char类型的, int类型的, float类型的。整合到一起共同构成这个复杂对象。把这些单一对象和在一起就需要用到结构体。

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

2. 结构体的声明

2,1结构体声明

基本结构:

struct 结构体名

{

        成员列表;

}变量列表;

这里struct  结构体名,共同构成了一个数据类型名。


//结构体类型的声明
struct stu//这里的struct是用来定义结构体
	//stu是结构体名(自定义的)
{
	char name;//名字
	int age;//年龄
	char sex[8];//性别
	float score;//分数

};//注意这里有一个;
struct stu
{
	char name;
	int age;


}s1, s2, s3;
//这里的s1,s2,s3是通过struct stu类型创建的变量
//可以写也可以不写,可以写一个也可以写多个。
//此时创建的s1, s2, s3,是全局变量。
//但是平时很少这样定义

同样结构体类型变量也可以在主函数内创建


int main()
{
	//在主函数内部也可以创建结构体变量
	struct stu s4;
	struct stu s5;//这里的s4, s5就是局部变量
	//struct stu整体才是结构体类型, 不能随便省略任何单个词
	 
	 
	 
	//如果觉得结构体类型太长, 这里可以用到typedef//类型重定义或者类型重命名
	typedef struct stu stu;//把struct stu 重新起个名字叫stu
	stu s5;
	stu s6;//这里经过类型重定义,就可以用自定义的类型名来创建变量s5,s6


	return 0;
}

类型重定义也有别的表示方式,例如在定义结构体的时候给它重命名。


typedef struct stu
{
	char name;
	int age;
	char sex[8];
	float score;
}stu;

//然后以后就可以用 stu 来定义结构体变量。

2,2结构体成员的类型

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

2,3结构体变量的定义的初始化

结构体变量的定义

struct Point
{
	int x;
	int y;
}p1; //声明类型的同时定义变量p1


struct Point p2; //定义结构体变量p2

结构体变量的初始化

//简单结构体初始化
struct Point
{
	int x;
	int y;
}p1 = {100, 200};//用大括号来初始化

struct Point p2 = { 100, 200 };
//复杂结构体的初始化
struct s
{
	char a;
	struct point po;
	double b;
	char arr[10];
};

//也是使用大括号来初始化
struct s ss = { 'w', {100, 200}, 1.1, "abcdef" };

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

struct Node n2 = { 20, {5, 6}, NULL };//结构体嵌套初始化


3. 结构体成员的访问

这里就要用到结构体成员访问操作符 " . " 和 " -> " 。

看实例

struct stu
{
	char name[30];
	int age;
	double score;
};

struct point
{
	int x;
	int y;
};

struct test
{
	int a;
	struct stu b;
	struct point c;
	char d;
};


#include<stdio.h>

void print1(struct test tt)//传过来的是数据,实参把数据传给形参
{
	printf("%d\n", tt.a);
	printf("%s %d %lf\n", tt.b.name, tt.b.age, tt.b.score);
	printf("%d %d\n", tt.c.x, tt.c.y);
	printf("%c\n", tt.d);
}


void print2(struct test* tt)//传过来的是地址
{
	printf("%d\n", tt->a);
	printf("%s %d %lf\n", tt->b.name, tt->b.age, tt->b.score);
	printf("%d %d\n", tt->c.x, tt->c.y);
	printf("%c\n", tt->d);

//注意这里不可以tt->b->name


}

int main()
{
	struct test tt = { 1, {"张雪峰", 21,100.0}, {100, 200}, 'w' };
	//用”.“字符,     结构体变量.结构体成员
	print1(tt);//传值调用
	//用”->“字符//通常运用于结构体指针
	print2(&tt);//这里是传址调用。     结构体指针->结构体成员



	return 0;
}

也可以通过访问符来修改数据

int main()
{
	struct test tt = { 1, {"张雪峰", 21,100.0}, {100, 200}, 'w' };
	
	tt.a = 1000;
	strcpy(tt.b.name, "刘雪萍");
	tt.b.age = 20;
	tt.b.score = 99.0;
	tt.c.x = 10000;
	tt.c.y = 20000;
	tt.d = 'q';
	print1(tt);//打印



	return 0;
}



4. 结构体传参


struct S
{
 int data[1000];
 int num;
};
struct S s = {{1,2,3,4}, 1000};



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



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



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

上面print1和print2函数显然第二个会更好一点

原因:

1,函数传参的时候,参数是需要压栈的。

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

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

5,拓展

内存被分为栈区, 堆区, 静态区。

栈区:局部变量, 函数的参数(形式参数)

堆区:动态内存开辟, mal loc, free loc, rea loc

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

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小峰同学&&&

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值