我在学校学习C,我有这个问题,而且我在解决它时遇到了麻烦。
以下代码有何作用?
#define N (100)
int main(void)
{
unsigned short i = 0;
unsigned long arr[2*N + 1];
unsigned long a = 0;
for (i = 0 ; i < N ; ++i) {
a ^= arr[i];
}
printf("%lu", a);
return 0;
}
如果你可以向我解释,那将会非常有用! 谢谢!
答案 0 :(得分:1)
解释你理解的内容通常是一个好主意,所以我们不必像对待 nothing 一样对待你。 重要提示:此代码的行为不正常。我稍后会讨论。
独占或运算符(^
)通过将以下模式应用于相关数字的二进制表示来生成其结果:
1
位。例如,如果左侧包含最右侧的0位且右侧包含最右侧的1位,则结果将包含最右侧的1位。例如,15 ^ 1
的操作数具有以下二进制表示法:
1111 ^
0001
......此独家或操作的结果将是:
1110
转换回十进制,那是14.再次为1,你最终会回到15(这是傻xor交换利用的属性)。
array[index]
运算符在array
所指示的位置获取index
内的元素。
^=
运算符是复合运算符。它结合了exclusive或赋值运算符。 a ^= arr[i];
大致相当于a = a ^ arr[i];
。这意味着:计算a
和arr[i]
的异或,并将其分配回a
。
for (i = 0 ; i < N ; ++i) /*
* XXX: Insert statement or block of code
*/
这表示一个循环,它将首先将值0
赋给i
,在i
小于N
时重复执行语句或代码块(100),每次递增i
。
总之,此代码生成数组arr
的独占或前100个元素。这是粗校验和算法的一种形式;我们的想法是获取一组值并将它们减少为单个值,以便您可以在以后执行某种形式的完整性检查,也许是在它们通过互联网或不可靠的文件系统进行传播之后。
但是,此代码调用未定义的行为,因为它使用未指定的值。为了避免不可预测的值或段错误等不稳定的行为(或更糟糕的是, heartbleed OpenSSL漏洞)您需要确保在尝试使用这些值之前提供变量值。
以下声明会明确地将第一个元素初始化为42
,并隐式地将所有其他元素初始化为0
:
unsigned long arr[2*N + 1] = { 42 };
重要的是要认识到,如果您希望任何未明确初始化的元素归零,则声明 = { ... }
的初始化部分是必需的。
答案 1 :(得分:0)
此功能将打印不可预测的值。
因为unsigned long arr[2*N + 1];
arr未初始化,并且它将根据您内存中的数据具有随机内容。
a ^= arr[i];
等于a = a^arr[i];
所以它会多次执行此操作(因为循环)然后会打印它。