2016-11-07 31 views
-1

我知道有符号整数和无符号整数之间的区别在于解释整数的高位比特。 如果有指定的有符号整数,则C编译器生成代码,假定高位用作符号标志。C中的高位比特

编译器如何使用高位作为符号标志?

当我写signed int num = 23;时,它在二进制格式的内存中看起来如何?

谢谢。

+0

取决于即使它符号或无符号的CPU上:见大端endian和little-endian。 – nicomp

+0

还有更多的因素。目标体系结构使用哪种endianess? –

+0

系统的Endianness被用来确定哪个是高位或低位 – smac89

回答

2

整数意味着什么是高阶位或低阶位?

当您从左向右写入数字的二进制表示的位时,包括前导零(如果有的话),最左边的位是高位;最右边的位是低位。

当有指定的有符号整数时,C编译器生成的代码假定高位被用作符号标志? 编译器如何使用高位作为符号标志?

这是特定于编写编译器的硬件。其原因是负数的表示与CPU的算术单元结合在一起,它产生特定于给定硬件的负数表示。

当我写入signed int num = 23时,它在内存中的外观如何?

由于数是23,在存储器中它的符号表示的是相同的23无符号表示,即0x00000017十六进制与4字节的整数的计算机上的。

2

除了由daslinkenlight提供的很好的答案外,这里还有一个玩具程序程序,它打印整型的二进制表示。

例C++代码:

#include <climits> 
#include <iostream> 
#include <iomanip> 
#include <string> 
#include <type_traits> 

template<typename T, 
     typename = typename std::enable_if<std::is_integral<T>::value, T>::type> 
std::string get_raw_bytes(T t) { 
    const auto limit = sizeof(T) * CHAR_BIT; 
    std::string bits(limit, '0'); 
    for(auto i = 0; i < limit; i++) { 
    bits[limit - i - 1] = ((t >> i) & 1) ? '1' : '0'; 
    } 
    return bits; 
} 

int main() { 
    std::cout << "Integers:\n"; 
    for (int i = -5 ; i < 6 ; i++) { 
    std::cout << std::setw(4) << i << " " << get_raw_bytes(i) << '\n'; 
    } 

    std::cout << "Character:\n"; 
    std::cout << std::setw(4) << (char)104 << " " << get_raw_bytes<char>(104) << '\n'; 
} 

例C代码:

#include <stdio.h> 
#include <stdlib.h> 
#include <limits.h> 

#define INT_BITS (sizeof(int) * CHAR_BIT) 

void get_int_raw_bytes(int in, char* out) { 
    for (unsigned long i = 0 ; i < INT_BITS ; i++) { 
    out[INT_BITS - i - 1] = ((in >> i) & 1) ? '1' : '0'; 
    } 
} 

void get_char_raw_bytes(char in, char* out) { 
    for (unsigned long i = 0 ; i < CHAR_BIT ; i++) { 
    out[CHAR_BIT - i - 1] = ((in >> i) & 1) ? '1' : '0'; 
    } 
} 

int main() { 
    puts("Integers:"); 
    for (int i = -5 ; i < 6 ; i++) { 
    char buffer[INT_BITS + 1]; 
    buffer[INT_BITS] = '\0'; 
    get_int_raw_bytes(i, buffer); 
    printf("%4.d %s\n", i, buffer); 
    } 
    puts("Character:"); 
    char buffer[CHAR_BIT + 1]; 
    buffer[CHAR_BIT] = '\0'; 
    get_char_raw_bytes(104, buffer); 
    printf("%4.c %s\n", 104, buffer); 
} 

随着输出示例:

Integers: 
    -5 11111111111111111111111111111011 
    -4 11111111111111111111111111111100 
    -3 11111111111111111111111111111101 
    -2 11111111111111111111111111111110 
    -1 11111111111111111111111111111111 
    0 00000000000000000000000000000000 
    1 00000000000000000000000000000001 
    2 00000000000000000000000000000010 
    3 00000000000000000000000000000011 
    4 00000000000000000000000000000100 
    5 00000000000000000000000000000101 
Character: 
    h 01101000 
+1

AGH!我以为我有C++过滤器!无论哪种方式,问题的关键是_is_语言不可知论:(......也许我会修复它是C. – druckermanly

+0

@RadLexus感谢您的领导。我已经(几乎)在两者之间取得平衡。至少,足以让我满足于结果。 :) – druckermanly