hello , 今天给大家分享一道简单C语言试题,温故知新。

问题:给定两个指针p1 和 p2(不为空), ​p1 = p2​ 和 ​*p1 = *p2​ 是一样的吗?

考察知识点:指针理解、左值、右值。

思路

对于这道题,容易出现误区:看表象,两者输出结果一致,认为是一样的操作。

p1 = p2​:很好理解,将p1 指向p2,即p1 和 p2 同时指向p2地址处,覆盖了原来p1的值。

*p1 = *p2​:表示将p2 指向的内容 赋值给p1 指向的内容,指针本身的地址不变。

p1 = p2

源代码:改变的是地址

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct _student {
int id;
int age;
char name[32];
float score;
} student_t;

static void dump_info(student_t *pstu)
{
printf("INFO(%s): student->id = %d\n", __func__, pstu->id);
printf("INFO(%s): student->age = %d\n", __func__, pstu->age);
printf("INFO(%s): student->name = %s\n", __func__, pstu->name);
printf("INFO(%s): student->score = %f\n", __func__, pstu->score);
}

int main()
{
student_t *p1 = NULL;
student_t *p2 = NULL;

p1 = (student_t*)malloc(sizeof(student_t));
if (!p1) {
printf("ERROR(%s):malloc for p1 error\n", __func__);
return -1;
}

p2 = (student_t*)malloc(sizeof(student_t));
if (!p1) {
printf("ERROR(%s):malloc for p1 error\n", __func__);
return -1;
}

p1->id = 1;
p1->age = 21;
strcpy(p1->name, "stu1");
p1->score = 90.0;

p2->id = 2;
p2->age = 25;
strcpy(p1->name, "stu2");
p2->score = 100.0;

printf("INFO(%s): $$$$$$$$$$$ before $$$$$$$$$$ \n", __func__);
printf("INFO(%s): p1 = %p \n",__func__, p1);
printf("INFO(%s): p2 = %p \n",__func__, p2);
dump_info(p1);
dump_info(p2);

p1 = p2;
printf("INFO(%s): $$$$$$$$$$$ p1 = p2 $$$$$$$$$$ \n", __func__);
printf("INFO(%s): p1 = %p \n",__func__, p1);
printf("INFO(%s): p2 = %p \n",__func__, p2);
dump_info(p1);
dump_info(p2);

return 0;
}

输出结果:p1 的地址被覆盖了,变成p2.

INFO(main): $$$$$$$$$$$ before $$$$$$$$$$ 
INFO(main): p1 = 0xd65010
INFO(main): p2 = 0xd65050
INFO(dump_info): student->id = 1
INFO(dump_info): student->age = 21
INFO(dump_info): student->name = stu2
INFO(dump_info): student->score = 90.000000
INFO(dump_info): student->id = 2
INFO(dump_info): student->age = 25
INFO(dump_info): student->name =
INFO(dump_info): student->score = 100.000000
INFO(main): $$$$$$$$$$$ p1 = p2 $$$$$$$$$$
INFO(main): p1 = 0xd65050
INFO(main): p2 = 0xd65050
INFO(dump_info): student->id = 2
INFO(dump_info): student->age = 25
INFO(dump_info): student->name =
INFO(dump_info): student->score = 100.000000
INFO(dump_info): student->id = 2
INFO(dump_info): student->age = 25
INFO(dump_info): student->name =
INFO(dump_info): student->score = 100.000000

*p1 = *p2

源代码:改变的是指向的内容

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct _student {
int id;
int age;
char name[32];
float score;
} student_t;

static void dump_info(student_t *pstu)
{
printf("INFO(%s): student->id = %d\n", __func__, pstu->id);
printf("INFO(%s): student->age = %d\n", __func__, pstu->age);
printf("INFO(%s): student->name = %s\n", __func__, pstu->name);
printf("INFO(%s): student->score = %f\n", __func__, pstu->score);
}

int main()
{
student_t *p1 = NULL;
student_t *p2 = NULL;

p1 = (student_t*)malloc(sizeof(student_t));
if (!p1) {
printf("ERROR(%s):malloc for p1 error\n", __func__);
return -1;
}

p2 = (student_t*)malloc(sizeof(student_t));
if (!p1) {
printf("ERROR(%s):malloc for p1 error\n", __func__);
return -1;
}

p1->id = 1;
p1->age = 21;
strcpy(p1->name, "stu1");
p1->score = 90.0;

p2->id = 2;
p2->age = 25;
strcpy(p1->name, "stu2");
p2->score = 100.0;

printf("INFO(%s): $$$$$$$$$$$ before $$$$$$$$$$ \n", __func__);
printf("INFO(%s): p1 = %p \n",__func__, p1);
printf("INFO(%s): p2 = %p \n",__func__, p2);
dump_info(p1);
dump_info(p2);

*p1 = *p2;
printf("INFO(%s): $$$$$$$$$$$ p1 = p2 $$$$$$$$$$ \n", __func__);
printf("INFO(%s): p1 = %p \n",__func__, p1);
printf("INFO(%s): p2 = %p \n",__func__, p2);
dump_info(p1);
dump_info(p2);

return 0;
}

输出结果:p1 和 p2 的地址不变,p1 指向的内容被覆盖了

INFO(main): $$$$$$$$$$$ before $$$$$$$$$$ 
INFO(main): p1 = 0x20d2010
INFO(main): p2 = 0x20d2050
INFO(dump_info): student->id = 1
INFO(dump_info): student->age = 21
INFO(dump_info): student->name = stu2
INFO(dump_info): student->score = 90.000000
INFO(dump_info): student->id = 2
INFO(dump_info): student->age = 25
INFO(dump_info): student->name =
INFO(dump_info): student->score = 100.000000
INFO(main): $$$$$$$$$$$ p1 = p2 $$$$$$$$$$
INFO(main): p1 = 0x20d2010
INFO(main): p2 = 0x20d2050
INFO(dump_info): student->id = 2
INFO(dump_info): student->age = 25
INFO(dump_info): student->name =
INFO(dump_info): student->score = 100.000000
INFO(dump_info): student->id = 2
INFO(dump_info): student->age = 25
INFO(dump_info): student->name =
INFO(dump_info): student->score = 100.000000

总结

本文简单温故一下知识的用法。对于p1 = p2 和 *p1 = *p2,只需要把握变化的地方就行。


  • p1 = p2: 改变的是指针地址。所以指向内容也跟着变了。
  • *p1 = *p2:改变的是指针指向的内容,指针本身地址不变。

C语言题解:p1 = p2 与 *p1 = *p2_#include

所以两者结果虽一致,但本身操作并不一致。