C语言中的*和&符号

转载自 https://blog.youkuaiyun.com/qq_21583681/article/details/78572009

 

之前对*和&符号一直理解的比较浅显。只知道: 
*p好像表示的是一个指针; 
&p表示的是一个地址。 
然而这次当遇到了下面这个情况的时候: 


int a = 10; 
int *b = &a;

printf(“%d\n”, a); 
printf(“%d\n”, &a); 
printf(“%d\n”, b); 
printf(“%d\n”, *b);

结果: 
10 
6487620 
6487620 
10

 

一脸懵逼,为什么&a和*b的值不是一样?这才发现自己其实一点都没有搞懂。

经过学习后,总结出来: 
变量a 本质上代表一个存储单元。CPU通过该存储单元的地址访问该存储单元中的数据。所以a本来代表两个值:存储单元的地址和储单元中的数据。于是就有了二异性。为了消除这种二义性,C语言规定a表示存储单元中的数据,&a表示存储单元的地址。 
a存储单元中的数据可以是一个普通数值,也可以是另一个存储单元的地址,比如:a = &b; 语句就是将b的存储单元的地址存入a存储单元中。C语言规定*a代表a中存储的地址对应的存储单元中的数据,也就是访问*a就等于访问b,于是*a提供了通过a访问b中的数据的手段。

a表示a对应的存储单元中的数据。 
&a表示a对应的存储单元的地址。 
*a表示:首先,要求a对应的存储单元中的数据 一定是另一个存储单元的地址。 
于是,*a表示另一个存储单元中的数据。 
当a声明的类型是int时,a中存储的是一个整数数值,通过a可以访问(读取或修改)这个数值。 
当a声明的类型是int *a中存储的是一个存储单元的地址,而该存储单元中存储的数据是一个整数数值;通过*a可以访问(读取或修改)这个数值。a == &*a 都是该存储单元的地址。 
当a声明的类型是int**时,a中存储的是一个存储单元的地址,而该存储单元中存储的数据是另外一个存储单元的地址,另外这个存储单元中存储的是一个整数数值;通过**a可以访问(读取或修改)这个数值。 

最后,在C语言里地址叫指针。还有,在C语言中的数组本质上其实也是指针,即:*a 等同于 a[]。
 

<think>好的,用户现在问的是C语言&&的区别。这个问题看起来有点基础,但需要仔细区分。首先,我需要确认用户的问题是否正确,因为“&&”看起来可能是个拼写错误。通常,C语言中的逻辑与运算符是“&&”,也就是两个&符号连在一起。而单个的&符号在C语言中有两种用途:按位与运算符取地址运算符。 首先,我要检查用户的问题是否存在拼写错误。用户写的是“&&”,中间的符号是全角的&,后面跟一个半角的&,这可能是在输入时的错误。但为了确保,我需要考虑两种情况:一种是用户可能想输入“&&”,即逻辑与运算符;另一种是确实想问“&”“&&”的区别,这可能需要指出全角半角符号的问题。 接下来,我需要明确C语言中的运算符。单&符号作为取地址运算符,用于获取变量的内存地址,例如在scanf中使用&a。而作为按位与运算符时,它用于对两个整数的二进制位进行与操作。另一方面,&&是逻辑与运算符,用于布尔表达式,判断两个条件是否都为真。 用户可能是在学习指针运算符时产生了混淆。例如,他们可能在代码中同时看到了&&&,但不清楚两者的区别。这时候需要分清楚两者的不同使用场景,以及语法上的差异。 另外,用户提到的“&&”中的第一个符号如果是全角字符,这在C语言中是不允许的,因为C语言要求所有的运算符都使用半角字符。因此,这可能是一个输入错误,需要提醒用户注意符号的正确输入方式。 接下来,我需要组织回答的结构。首先解释每个符号的用途,再对比它们的区别。可能还需要给出代码示例,帮助用户理解。同时,要强调全角半角符号的问题,避免用户因为输入错误导致编译失败。 需要注意的是,用户的英语水平可能有限,或者对编程术语不熟悉,因此要使用简单明了的中文解释,避免使用过于专业的术语,必要时举例说明。 可能用户的实际需求是理解代码中出现的&&&,特别是在条件判断指针操作中的不同应用。例如,他们可能在if语句中看到了&&,而在变量前看到了&,但不知道两者的区别。这时候需要明确两者的不同用途,以及在不同上下文中的意义。 总结来说,回答需要涵盖以下几点: 1. &作为取地址运算符的用法。 2. &作为按位与运算符的用法。 3. &&作为逻辑与运算符的用法。 4. 全角半角符号的问题(如果适用)。 5. 通过代码示例展示不同情况下的使用。 6. 强调两者在功能使用场景上的区别。 在回答时,要确保内容准确,结构清晰,帮助用户逐步理解每个符号的作用,并避免常见的错误。此外,提醒用户注意代码中的拼写错误符号的正确使用,特别是在初学阶段容易混淆的地方。</think>在C语言中,`&` `&&` 是完全不同的运算符。它们的核心区别在于**用途操作方式**,以下是详细解析: --- ### 一、`&` 运算符的两种用途 #### 1. **取地址运算符**(Address Operator) - **功能**:获取变量的内存地址 - **语法**:`&变量名` - **使用场景**:主要用于指针操作`scanf`输入 - **示例**: ```c int a = 10; int *p = &a; // p保存a的内存地址 scanf("%d", &a); // 通过地址修改变量a的值 ``` #### 2. **按位与运算符**(Bitwise AND) - **功能**:对两个整数的二进制位进行逐位与运算 - **语法**:`数值1 & 数值2` - **运算规则**:全1得1,有0则0 - **示例**: ```c int x = 5; // 二进制 0101 int y = 3; // 二进制 0011 int z = x & y; // 结果 0001(十进制1) ``` --- ### 二、`&&` 运算符的用途 #### **逻辑与运算符**(Logical AND) - **功能**:判断两个条件是否**同时为真** - **语法**:`条件1 && 条件2` - **运算规则**: - 若`条件1`为假 → 直接返回`0`(短路特性,不计算`条件2`) - 若`条件1`为真 → 返回`条件2`的真假结果 - **示例**: ```c int a = 5, b = 10; if (a > 0 && b < 20) { // 判断两个条件是否同时满足 printf("条件成立"); } ``` --- ### 三、关键对比表格 | 特性 | `&`(按位与) | `&&`(逻辑与) | `&`(取地址) | |---------------|---------------|----------------|---------------| | **操作对象** | 整数 | 布尔表达式 | 变量 | | **结果类型** | 整数 | `0`或`1` | 指针(地址) | | **短路特性** | 无 | 有 | 无 | | **典型用途** | 位掩码操作 | 条件判断 | 指针初始化 | --- ### 四、常见错误场景 #### 1. **混淆逻辑与按位与** ```c int x = 5, y = 3; if (x & y) { // 实际判断 0101 & 0011 = 0001 → if(1) printf("按位与结果为真"); } if (x && y) { // 判断 5!=0 且 3!=0 → 真 printf("逻辑与条件成立"); } ``` #### 2. **误用取地址符** ```c int a = 10; int *p = a; // 错误!未使用&获取地址 int *p = &a; // 正确写法 ``` #### 3. **全角符号问题** ```c if (a && b) { // 错误!使用全角符号`&` // 编译报错:error: expected expression } ``` --- ### 五、扩展理解 #### 1. **运算符优先级** - `&`(按位与)优先级高于`&&`(逻辑与) - 使用括号明确优先级: ```c (a & b) && (c | d) // 更清晰的写法 ``` #### 2. **地址操作本质** ```c int arr[3] = {1,2,3}; printf("%p", &arr[0]); // 输出数组首元素地址 ``` #### 3. **布尔值的本质** C语言中: - `0` 表示假 - **非0值**均视为真 ```c int x = 5, y = 0; printf("%d", x && y); // 输出0(因为y为0) ``` --- ### 六、记忆技巧 1. **单`&`**: - 需要地址 → 取地址(`&a`) - 处理二进制 → 按位与(`a & b`) 2. **双`&&`**: - 需要同时满足条件 → 逻辑与(`条件1 && 条件2`) 3. **符号验证**: - 确保使用半角符号(`&``&&`,而非全角`&`) --- 通过理解运算符的底层逻辑具体应用场景,可以避免常见的编码错误。建议在实际编码时结合编译器的错误提示进行调试(例如GCC会明确提示`expected ‘;’ before ‘&&’`等错误)。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值