> For the complete documentation index, see [llms.txt](https://labspc.gitbook.io/cnippets/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://labspc.gitbook.io/cnippets/chap6.-jie-gou-yu-lian-he/6.2-han-shu-yu-zhi-xiang-jie-gou-de-zhi-zhen.md).

# 6.2 函数与指向结构的指针

### 6.2.1 结构的访问 <a href="#jgivc" id="jgivc"></a>

在C语言中，结构体可以通过**结构体对象**和**结构体指针**两种方式来访问其成员。

`结构体对象.成员名` ：这种方式是直接使用结构体对象

```c
struct Person {
    char name[50];
    int age;
};

struct Person person1;
person1.age = 30;   // 直接通过结构体对象访问成员变量
```

**区别和适用场景：**

* 直接访问结构体对象的成员**通常更加简洁明了**，特别适用于局部变量或者已经定义好的结构体对象。
* 适用于单个结构体对象的操作，**不涉及指针的使用**。

`结构体指针变量->成员名` ：这种方式是通过结构体指针来访问结构体的成员。使用 **`->`** 操作符来通过指针访问结构体的成员变量。

```c
struct Person {
    char name[50];
    int age;
};

struct Person *ptrPerson;
ptrPerson = &person1;
ptrPerson->age = 30;   // 通过结构体指针访问成员变量
```

**区别和适用场景：**

* 通过结构体指针访问结构体的成员变量**通常用于动态分配的内存和数据结构，比如链表、树**等。
* 使用**结构体指针允许在函数中传递结构体的地址**，从而可以在函数内部修改结构体的内容，而不需要返回结构体本身。
* 适用于需要动态管理内存或者在函数之间传递结构体的情况。

在C语言中，当使用结构体对象进行成员访问时，不会进行拷贝操作。. 操作符用于直接访问结构体对象的成员，不会创建副本或进行任何拷贝操作。

当你使用结构体对象.成员名时，实际上是在直接引用结构体对象内存中的成员，而**不会涉及到任何复制**。这意味着对结构体成员的操作会直接影响原始的结构体对象。

相比之下，当你使用指针访问结构体成员时，也**不会进行拷贝**。指针操作也是直接引用结构体的成员，而不是创建副本。

### 6.2.2 指向结构体的指针在做什么 <a href="#i3bgi" id="i3bgi"></a>

指向结构的指针是指针变量，它**存储了一个结构体的地址**，允许我们通过该指针间接地访问和操作结构体的成员。这种方式为我们提供了更灵活和有效地访问结构体成员的方法。

具体来说，指向结构的指针可以做以下事情：

1. **访问结构体成员：** 通过指针可以访问结构体的成员变量。可以使用箭头操作符 **->** 来访问结构体指针所指向结构体的成员。

```c

struct Person {
    char name[50];
    int age;
};

struct Person person1;
struct Person *ptrPerson;

ptrPerson = &person1;
ptrPerson->age = 30; // 通过指针访问结构体成员
```

2. **动态分配内存：** 可以使用指向结构的指针动态地分配内存空间，以便在运行时创建结构体对象。

```c

struct Person *ptrPerson;
ptrPerson = (struct Person *)malloc(sizeof(struct Person));
```

3. **传递结构体参数：** 可以将指向结构的指针作为函数的参数传递，**从而允许函数对结构体进行修改，而不需要返回结构体本身**。

```c

void initializePerson(struct Person *ptr) {
    ptr->age = 30;
}

int main() {
    struct Person person1;
    initializePerson(&person1); // 传递结构体指针作为参数
    return 0;
}
```

4. **动态分配内存和数据结构的创建：** 指向结构的指针**通常用于动态创建数据结构，比如链表、树**等。通过指针可以轻松地在堆上分配内存，并将结构体连接在一起。

### 6.2.3 指向结构体的指针作为函数参数 <a href="#d3zhk" id="d3zhk"></a>

在C语言中，通过传递指向结构体的指针作为函数参数，可以方便地对结构体进行修改。这种方法避免了将整个结构体作为参数传递，节省了内存空间和提高了效率。

解释：结构体作为函数参数传递时，建议直接使用指向结构的指针，即简称为结构指针。

{% code title="6.2.3 struct-pointer-func.c" lineNumbers="true" %}

```c
#include <stdio.h>

// 定义结构体 Person
struct Person {
    int age;
};

// 函数 initializePerson，用于初始化结构体成员变量
// 函数 initializePerson 接受一个指向 Person 结构体的指针 ptr 作为参数
void initializePerson(struct Person *ptr) {
    ptr->age = 30; // 将结构体指针所指向的结构体的年龄设置为30
}

// 主函数
int main() {
    // 声明一个结构体变量 person1
    //struct Person person1;
    struct Person ptr; // 这里声明的结构体变量 ptr 和 函数的参数 ptr 重名也可以

    // 调用 initializePerson 函数，并传递 person1 的地址作为参数
    initializePerson(&ptr);

    // 打印初始化后的成员变量
    printf("Age: %d\n", ptr.age);

    return 0;
}
```

{% endcode %}
