C learning_15 结构体类型的声明、结构体初始化、结构体成员访问、结构体传参

简介: C learning_15 结构体类型的声明、结构体初始化、结构体成员访问、结构体传参

结构体类型的声明


结构的基础知识


       结构是一种复合数据类型,它允许将不同类型的数据组合在一起形成一个新的自定义类型。结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。


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

结构体:一组奴役的相同类型元素的集合


结构的声明


struct tag

{

       member-list;//成员列表

}variable-list;//变量列表

//描述一个学生 - 声明一个结构体类型
struct Stu
{
  //成员变量,是用来描述结构体对象的相关属性的
  char name[20];
  int age;
  char sex[3];//汉字占两个字节
};


结构成员的类型


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


结构体初始化


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

//描述一个学生 - 声明一个结构体类型
struct Stu
{
  //成员变量,是用来描述结构体对象的相关属性的
  char name[20];
  int age;
  char sex[3];//汉字占两个字节
}p1;//全局变量 - 声明类型的同时定义变量p1
int main()
{
  struct Stu p2;//局部变量 - //定义结构体变量p2
  //初始化:定义变量的同时赋初值
  struct Stu p3 = { "zhangsan",20,"男" };
}

  这段代码定义了一个名为 `Stu` 的结构体类型,它有三个成员变量:`name`、`age` 和 `sex`,用于描述一个学生对象的相关属性。


       接着,定义了一个全局变量 `p1`,它是 `Stu` 类型的变量,这里在声明结构体类型的同时定义了变量 `p1`。

       `main` 函数中,定义了一个局部变量 `p2`,它也是 `Stu` 类型的变量。

       在定义变量的同时,可以使用结构体初始化语法来为结构体的成员变量赋初值。例如,`p3` 变量的初始化语法为 `{ "zhangsan",20,"男" }`,它依次初始化了 `name`、`age` 和 `sex` 三个成员变量的初始值。


结构体的嵌套初始化

struct Point
{
  int x;
  int y;
}p1; //声明类型的同时定义变量p1
struct Point p2; //定义结构体变量p2
//初始化:定义变量的同时赋初值。
struct Point p3 = { 1,2 };
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 };//结构体嵌套初始化
//不按照顺序初始化
struct Node n3 = { .next = NULL,.data = 18,.p.x = 1,.p.y = 2 };


结构体成员访问


#include<stdio.h>
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;
}

 这段代码定义了一个结构体 `Stu`,包含了字符串类型的姓名和整型的年龄。接下来定义了一个名为 `print` 的函数,它的参数是一个指向结构体 `Stu` 的指针 `ps`。


       在函数中,首先使用 `.` 操作符访问结构体指针 `ps` 指向的对象的成员变量 `name` 和 `age`,并使用 `printf` 函数输出这两个变量的值。其中要使用 `(*ps)` 操作符来访问指针所指向的结构体变量的成员。


       接下来,使用 `->` 操作符访问结构体指针 `ps` 指向的对象的成员变量 `name` 和 `age`,并使用 `printf` 函数输出这两个变量的值。由于 `ps` 已经是一个指向结构体 `Stu` 的指针,因此可以直接使用 `ps->name` 和 `ps->age` 来访问结构体中的成员变量。


       在 `main` 函数中,定义了一个结构体变量 `s`,并初始化了它的姓名和年龄。接着调用 `print` 函数,并将指向 `s` 的地址作为参数传递给它。最后返回 0。


结构体传参


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;
}


 这段代码定义了一个结构体 `S`,其中包含一个长度为1000的整型数组和一个表示数组元素个数的整型变量 `num`。接下来定义了两个函数 `print1` 和 `print2`,用于输出结构体变量 `s` 中的成员变量 `num`。


       在 `main` 函数中,定义了结构体变量 `s`,并初始化了它的数据和元素个数。接着调用了 `print1` 函数和 `print2` 函数,分别传递了结构体变量 `s` 和它的地址 `&s` 作为参数。最后返回 0。


       `print1` 函数使用了结构体传参的方式,将整个结构体变量 `s` 拷贝到函数的栈空间中。这种方式的好处是在函数执行时,对结构体的修改不会影响到原结构体变量的值,因此更加安全。但是缺点是在函数调用时需要进行结构体的拷贝,函数传参的时候,参数是需要压栈的。 如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降。


       `print2` 函数使用了结构体指针的方式,将结构体变量 `s` 的地址作为参数传递给了函数。这种方式的好处是在函数执行时,如果需要修改结构体的值,可以直接通过指针来访问结构体的成员变量,不需要进行结构体的拷贝操作,同时由于指针变量的空间大小是4/8个字节,对系统的开销较小。


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

相关文章
|
1月前
|
C语言
结构体变量的初始化
结构体变量的初始化。
12 3
|
27天前
|
存储 编译器 Linux
匿名结构体类型、结构体的自引用、结构体的内存对齐以及结构体传参
匿名结构体类型、结构体的自引用、结构体的内存对齐以及结构体传参
|
8月前
|
存储 编译器 C++
32.【C/C++ 结构体全类型 (详解)】(一)
32.【C/C++ 结构体全类型 (详解)】
42 0
|
8月前
|
存储 Linux C++
结构体类型的定义和初始化
结构体类型的定义和初始化
|
2月前
|
存储 C语言
定义结构体类型变量
定义结构体类型变量
10 1
|
2月前
|
程序员 C语言
结构体类型变量的定义
结构体类型变量的定义
9 0
|
2月前
|
C++
22结构体类型
22结构体类型
12 0
|
4月前
结构体变量的定义以及与结构体变量调用的两种方式
结构体变量的定义以及与结构体变量调用的两种方式
41 0
|
5月前
|
存储 C++
[C++] 结构体Struct类型和变量定义
[C++] 结构体Struct类型和变量定义
39 0
|
7月前
|
存储 C语言
浅谈结构体类型
浅谈结构体类型

热门文章

最新文章