关于整数数据类型和促销

时间:2013-11-06 03:17:01

标签: c

  • 平台:Linux 3.2.0 x86(Debian 7.1)
  • 编译:GCC 4.7.2(Debian 4.7.2-5)

我正在写一个整数到字符串转换函数,它接受一个参数的整数值(基数)。整数参数(radix)的有效范围非常小(2-36),小于char的最大大小。所以我想将参数声明为char,但是我必须通过所述参数乘以一个long long int,我想知道它是如何工作的。我不想将参数声明为char,如果它为计算过程添加了额外的东西。所以我的问题是当我将一个long long int乘以一个char来计算本身时会发生什么。此函数在最坏的情况下写入少量数据,这些数据小于unsigned char的最大大小,所以我想使用short int来索引它,因为当我尝试使用char取消引用指针时,我得到一个警告。所以我的问题是为什么指针不能被char取消引用,并且当我将索引的值增加或减少时,为索引使用短的int添加任何东西到解除引用过程或计算过程。这些行为是否一致,因为我听说某些系统上的16位整数数据类型在算术方面的效率实际上低于32位整数数据类型,但我不知道是否属实。

int integer_conversion(long long int integer, char *str, short int str_size, char radix)
{
    //'i' is the index variable I was talking about.
short int i = 1;
long long int radix_place = 1;

if(str == NULL) return -1;
if(str_size <= 0) return -2;

if(integer < 0)
{
            //radix_place(long long int) * radix(char)
    for(; integer / radix_place <= -radix; radix_place *= radix, i++);
    i++;

    if(i > str_size) return -4;

    str[i] = '\000';
    i--;

    if(radix >= 2 && radix <= 10)
    {
        for(; i >= 1; i--)
        {
                            //integer(long long int) mod radix(char)
            str[i] = -(integer % radix) + '0';
                            //integer(long long int) / radix(char)
            integer /= radix;
        }
    }
    else if(radix >= 11 && radix <= 36)
    {
        for(; i >= 1; i--)
        {
                            //integer(long long int) mod radix(char)
            str[i] = -(integer % radix);

                            //Is any type of conversion or promotion preformed here?
            if(str[i] <= 9) str[i] += '0';
            else str[i] += '7';

                            //integer(long long int) / radix(char)
            integer /= radix;
        }
    }
    else return 2354;

    str[0] = '-';
}
else
{
            //radix_place(long long int) * radix(char)
    for(; integer / radix_place >= radix; radix_place *= radix, i++);

    if(i > str_size) return -4;

    str[i] = '\000';
    i--;

    if(radix >= 2 && radix <= 10)
    {
        for(; i >= 0; i--)
        {
                            //integer(long long int) mod radix(char)
            str[i] = integer % radix + '0';
                            //integer(long long int) / radix(char)
            integer /= radix;
        }
    }
    else if(radix >= 11 && radix <= 36)
    {
        for(; i >= 0; i--)
        {
                            //integer(long long int) mod radix(char)
            str[i] = integer % radix;

                            //Is any type of conversion or promotion preformed here?
            if(str[i] <= 9) str[i] += '0';
            else str[i] += '7';

                            //integer(long long int) / radix(char)
            integer /= radix;
        }
    }
    else return 2354;
}

return 0;
}

1 个答案:

答案 0 :(得分:2)

两部分:

  1. 效率。在现代处理器上,在大多数地方声明类型短于int的效率没有增加效率,例如函数参数和局部变量。如果您正在为一个小型微控制器编写,那么charunsigned char参数可能会有用。

  2. 正确性。所有整数类型(包括char)将首先升级为int,除非它们不合适,在这种情况下,它们会被提升为unsigned int,除非它们不合适。然后,“通常的算术转换”将大多数操作中的两种类型都提升为相同的类型。

  3. 以下是一个例子:

    char c;
    long long x;
    return c * x;
    

    在这种情况下,结果是:

    return ((long long) c) * x;
    

    (除非,sizeof(long long) == 1CHAR_BIT == 64char默认无效。但这是一个彻头彻尾的病态案例。)

    建议

    使用int代替short

    int integer_conversion(long long int integer, char *str, int str_size, int radix)
    {
        // don't bother with "short"
        int i = 1;
        long long int radix_place = 1;
    
        if(str == NULL) return -1;
        if(str_size <= 0) return -2;