C 结构体指针

在 C 语言中,我们可以为一个变量定义一个指针,也可以为一个数组指定一个指针。对于结构体类型来说,我们同样需要可以分为下面 2 种情况。

  • 指向结构体变量的指针。
  • 指向结构体数组的指针。

语法:

struct 结构体类型* 指针变量名;

说明:

结构体数组一般是 “一维” 的,所以它的指针和结构体变量的指针定义方式也是一样的,都是采用上面这种语法。

示例 1:C 指向结构体变量的指针

下面例子先定义一个结构体变量,然后再定义一个指针指向该结构体变量。

#include <stdio.h>

// 定义结构体类型
struct Student
{
    int id;             // 学号
    char name[10];      // 姓名
    char gender;           // 性别,'m' 表示男,'f' 表示女
    int age;            // 年龄
};
int main(void)
{
    // 定义一个结构体变量
    struct Student stu = {1001, "阿莫", 'm', 20};

    // 定义一个指针
    struct Student* p;
    p = &stu;

    printf("学号:%d\n", (*p).id);
    printf("姓名:%s", (*p).name);
    return 0;
}

运行结果如下。

学号:1001
姓名:阿莫

分析:

在这个例子中,我们定义了一个名为 p 的结构体指针,它指向的是结构体变量 stu。因此在非定义部分时,*p 代表的就是 stu 本身。所以我们可以使用 (*p).id 来获取 no 成员的值,也可以使用 (*p).name 来获取 name 成员的值。需要注意的是,*p 外面的括号不能省略。

想要访问结构体成员,如果是通过结构体变量名来访问,我们必须使用 “.” 运算符。比如 stu.id、stu.name。如果是通过指针变量名来访问,我们必须使用 “->” 运算符,如 p->no、p->name。从之前的学习可以知道,*p 和 stu 是等价的,所以这里才使用 (*p).id、(*p).name 这种方式。

对于这个例子来说,下面 3 种写法是等价的,都可以获取 name 这个成员的值。我们需要把每一种写法都理解清楚。

// 写法 1
stu.name

// 写法 2
(*p).name

// 写法 3
p->name

如果想要修改某一个成员的值,我们需要注意一下:

// 错误写法(不能直接赋值):
// p->name = "Tom"; 

// 正确写法(使用 strcpy):
strcpy(p->name, "Tom");

示例 2:C 指向结构体数组的指针

下面例子先定义一个结构体数组,然后再定义一个指针指向该结构体数组。

#include <stdio.h>

// 定义结构体类型
struct Student
{
    int id;             // 学号
    char name[10];      // 姓名
    char gender;           // 性别,'m' 表示男,'f' 表示女
    int age;            // 年龄
};

int main(void)
{
    // 定义一个结构体数组
    struct Student stuArr[3] = {
        {1001, "Jack", 'm', 20}, 
        {1002, "Lucy", 'f', 21}, 
        {1003, "Tony", 'm', 19}
    };

    // 定义一个指针
    struct Student* p;
    p = stuArr;

    // 获取成员的值
    printf("Jack 的学号:%d\n", p[0].id);
    printf("Lucy 的学号:%d\n", p[1].id);
    printf("Tony 的学号:%d", p[2].id);
    return 0;
}

运行结果如下。

Jack 的学号:1001
Lucy 的学号:1002
Tony 的学号:1003

分析:

对于结构体变量来说,我们需要在变量名前面加上 “&” 才能获取它的地址。但是对于结构体数组来说,数组名本身就代表它的地址,所以我们不需要在前面加上 “&” 了。这一点和普通变量、普通数组之间的区别是一样的。

此外,对于这个例子来说,下面 2 种方式是等价的。

// 方式 1
printf("Jack 的学号:%d\n", p[0].id);
printf("Lucy 的学号:%d\n", p[1].id);
printf("Tony 的学号:%d", p[2].id);

// 方式 2
printf("Jack 的学号:%d\n", (*(p + 0)).id);
printf("Lucy 的学号:%d\n", (*(p + 1)).id);
printf("Tony 的学号:%d", (*(p + 2)).id);

对于第 2 种方式,p 是一个一维数组的指针变量,每次加上 1 之后,其实就等于增加一个步长,也就是指向下一个元素了。

从之前的学习可以知道,结构体变量类似于 “普通变量”,结构体数组类似于 “普通数组”,它们的特性以及指针语法都是一样的。小伙伴们可以多多对比理解一下,这样更能加深理解和记忆。

上一篇: C 结构体数组

下一篇: C 枚举

给站长反馈

绿叶网正在不断完善中,小伙伴们如果发现任何问题,还望多多给站长反馈,谢谢!

邮箱:lvyenet@vip.qq.com

「绿叶网」服务号
绿叶网服务号放大
关注服务号,微信也能看教程。
绿叶网服务号