1. 运算符优先级
在C语言中,运算符的优先级决定了在表达式中各个运算符的执行顺序。当一个表达式中有多个运算符时,优先级高的运算符会先被计算。如果两个运算符的优先级相同,那么它们的结合性(从左到右或从右到左)会决定它们的计算顺序。
以下是一些基本的C语言运算符优先级(从高到低):
-
后缀运算符:例如数组下标
[]
、函数调用()
、成员访问.
和->
、后缀递增++
和后缀递减--
。 -
一元运算符:例如前缀递增
++
、前缀递减--
、取地址&
、解引用*
、正负号+
和-
、位非~
、逻辑非!
、类型转换(type)
、大小操作符sizeof
。 -
乘法运算符:
*
(乘法)、/
(除法)、%
(取模)。 -
加法运算符:
+
(加法)、-
(减法)。 -
位移运算符:
<<
(左移)、>>
(右移)。 -
关系运算符:
<
(小于)、<=
(小于等于)、>
(大于)、>=
(大于等于)。 -
相等运算符:
==
(等于)、!=
(不等于)。 -
位与运算符:
&
。 -
位异或运算符:
^
。 -
位或运算符:
|
。 -
逻辑与运算符:
&&
。 -
逻辑或运算符:
||
。 -
条件运算符:
? :
。 -
赋值运算符:例如
=
、+=
、-=
、*=
、/=
、%=
、<<=
、>>=
、&=
、^=
、|=
。 -
逗号运算符:
,
。
当表达式中的运算符优先级相同时,它们会按照从左到右的顺序进行计算,除非运算符的结合性是从右到左(例如赋值运算符和条件运算符)。
例如,在表达式a = b + c * d
中,乘法运算符*
的优先级高于加法运算符+
,所以c * d
会先被计算,然后其结果再与b
相加,最后赋值给a
。
了解运算符的优先级对于编写正确和易于理解的代码是非常重要的。如果需要改变默认的运算顺序,可以使用括号来明确指定优先级。
例题:
#include <iostream>
int main() {
int i = 10;
printf("%d", i %= 2 ? 1 : 2);
return 0;
}
上述代码的输出为什么是0而不是2?
上述代码的输出是0而不是2,是因为在C++中,条件运算符(? :)的优先级高于赋值运算符(=)。
根据C++的运算符优先级规则,条件运算符的优先级高于赋值运算符。因此,在执行i %= 2 ? 1 : 2
时,先进行条件运算符的判断,然后根据判断结果进行赋值操作。
具体来说,首先计算i %= 2
,即i = i % 2
,将i
的值更新为10 % 2
的结果,即0。然后,根据条件运算符的判断结果,如果条件为真(非零),则取第二个操作数的值,即2;如果条件为假(零),则取第三个操作数的值,即1。
由于i
的值为0,满足条件运算符的条件(非零),所以最终的结果是2。但是,由于printf函数中的格式化字符串是"%d",它只会输出整数部分,而不会输出小数部分。因此,即使结果为2,输出仍然是0。
swtich括号内的数据只能是整型?
在C语言中,switch
语句括号内的表达式的结果必须是一个整数类型(包括 char
,因为 char
在C语言中本质上是一种小的整数类型)。这意味着你不能直接使用浮点数、字符串或其他非整数类型的值作为 switch
语句的条件。
然而,你可以通过一些转换或技巧来使用非整数类型的值。例如,如果你有一个浮点数并且想基于它的整数部分进行切换,你可以将其转换为整数。对于字符串,你可以使用字符串的哈希值或某种形式的编码作为 switch
语句的条件。
但请注意,这样的做法可能会使代码变得复杂且难以维护,因此在实践中并不常见。对于非整数类型的值,通常更推荐使用 if
和 else if
语句进行条件判断。
总结来说,虽然 switch
语句在C语言中主要用于整数类型的值,但通过一些技巧,你也可以间接地使用非整数类型的值。然而,这通常不是最佳实践,除非有特定的需求或理由。
c语言函数内部定义的临时变量有默认赋值吗?
在C语言中,如果你在函数内部定义了临时变量(也称为局部变量),那么这些变量不会自动被赋予默认值。它们的初始值是未定义的,这意味着它们包含的是它们所在内存位置的当前值,这些值可能是随机的、不可预测的,并且可能包含垃圾值。
为了避免使用未初始化的变量,你应该在声明变量时立即给它们赋值。这样,你就可以确保你的程序使用的是预期的值,而不是内存中的随机值。
例如:
int myFunction() {
int myVar = 0; // 初始化为0
// ... 其他代码 ...
return myVar;
}
在这个例子中,myVar
被初始化为0,所以你可以安全地在后续的代码中使用它,而不必担心它包含的是未定义的值。