- ❀结构体类型的声明
- 结构成员的类型
- 结构的声明
- ❀结构体初始化
- 结构体变量的定义
- 结构体变量的初始化
- ❀结构体成员的访问
- 更改成员的值
- ❀结构体传参
- 传参方式的比较
普通的类型有时候并不能表达我们需要的复杂对象。
结构是一些值的集合,这些值称为成员变量。
结构的每个成员可以是不同类型的变量。
结构的成员可以是标量、数组、指针,甚至是其他结构体。
结构的声明1、语法形式:
struct tag//j结构体关键字 结构体标签
{
member-list;//成员列表
}variable-list;//变量列表
2、
//结构体类型的声明
struct Stu//struct Stu是结构体类型名
{
char name[20];//名字
int age;//年龄
char sex[8];//性别
float score;
}s1,s2,s3;//变量列表是可以不写的
//s1,s2,s3是通过struct Stu类型创建的变量
//s1,s2,s4是全局变量
int main()
{
//s4,s5是局部变量
struct Stu s4;
struct Stu s5;
//Stu s6;//struct Stu 才是结构体类型,C语言默认不能随便省略struct关键字
return 0;
}
3、可以省略struct关键字的写法
struct Stu
{
char name[20];
int age;
char sex[8];
float score;
}s1,s2,s3;
//typedef 类型重定义/重命名
typedef struct Stu Stu;//struct Stu = Stu
int main()
{
struct Stu s4;
struct Stu s5;
Stu s6;
return 0;
}
typedef struct Stu
{
char name[20];
int age;
char sex[8];
float score;
}Stu;
int main()
{
struct Stu s4;
struct Stu s5;
Stu s6;
return 0;
}
❀结构体初始化
结构体变量的定义
struct Point
{
int x;
int y;
}p1;//全局变量
int main()
{
struct Point p;//局部变量
return 0;
}
结构体变量的初始化
struct Point
{
int x;
int y;
}p1 = {10, 15};//{多个成员}
int main()
{
struct Point p = {100, 200};
return 0;
}
结构体嵌套初始化:
struct Point
{
int x;
int y;
};
struct S
{
char c;
struct Point sp;
double d;
char arr[20];
};
int main()
{
struct S ss = { 'w', {100,20}, 5.5, "hello"};
return 0;
}
struct Node
{
int data;
struct Point p;
struct Node* next;
}n1 = {10, {4,5}, NULL};
int main()
{
struct Node n2 = {20, {5, 6}, NULL};
return 0;
}
❀结构体成员的访问
结构成员访问操作符:
结构体变量 . 结构体成员 .
结构体指针 -> 结构体成员 ->
1、
struct Point
{
int x;
int y;
};
struct S
{
char c;
struct Point sp;
double d;
char arr[20];
};
int main()
{
struct S ss = { 'w', {100,20}, 5.5, "hello"};
printf("%cn", ss.c);
printf("%d %dn", ss.sp.x, ss.sp.y);
printf("%lfn", ss.d);
printf("%sn", ss.arr);
return 0;
}
struct Point
{
int x;
int y;
};
struct S
{
char c;
struct Point sp;
double d;
char arr[20];
};
void print1(struct S s)
{
printf("%cn", s.c);
printf("%d %dn", s.sp.x, s.sp.y);
printf("%lfn", s.d);
printf("%sn", s.arr);
}
int main()
{
struct S ss = { 'w', {100,20}, 5.5, "hello" };
print1(ss);//打印struct S类型的变量
return 0;
}
2、
struct Point
{
int x;
int y;
};
struct S
{
char c;
struct Point sp;
double d;
char arr[20];
};
void print2(struct S* ps)
{
printf("%cn", ps->c);
printf("%d %dn", ps->sp.x, ps->sp.y);
//printf("%d %dn", ps->sp->x, ps->sp->y);//err - ->的左边操作数是结构体变量,不是指针
printf("%lfn", ps->d);
printf("%sn", ps->arr);
}
int main()
{
struct S ss = { 'w', {100,20}, 5.5, "hello" };
print2(&ss);
return 0;
}
更改成员的值
#include❀结构体传参struct Point { int x; int y; }; struct S { char c; struct Point sp; double d; char arr[20]; }; int main() { struct S ss = { 'w', {100,20}, 5.5, "hello"}; ss.c = 'b'; ss.sp.x = 1000; ss.sp.y= 2000; ss.d = 3.14; //ss.arr = "world";//err - 数组名是地址常量 strcpy(ss.arr, "world");//strcpy字符串拷贝 return 0; }
struct S
{
int num;
};
//结构体传参
void print1(struct S s)
{
printf("%dn", s.num);
}
//结构体地址传参
void print2(struct S* ps)
{
printf("%dn", ps->num);
}
int main()
{
struct S s = { 1000 };
//print1(s);//传结构体
print2(&s);//传地址
return 0;
}
传参方式的比较
结构体传参的时候,要传结构体的地址。
原因:
函数传参的时候,参数是需要压栈的。
传值时形参是实参的一份临时拷贝;如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,会浪费大量空间,所以会导致性能的下降。
传址形参也就只需要接收4/8B的地址就可。
为了传址后的安全性,可以使用const。
int Add(int x, int y)
{
int z = 0;
z = x + y;
return z;
}
int main()
{
int a = 10;
int b = 20;
int c = 0;
c = Add(a, b);
printf("%dn", c);
return 0;
}
每一次函数调用都要在栈区上开辟一片空间
C语言中常见的传参方式是从右向左。



