C语言中*a与a的区别和联系
1. &a
(取地址操作符)
-
作用:获取变量
a
在内存中的地址。 -
结果类型:返回一个指针,类型是
a 的类型*
。 -
适用对象:任何非寄存器变量(例如
int
、float
、数组、结构体等)。 -
示例:
int a = 10;
int *p = &a; // p 指向 a 的地址
&a
的类型是int*
,表示“指向int
的指针”。
2. *a
(解引用操作符)
-
作用:访问指针
a
指向的值。 -
结果类型:返回指针
a
指向的实际数据,类型是a 的类型
去掉一个*
。 -
适用对象:必须是一个指针变量。
-
示例:
int a = 10;
int *p = &a; // p 保存 a 的地址
int value = *p; // value = 10(通过 p 解引用获取 a 的值)
-
*p
的类型是int
,表示“p
指向的int
值”。
3. 区别对比
4. 联系与结合使用
(1) 互为逆操作
-
如果
a
是一个指针,且p = &a
,则:
int a = 10;
int *p = &a;
assert(*p == a); // *p 等价于 a
assert(p == &a); // p 保存的是 a 的地址
(2) 多级指针
-
可以通过嵌套
&
和*
操作符处理多级指针:
int a = 10;
int *p = &a; // p 是 int* 类型
int **pp = &p; // pp 是 int** 类型
assert(**pp == 10); // **pp 等价于 *(*pp) -> *p -> a
(3) 函数参数传递
-
&a
用于传递变量的地址(如函数修改外部变量):
void modify(int *ptr) {
*ptr = 20; // 通过指针修改外部变量的值
}
int main() {
int a = 10;
modify(&a); // 传递 a 的地址
printf("%d", a); // 输出 20
}
5. 常见错误
(1) 对非指针变量使用 *
int a = 10;
int b = *a; // 错误!a 不是指针,无法解引用
(2) 对寄存器变量使用 &
register int a = 10;
int *p = &a; // 错误!寄存器变量没有内存地址
(3) 未初始化指针的解引用
int *p; // 未初始化
int value = *p; // 未定义行为!可能崩溃或数据错误
6. 总结
-
&a
:获取变量地址,生成指针。 -
*a
:访问指针指向的值,要求a
必须是指针。 -
核心区别:
-
&a
是从数据到指针(值 → 地址)。 -
*a
是从指针到数据(地址 → 值)。
-
-
联合使用场景:多级指针、函数参数传递、动态内存管理等。