C语言中声明指针变量时写"*"的作用及相关问题咨询
C语言指针核心疑问:声明中
*的作用与编译报错解析 一、指针声明中*的作用
你已经理解指针的类型(比如int)用来指定解引用时读取的字节数,那*的核心作用是明确变量的指针身份:
- 在
int *p的声明里,*告诉编译器:p不是普通的int变量,而是一个存储int类型变量地址的指针。 - 完整的
int *p表示p的类型是int*(指向int的指针),它的使命是保存内存地址,而非直接存储数值。
两种写法的本质区别
int *p = &x;(正确写法)p被声明为int*类型的指针变量,&x是int变量的地址,类型完全匹配。编译器可以正确识别后续的*p是对指针的解引用操作,读取对应类型的字节数(比如int占4字节)。
int p = &x;(错误写法)- 这是把
int*类型的地址值,强行赋值给int类型的普通变量,属于隐式类型不匹配转换。编译器会抛出警告(比如-Wint-conversion),因为指针和int的字节宽度可能不匹配(64位系统下指针是8字节,int是4字节,会截断地址),后续操作会埋下运行隐患。
- 这是把
二、为何gcc报错但终端显示“输出正常”?
你看到的终端输出是误导性的假象:
- gcc的报错信息里明确提示了编译错误(第10、11行的
invalid type argument of unary '*'),说明当前错误代码根本没有编译成功,无法生成可执行文件。 - 你运行的大概率是之前编译好的正确版本代码的可执行文件,不是当前错误代码的产物。
来看错误代码的关键问题:
#include <stdio.h> int main() { int x = 1025; int p = &x; // 无"*",将地址赋值给普通int变量 char p0 = (char *)p; // 类型转换后仍赋值给普通char变量 printf("%d\n", *p); printf("%d\n", *p0); return 0; }
这里的*p和*p0是语法错误:p是普通int变量,p0是普通char变量,*运算符只能作用于指针类型,不能对基础数值类型执行解引用操作,所以gcc直接终止编译,不会生成可执行文件。
补充:正确代码的逻辑回顾
你最初的正确代码清晰展示了指针类型的作用:
#include <stdio.h> int main() { int x = 1025; // int占4字节,二进制为00000000 00000000 00000100 00000001 int *p = &x; // p是指向int的指针,存储x的地址 char *p0 = (char *)p; // 强制转换为指向char的指针,地址值和p一致 printf("%d\n", *p); // 解引用p,读取4字节,返回1025 printf("%d\n", *p0); // 解引用p0,读取1字节,返回1(低地址的1字节) return 0; }
这里的*p是合法的解引用:因为p是指针类型,编译器知道要从p存储的地址开始,读取int类型对应的4字节数据。
内容的提问来源于stack exchange,提问作者s7eqx9f74nc4
相关产品推荐
相关产品推荐

