C语言—结构体

结构体的声明

结构的基础知识

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

结构体的定义:

struct  结构体类型的名称
{
    
    
	结构体的相关属性(结构的成员变量)
};


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

结构的声明

语法:

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

实例:描述一个学生

struct Stu
{
    
    
	//成员变量
	char name[20];//名字
	int age;//年龄
	char id[20];
} s1,s2;//s1和s2也是结构体变量
//s1,s2是全局变量

int main()
{
    
    
	//s是局部变量
	struct Stu s ;//struct Stu类型创建的对象

	return 0;
}

结构成员的类型

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

实例:

struct B
{
    
    
	char c;
	short s;
	double d;
};

struct Stu
{
    
    
	//成员变量
	struct B sb;
	char name[20];//名字
	int age;//年龄
	char id[20];
} s1,s2;//s1和s2也是结构体变量
//s1,s2是全局变量

int main()
{
    
    
	//s是局部变量
	struct Stu s;//对象
	
	return 0;
}

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

实例:

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

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


//初始化:定义变量的同时赋初值。
struct Point p3 = {
    
    x, y};

struct Stu        //类型声明
{
    
    
 	char name[15];//名字
 	int age;      //年龄
};

struct Stu s = {
    
    "zhangsan", 20};//初始化

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

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

结构体成员的访问

  • 结构体变量访问成员 结构变量的成员是通过点操作符(.)访问的。点操作符接受两个操作数。 例如:

在这里插入图片描述
访问s的成员:

struct S s;
strcpy(s.name, "zhangsan");//使用.访问name成员
s.age = 20;//使用.访问age成员
  • 结构体指针访问指向变量的成员 有时候得到的不是一个结构体变量,而是指向一个结构体的指针。例如:
struct Stu
{
    
    
 	char name[20];
 	int age;
};

void print(struct Stu* ps)
{
    
    
 	printf("name = %s   age = %d\n", (*ps).name, (*ps).age);
    //使用结构体指针访问指向对象的成员
 	printf("name = %s   age = %d\n", ps->name, ps->age);
}

int main()
{
    
    
    struct Stu s = {
    
    "zhangsan", 20};
    print(&s);//结构体地址传参
    return 0;
}

实例:

struct B
{
    
    
	char c;
	short s;
	double d;
};

struct Stu
{
    
    
	//成员变量
	struct B sb;
	char name[20];//名字
	int age;//年龄
	char id[20];
} s1,s2;//s1和s2也是结构体变量
//s1,s2是全局变量

int main()
{
    
    
	//s是局部变量
	struct Stu s = {
    
     {
    
    'w', 20, 3.14}, "张三", 30, "202005034"};//对象
	//.  ->
	printf("%c\n", s.sb.c);
	printf("%s\n", s.id);

	struct Stu* ps = &s;
	printf("%c\n", (*ps).sb.c);
	printf("%c\n", ps->sb.c);

	return 0;
}

结构体传参

实例:

struct B
{
    
    
	char c;
	short s;
	double d;
};
struct Stu
{
    
    
	//成员变量
	struct B sb;
	char name[20];//名字
	int age;//年龄
	char id[20];
};

void print1(struct Stu t)
{
    
    
	printf("%c %d %lf %s %d %s\n", t.sb.c, t.sb.s, t.sb.d, t.name, t.age, t.id);
}

void print2(struct Stu* ps)
{
    
    
	printf("%c %d %lf %s %d %s\n", ps->sb.c, ps->sb.s, ps->sb.d, ps->name, ps->age, ps->id);
}

int main()
{
    
    
	//s是局部变量
	struct Stu s = {
    
     {
    
    'w', 20, 3.14}, "张三", 30, "202005034" };//对象
	//写一个函数打印s的内容
	print1(s);
	print2(&s);

	return 0;
}

注:print1和print2函数的功能一样,首选print2函数。 因为函数传参的时候,参数是需要压栈的。 如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降。

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

补充:

  • 栈是一种数据结构。栈的特点是先进后出、后进先出
  • 给栈中放数据的操作—压栈 ;从栈中拿数据的操作—出栈
  • 每个函数调用都会在内存的栈区上开辟一块空间
  • 函数传参通常(大部分情况下、绝大部分编译器(编译器设计))情况下传参顺序是参数是从右向左传参的
  • 函数传参也是压栈操作
  • 函数调用参数压栈:
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/AI_ELF/article/details/117388366