C中的异或相同数据导致非零值。为什么?

C中的异或相同数据导致非零值。为什么?,c,pointers,xor,C,Pointers,Xor,如何对指针指向的两个数据段进行异或运算 我已经尝试过这个,一个基于stackoverflow的类似解决方案,但是输出不是我所期望的 代码如下: void printXor(){ int j; char* c = strdup("hey"); for(j = 0; j < strlen(c); j++){ c[j] ^= c[j]; } printf("%d\n", *(int*)(c)); } void printXor(

如何对指针指向的两个数据段进行异或运算

我已经尝试过这个,一个基于stackoverflow的类似解决方案,但是输出不是我所期望的

代码如下:

void printXor(){    
    int j;
    char* c = strdup("hey");
    for(j = 0; j < strlen(c); j++){
        c[j] ^= c[j];
    }

    printf("%d\n", *(int*)(c));
}
void printXor(){
int j;
char*c=strdup(“嘿”);
对于(j=0;j

但是输出是:
7955712
。输出不应该是0吗?我将“hey”与“hey”进行异或运算,其int值为0,对吗?

看看这个循环:

for(j = 0; j < strlen(c); j++) {
    c[j] ^= c[j];
}
(j=0;j 您正在修改
c
,并使用
strlen
计算其长度。在第一个迭代器之后,strlen
返回0,循环停止


如果将
7955712
转换为十六进制,则为
0x796500
。0x79是
'y'
的代码,
0x65
'e'
的代码,最低有效字节是
0x00
。由于您在一台小型endian计算机上运行此操作,因此会得到一个空字符串。

严格来说,由于将
字符
数组作为
int
读取时出现了别名冲突,因此代码的行为未定义

你可以把问题的症结重铸到一个明确的层次

#include <stdio.h>
#include <stdint.h>
int main(){    

    int32_t n;
    char* c = &n;
    c[0] = 'h';
    c[1] = 'e';
    c[2] = 'y';
    c[3] = 0;

    for( int j = 0; j < strlen(c); j++){
        c[j] ^= c[j];
    }
    printf("%" PRId32 "\n", n);
}
#包括
#包括
int main(){
int32_t n;
char*c=&n;
c[0]=‘h’;
c[1]=“e”;
c[2]=“y”;
c[3]=0;
对于(int j=0;j

由于
strlen
的后续值将为0,因为
c[0]
将对NUL终止符求值,因此只有
for
循环的一次迭代运行,因此输出不是零。

@EugeneSh
c
指向四个字节中的第一个。您正在用
*(int*)(c)
打破严格的别名,因此遭受未定义行为的折磨。@Ivan任何东西都可以作为字符数组访问,但不能以相反的方式访问。@Ivan但不能反之亦然…是的,有效类型的问题是,
malloc
ed内存已经被分配器本身访问过,因此严格来说,它不是一个
char
int
,而是其他的东西。标准在这里似乎不是很有用。不,不是这样。分配的字符数组长度为4字节,与int相同。因此,当数据在自身上进行异或运算时,在4字节内存中,应该到处都是零。之后,我将这个4字节内存作为int读取。有什么问题吗?@DataChanturia您没有对所有内容进行XOR运算,只有第一个元素。当循环的条件在第一次迭代后重新计算时,它会看到
strlen(c)
返回
0
,因此循环在一次迭代后停止。@DataChanturia:No.No.No。
循环在第一次迭代后终止。@DataChanturia-Huh?您可以使用xor
char
s,而不是
int
s。没错!斯特伦(c)就是问题所在(起初误解了这一点)。