Type conversion - unsigned to signed int/char

本文详细解释了C语言中不同类型变量进行比较时的隐式类型转换规则,包括整数提升和常规算术转换等概念,并通过具体示例阐述了这些规则如何影响程序的输出结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Q:

I tried the to execute the below program:

#include <stdio.h>

int main() {
    signed char a = -5;
    unsigned char b = -5;
    int c = -5;
    unsigned int d = -5;

    if (a == b)
        printf("\r\n char is SAME!!!");
    else
        printf("\r\n char is DIFF!!!");

    if (c == d)
        printf("\r\n int is SAME!!!");
    else
        printf("\r\n int is DIFF!!!");

    return 0;
}

For this program, I am getting the output:

char is DIFF!!! int is SAME!!!

Why are we getting different outputs for both?
Should the output be as below ?

char is SAME!!! int is SAME!!!

A1:

This is because of the various implicit type conversion rules in C. There are two of them that a C programmer must know: the usual arithmetic conversions and the integer promotions (the latter are part of the former).

In the char case you have the types (unsigned char) == (signed char). These are both small integer types. Other such small integer types are bool and short. The integer promotion rules state that whenever a small integer type is an operand of an operation, its type will get promoted to int, which is signed. This will happen no matter if the type was signed or unsigned.

In the case of the signed char, the sign will be preserved and it will be promoted to an intcontaining the value -5. In the case of the unsigned char, it contains a value which is 251 (0xFB ). It will be promoted to an int containing that same value. You end up with

if( (int)-5 == (int)251 )

In the integer case you have the types  (unsigned int) == (signed int) . They are not small integer types, so the integer promotions do not apply. Instead, they are balanced by  the usual arithmetic conversions , which state that if two operands have the same "rank" (size) but different signedness, the signed operand is converted to the same type as the unsigned one. You end up with

if( (unsigned int)-5 == (unsigned int)-5)

A2:

Cool question!

The int comparison works, because both ints contain exactly the same bits, so they are essentially the same. But what about the chars?

Ah, C implicitly promotes chars to ints on various occasions. This is one of them. Your code saysif(a==b), but what the compiler actually turns that to is:

if((int)a==(int)b) 

(int)a is -5, but (int)b is 251. Those are definitely not the same.

EDIT: As @Carbonic-Acid pointed out, (int)b is 251 only if a char is 8 bits long. If int is 32 bits long, (int)b is -32764.

REDIT: There's a whole bunch of comments discussing the nature of the answer if a byte is not 8 bits long. The only difference in this case is that (int)b is not 251 but a different positive number, which isn't -5. This is not really relevant to the question which is still very cool.

From: http://stackoverflow.com/questions/17312545/type-conversion-unsigned-to-signed-int-char
#ifndef __INA219_H #define __INA219_H #include "config.h" // I2C Address Options #define INA219_I2C_ADDRESS_CONF_0 (u8)(0x40 << 1) // A0 = GND, A1 = GND #define INA219_I2C_ADDRESS_CONF_1 (u8)(0x41 << 1) // A0 = VS+, A1 = GND #define INA219_I2C_ADDRESS_CONF_2 (u8)(0x42 << 1) // A0 = SDA, A1 = GND #define INA219_I2C_ADDRESS_CONF_3 (u8)(0x43 << 1) // A0 = SCL, A1 = GND #define INA219_I2C_ADDRESS_CONF_4 (u8)(0x44 << 1) // A0 = GND, A1 = VS+ #define INA219_I2C_ADDRESS_CONF_5 (u8)(0x45 << 1) // A0 = VS+, A1 = VS+ #define INA219_I2C_ADDRESS_CONF_6 (u8)(0x46 << 1) // A0 = SDA, A1 = VS+ #define INA219_I2C_ADDRESS_CONF_7 (u8)(0x47 << 1) // A0 = SCL, A1 = VS+ #define INA219_I2C_ADDRESS_CONF_8 (u8)(0x48 << 1) // A0 = GND, A1 = SDA #define INA219_I2C_ADDRESS_CONF_9 (u8)(0x49 << 1) // A0 = VS+, A1 = SDA #define INA219_I2C_ADDRESS_CONF_A (u8)(0x4A << 1) // A0 = SDA, A1 = SDA #define INA219_I2C_ADDRESS_CONF_B (u8)(0x4B << 1) // A0 = SCL, A1 = SDA #define INA219_I2C_ADDRESS_CONF_C (u8)(0x4C << 1) // A0 = GND, A1 = SCL #define INA219_I2C_ADDRESS_CONF_D (u8)(0x4D << 1) // A0 = VS+, A1 = SCL #define INA219_I2C_ADDRESS_CONF_E (u8)(0x4E << 1) // A0 = SDA, A1 = SCL #define INA219_I2C_ADDRESS_CONF_F (u8)(0x4F << 1) // A0 = SCL, A1 = SCL #define INA219_I2C_ADDRESS INA219_I2C_ADDRESS_CONF_0 /*----------------------------------------------------------------------------*/ // Register Addresses #define INA219_REG_CONFIG (u8)(0x00) // CONFIG REGISTER (R/W) #define INA219_REG_SHUNTVOLTAGE (u8)(0x01) // SHUNT VOLTAGE REGISTER (R) #define INA219_REG_BUSVOLTAGE (u8)(0x02) // BUS VOLTAGE REGISTER (R) #define INA219_REG_POWER (u8)(0x03) // POWER REGISTER (R) #define INA219_REG_CURRENT (u8)(0x04) // CURRENT REGISTER (R) #define INA219_REG_CALIBRATION (u8)(0x05) // CALIBRATION REGISTER (R/W) /*----------------------------------------------------------------------------*/ // Macros for assigning config bits #define INA219_CFGB_RESET(x) (u16)((x & 0x01) << 15) // Reset Bit #define INA219_CFGB_BUSV_RANGE(x) (u16)((x & 0x01) << 13) // Bus Voltage Range #define INA219_CFGB_PGA_RANGE(x) (u16)((x & 0x03) << 11) // Shunt Voltage Range #define INA219_CFGB_BADC_RES_AVG(x) (u16)((x & 0x0F) << 7) // Bus ADC Resolution/Averaging #define INA219_CFGB_SADC_RES_AVG(x) (u16)((x & 0x0F) << 3) // Shunt ADC Resolution/Averaging #define INA219_CFGB_MODE(x) (u16) (x & 0x07) // Operating Mode /*----------------------------------------------------------------------------*/ // Configuration Register #define INA219_CFG_RESET INA219_CFGB_RESET(1) // Reset Bit #define INA219_CFG_BVOLT_RANGE_MASK INA219_CFGB_BUSV_RANGE(1) // Bus Voltage Range Mask #define INA219_CFG_BVOLT_RANGE_16V INA219_CFGB_BUSV_RANGE(0) // 0-16V Range #define INA219_CFG_BVOLT_RANGE_32V INA219_CFGB_BUSV_RANGE(1) // 0-32V Range (default) #define INA219_CFG_SVOLT_RANGE_MASK INA219_CFGB_PGA_RANGE(3) // Shunt Voltage Range Mask #define INA219_CFG_SVOLT_RANGE_40MV INA219_CFGB_PGA_RANGE(0) // Gain 1, 40mV Range #define INA219_CFG_SVOLT_RANGE_80MV INA219_CFGB_PGA_RANGE(1) // Gain 2, 80mV Range #define INA219_CFG_SVOLT_RANGE_160MV INA219_CFGB_PGA_RANGE(2) // Gain 4, 160mV Range #define INA219_CFG_SVOLT_RANGE_320MV INA219_CFGB_PGA_RANGE(3) // Gain 8, 320mV Range (default) #define INA219_CFG_BADCRES_MASK INA219_CFGB_BADC_RES_AVG(15) // Bus ADC Resolution and Averaging Mask #define INA219_CFG_BADCRES_9BIT_1S_84US INA219_CFGB_BADC_RES_AVG(0) // 1 x 9-bit Bus sample #define INA219_CFG_BADCRES_10BIT_1S_148US INA219_CFGB_BADC_RES_AVG(1) // 1 x 10-bit Bus sample #define INA219_CFG_BADCRES_11BIT_1S_276US INA219_CFGB_BADC_RES_AVG(2) // 1 x 11-bit Bus sample #define INA219_CFG_BADCRES_12BIT_1S_532US INA219_CFGB_BADC_RES_AVG(3) // 1 x 12-bit Bus sample (default) #define INA219_CFG_BADCRES_12BIT_2S_1MS INA219_CFGB_BADC_RES_AVG(9) // 2 x 12-bit Bus samples averaged together #define INA219_CFG_BADCRES_12BIT_4S_2MS INA219_CFGB_BADC_RES_AVG(10) // 4 x 12-bit Bus samples averaged together #define INA219_CFG_BADCRES_12BIT_8S_4MS INA219_CFGB_BADC_RES_AVG(11) // 8 x 12-bit Bus samples averaged together #define INA219_CFG_BADCRES_12BIT_16S_8MS INA219_CFGB_BADC_RES_AVG(12) // 16 x 12-bit Bus samples averaged together #define INA219_CFG_BADCRES_12BIT_32S_17MS INA219_CFGB_BADC_RES_AVG(13) // 32 x 12-bit Bus samples averaged together #define INA219_CFG_BADCRES_12BIT_64S_34MS INA219_CFGB_BADC_RES_AVG(14) // 64 x 12-bit Bus samples averaged together #define INA219_CFG_BADCRES_12BIT_128S_68MS INA219_CFGB_BADC_RES_AVG(15) // 128 x 12-bit Bus samples averaged together #define INA219_CFG_SADCRES_MASK INA219_CFGB_SADC_RES_AVG(15) // Shunt ADC Resolution and Averaging Mask #define INA219_CFG_SADCRES_9BIT_1S_84US INA219_CFGB_SADC_RES_AVG(0) // 1 x 9-bit Shunt sample #define INA219_CFG_SADCRES_10BIT_1S_148US INA219_CFGB_SADC_RES_AVG(1) // 1 x 10-bit Shunt sample #define INA219_CFG_SADCRES_11BIT_1S_276US INA219_CFGB_SADC_RES_AVG(2) // 1 x 11-bit Shunt sample #define INA219_CFG_SADCRES_12BIT_1S_532US INA219_CFGB_SADC_RES_AVG(3) // 1 x 12-bit Shunt sample (default) #define INA219_CFG_SADCRES_12BIT_2S_1MS INA219_CFGB_SADC_RES_AVG(9) // 2 x 12-bit Shunt samples averaged together #define INA219_CFG_SADCRES_12BIT_4S_2MS INA219_CFGB_SADC_RES_AVG(10) // 4 x 12-bit Shunt samples averaged together #define INA219_CFG_SADCRES_12BIT_8S_4MS INA219_CFGB_SADC_RES_AVG(11) // 8 x 12-bit Shunt samples averaged together #define INA219_CFG_SADCRES_12BIT_16S_8MS INA219_CFGB_SADC_RES_AVG(12) // 16 x 12-bit Shunt samples averaged together #define INA219_CFG_SADCRES_12BIT_32S_17MS INA219_CFGB_SADC_RES_AVG(13) // 32 x 12-bit Shunt samples averaged together #define INA219_CFG_SADCRES_12BIT_64S_34MS INA219_CFGB_SADC_RES_AVG(14) // 64 x 12-bit Shunt samples averaged together #define INA219_CFG_SADCRES_12BIT_128S_68MS INA219_CFGB_SADC_RES_AVG(15) // 128 x 12-bit Shunt samples averaged together #define INA219_CFG_MODE_MASK INA219_CFGB_MODE(7) // Operating Mode Mask #define INA219_CFG_MODE_POWERDOWN INA219_CFGB_MODE(0) // Power-Down #define INA219_CFG_MODE_SVOLT_TRIGGERED INA219_CFGB_MODE(1) // Shunt Voltage, Triggered #define INA219_CFG_MODE_BVOLT_TRIGGERED INA219_CFGB_MODE(2) // Bus Voltage, Triggered #define INA219_CFG_MODE_SANDBVOLT_TRIGGERED INA219_CFGB_MODE(3) // Shunt and Bus, Triggered #define INA219_CFG_MODE_ADCOFF INA219_CFGB_MODE(4) // ADC Off (disabled) #define INA219_CFG_MODE_SVOLT_CONTINUOUS INA219_CFGB_MODE(5) // Shunt Voltage, Continuous #define INA219_CFG_MODE_BVOLT_CONTINUOUS INA219_CFGB_MODE(6) // Bus Voltage, Continuous #define INA219_CFG_MODE_SANDBVOLT_CONTINUOUS INA219_CFGB_MODE(7) // Shunt and Bus, Continuous (default) /*----------------------------------------------------------------------------*/ // Bus Voltage Register #define INA219_BVOLT_CNVR (u16)(0x0002) // Conversion Ready #define INA219_BVOLT_OVF (u16)(0x0001) // Math Overflow Flag struct ina219_value_t { int16 voltage; int32 shunt; int32 current; int32 power; }; extern void drv_ina219_init(void); extern int16 ina219_GetBusVoltage_mV(void); extern int32 ina219_GetShuntVoltage_uV(void); extern int32 ina219_GetCurrent_uA(void); extern int32 ina219_GetPower_mW(void); extern void ina219_process(void); #endif //__DRV_INA219_H__ C51的结构体怎么跨文件调用
最新发布
07-18
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值