【C语言】结构体指针

简介: 【C语言】结构体指针

结构体

基础知识

初识结构体,可以先看这篇浅显易懂的文章结构体–基础篇

所谓结构体,是一组类型可以不同的相关变量(或数组)的集合。

构成结构体的变量(或数组)称为结构体的成员

C语言要求,在定义结构体变量时,需要明确给定每个成员的名字类型

声明一种·结构体类型,需要定义一个标识符,这种标识符称为结构体类型标识符。

struct student
{
    char name[20];
    char num[11];
    int age;
    float score;
};//student 是结构体类型的标识符    
//struct student 是一种结构体类型

对于结构体变量的成员可以进行哪些操作,取决于结构体变量的成员是哪种类型的。因为结构体变量的成员在本质上也是变量(或数组),所以对于结构体变量成员的操作,与同类型变量(或数组)的操作是相同的。

注意对于成员的赋值

我们先来看一个错误的程序:

#include <stdio.h>
struct student 
{
  char name[20];
  char num[20];
  int score;
};
int main (void)
{
  struct student stu;
  stu.score=99;
  stu.name="Lin hui";
  stu.num="S2208017";
  printf("%d,%s,%s\n",stu.score,stu.name,stu.num);
  return 0;
}

编译系统会报错,这是为什么呢?

该程序编译时,将会产生“给数组名赋值”的错误。

这是因为结构体变量stu的两个成员num和name均为字符数组

而数组名属于指针常量,因而不能对数组名进行赋值。

那么,如何才能将字符串存放如字符数组成员中呢?我们可以利用strcpy函数。

正确的程序

#include <stdio.h>
#include <string.h>
struct student 
{
  char name[20];
  char num[20];
  int score;
};
int main (void)
{
  struct student stu;
  stu.score=99;
  strcpy(stu.name,"Linhui");
  strcpy(stu.num,"S2208017");
  printf("%d,%s,%s\n",stu.score,stu.name,stu.num);
  return 0;
}

结构体指针

指针的基本功能就是间接引用,也就是通过指针变量间接地引用另一个变量。

为什么要使用指针呢?

指针的独特优势在于,在C语言中的某些功能只能借助于间接引用才能实现。

例如,局部变量的跨函数改写,就只能通过间接引用才能实现。

同样地,结构体指针的功能就是间接地引用结构体变量。

而C语言中的某些功能(例如动态链表)就必须借助于结构体指针才能实现。

指向结构体变量的指针

struct student    //声明结构体类型
{
    char name[20];
    char num[20];
    int age;
    int score;
};
struct student stu;//定义结构体类型的变量stu
struct *p;//定义指向结构体变量的指针变量p
p=&stu;//赋初值

结构体指针与结构体成员指针

一旦定义了指向结构体变量的指针,就可以通过该指针间接引用所指向的结构体变量。

p=&stu;

那么,就可以用*p来间接引用结构体变量stu;

上述是把结构体变量的首地址赋值给指针变量p,所以结构体指针变量p指向了结构体变量stu。

例:

虽然结构体指针和结构体第一个成员的地址值相同,但结构体指针结构体成员指针的含义是不同的。

struct student *p;*p=stu;
int *p1=stu.num;

虽然p和p1的值是相同的,都是2000H。但是p是指向结构体类型变量的指针,而p1是指向int型变量的指针。若执行p++,则p的值为2043H,而执行p1++,p1的值为2002H。

用结构体指针引用结构体成员

既然可以利用结构体指针引用结构体变量,当然也可以引用结构体变量的成员

其一般形式为:

(*结构体指针变量).成员名

需要注意,这里的括号必不可少。如果去掉括号后:

*结构体指针变量.成员名

由于成员运算符“.”的优先级高于间接引用运算符"*",所以上式即为:

*(结构体指针变量.成员名)

而指针变量不可能有成员,从而导致语法错误。

例:

从键盘输入一个学生的学号、姓名、年龄和成绩,并存入一个结构体变量中,然后依次输出各项数据。要求通过结构体指针``间接引用该结构体变量的成员`。

#include <stdio.h>
struct student   //定义结构体类型说明符 student
{
    char num[20];
    char name[20];
    int age;
    float score;
};
int main (void)
{
    struct student stu,*p=&stu;
    gets((*p).num);//输入学号
    gets((*p).name);//输入姓名
    scanf("%d",&(*p).age);//输入年龄
    scanf("%f",&(*p).score);//输入成绩
    printf("学号\t姓名\t年龄\t成绩\n");
    printf("%s\t%s\t%d\t%.2f\n",(*p).num,(*p).name,(*p).age,(*p).score);
    return 0;
}

上述间接引用形式比较直观,但略显繁琐,故C语言提供了另一种更加简洁的·引用形式。

其一般形式为:

结构体指针变量->成员名

此处的“- >”称为指向运算符。

其功能等价于:

(*结构体指针变量).成员名

让我们再来以这种方式做一下上面的题目:

从键盘输入一个学生的学号、姓名、年龄和成绩,并存入一个结构体变量中,然后依次输出各项数据。要求通过结构体指针``间接引用该结构体变量的成员`。

#include <stdio.h>
struct student //定义结构体类型说明符
{
    char num[20];
    char name[20];
    int age;
    float score;
};
int main (void)
{
    struct student stu,*p=&stu;
    gets(p->num);
    gets(p->name);
    scanf("%d",&p->age);
    scanf("%f",&p->score);
    printf("学号\t姓名\t年龄\t成绩\n");
    printf("%s\t%s\t%d\t%.2f\n",p->num,p->name,p->age,p->score);
    return 0;
}


相关文章
|
24天前
|
C语言
【c语言】指针就该这么学(1)
本文详细介绍了C语言中的指针概念及其基本操作。首先通过生活中的例子解释了指针的概念,即内存地址。接着,文章逐步讲解了指针变量的定义、取地址操作符`&`、解引用操作符`*`、指针变量的大小以及不同类型的指针变量的意义。此外,还介绍了`const`修饰符在指针中的应用,指针的运算(包括指针加减整数、指针相减和指针的大小比较),以及野指针的概念和如何规避野指针。最后,通过具体的代码示例帮助读者更好地理解和掌握指针的使用方法。
45 0
|
22天前
|
存储 C语言
如何在 C 语言中实现结构体的深拷贝
在C语言中实现结构体的深拷贝,需要手动分配内存并逐个复制成员变量,确保新结构体与原结构体完全独立,避免浅拷贝导致的数据共享问题。具体方法包括使用 `malloc` 分配内存和 `memcpy` 或手动赋值。
30 10
|
21天前
|
存储 大数据 编译器
C语言:结构体对齐规则
C语言中,结构体对齐规则是指编译器为了提高数据访问效率,会根据成员变量的类型对结构体中的成员进行内存对齐。通常遵循编译器默认的对齐方式或使用特定的对齐指令来优化结构体布局,以减少内存浪费并提升性能。
|
23天前
|
C语言
【c语言】指针就该这么学(3)
本文介绍了C语言中的函数指针、typedef关键字及函数指针数组的概念与应用。首先讲解了函数指针的创建与使用,接着通过typedef简化复杂类型定义,最后探讨了函数指针数组及其在转移表中的应用,通过实例展示了如何利用这些特性实现更简洁高效的代码。
15 2
|
23天前
|
C语言
如何避免 C 语言中的野指针问题?
在C语言中,野指针是指向未知内存地址的指针,可能引发程序崩溃或数据损坏。避免野指针的方法包括:初始化指针为NULL、使用完毕后将指针置为NULL、检查指针是否为空以及合理管理动态分配的内存。
|
23天前
|
C语言
C语言:哪些情况下会出现野指针
C语言中,野指针是指指向未知地址的指针,通常由以下情况产生:1) 指针被声明但未初始化;2) 指针指向的内存已被释放或重新分配;3) 指针指向局部变量,而该变量已超出作用域。使用野指针可能导致程序崩溃或不可预测的行为。
|
26天前
|
编译器 C语言
共用体和结构体在 C 语言中的优先级是怎样的
在C语言中,共用体(union)和结构体(struct)的优先级相同,它们都是用户自定义的数据类型,用于组合不同类型的数据。但是,共用体中的所有成员共享同一段内存,而结构体中的成员各自占用独立的内存空间。
|
30天前
|
存储 C语言
C语言32位或64位平台下指针的大小
在32位平台上,C语言中指针的大小通常为4字节;而在64位平台上,指针的大小通常为8字节。这反映了不同平台对内存地址空间的不同处理方式。
|
26天前
|
存储 C语言
C语言:结构体与共用体的区别
C语言中,结构体(struct)和共用体(union)都用于组合不同类型的数据,但使用方式不同。结构体为每个成员分配独立的内存空间,而共用体的所有成员共享同一段内存,节省空间但需谨慎使用。
|
30天前
|
编译器 C语言 C++
C语言结构体
C语言结构体
25 5