【问题标题】:Can I access every byte of a int variable through a char* pointer?我可以通过 char* 指针访问 int 变量的每个字节吗?
【发布时间】:2014-06-03 15:18:24
【问题描述】:

我想知道是否可以使用 char* 值来访问 int 值的每个字节...所以我尝试使用指针值来访问 int 的第一个字节并使用 for 循环来访问另一个整数字节...
代码如下:

int char_to_bin(char* d){
    int p= (int)*d;
    int i=0,number=0;
    if (p>=0){
        do{

            number+= (p%2)*(pow(10,i));
            i++;
            p= p/2;
            }while (p>0);
        }
    else{
        p=p *(-1);
        do{

            number+= (p%2)*pow(10,i);
            i++;
            p=p/2;
            }while (p>0);
        number*=-1;
        }

    return number;
}

long int int_to_bin(int* p){
    long int j=1,number=0,number1=0,number2=0,digits;
    char* c=&p;
    number=char_to_bin(c);
    for (j;j<(sizeof(int)/sizeof(char));j++){
        number1=char_to_bin(c+j);
        digits=floor(log10(abs(number1))) + 1;
        number2=number1*pow(10,digits);
        number=number1+number2;
    }
    return number;
}


int main(){

    char k= 100;
    char* j= &k;
    int inte=100;
    int *h;
    h= &inte;
    int c= char_to_bin(j);
    printf("%d\n",c);
    long int d= int_to_bin(h);
    printf("%ld\n",d);
}

int char_to_bin(char* d) 函数将一个指向的 char 值转换为二进制数,我对其进行的所有测试都表明它有效。但是当我在int_to_bin(int* p) 中使用int char_to_bin(char* d) 时出现问题。
基本上,int_to_bin(int* p) 应该将指向 int 的第一个字节转换为二进制,然后将后面的字节(因为 char* 指向一个字节)转换为十进制,将字节乘以 10^(位数),这样例如,我可能会得到一个像“000000001100100”这样的数字,但是出了点问题,函数的结果与二进制有很大不同,另外,我试图在 int_to_bin(int* p) 函数中放置一个 printf("%d \n",number1),如下所示:

long int int_to_bin(int* p){
    long int j=1,number=0,number1=0,number2=0,digits;
    char* c=&p;
    number=char_to_bin(c);
    for (j;j<(sizeof(int)/sizeof(char));j++){
        number1=char_to_bin(c+j);
        printf("%d \n",number1); //---------------here------------------
        digits=floor(log10(abs(number1))) + 1;
        number2=number1*pow(10,digits);
        number=number1+number2;
    }
    return number;
}

检查给定内存地址中包含的值...据我所知,int变量类型占用4个字节内存,字节内容之和就是值或者变量...但是我得到的结果与变量值完全不同。
有什么办法可以解决这个问题,还是我应该放弃并尝试将传递给int_to_bin(int* p) 的int 转换为char 并将其传递给char_to_bin(char* p) 函数?

【问题讨论】:

  • 您所说的“int”可能是“unsigned int”或“uint32”。此外,您可能应该通过执行类似 'unsigned char hi_byte = myUint32 & 0xFF00' 和 'unsigned char lo_byte = myUint32 & 0x00FF' 之类的操作来屏蔽 'uint32' 来做到这一点。

标签: c pointers


【解决方案1】:

据我所知,int变量类型占用4字节内存,而 字节内容的总和是值还是变量...

嗯,intsizeof(int) 字节,在现代 PC 操作系统(64 位和 32 位)上通常是 4,但它可以是任何东西,只要 sizeof(short) sizeof(int) sizeof(long)。所以总是使用sizeof 而不是硬编码的值。

但值不是 sum 的内容...那将非常浪费,不同顺序的相同字节会给出相同的 int。值是,取决于字节顺序,并假设无符号数:

(c[0] << 24) | (c[1] << 16) | (c[2] << 8) | (c[3] << 0); // big endian

(c[3] << 24) | (c[2] << 16) | (c[1] << 8) | (c[0] << 0); // little endian

unsigned char *c = (unsigned char*)(&amp;unsigned_int_variable);.


请注意,尽管 char* 指针是例外(请参阅 cmets),但通常将不同类型的指针设置为指向值会破坏所谓的 "strict aliasing rules",在执行此类操作之前您应该阅读相关内容。

【讨论】:

  • char * 是严格别名规则的一个例外(允许实现 memcpy 之类的东西)。但否则这是正确的。
  • @TavianBarnes 更新了关于char* 别名的答案,但与此相关的是,memcpy 接受void* 那么char* 与它有什么关系?
  • memcpy 可以通过将指针转换为char * 并复制chars 在内部实现。 char 以外的类型将违反严格的别名。
  • @TavianBarnes 我更新了一些关于严格别名的答案,你能给出第二个意见吗?
  • 您对 char 规则是“单向”是正确的,但从我对标准的阅读来看,它不适用于此处。如果你有一个char 数组并且你通过int* 访问它,那么就会有问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-15
  • 2013-01-10
  • 2020-03-10
  • 1970-01-01
  • 2021-04-27
  • 1970-01-01
  • 2015-01-15
相关资源
最近更新 更多