本文介绍了更好地理解c中可变参数的类型提升的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在c中调用变量参数函数时,整数参数提升为int,浮点参数提升为double

int 类型在32位计算机上应为4字节,在64位计算机上应为8字节,对吗?

所以我想知道在传递<$ c时追加什么内容$ c> long long int 到变量参数函数,如printf,格式为%lld

而且,我想知道当我将 long double 变量传递给具有%Lf 格式的printf时追加什么内容(无论是32还是64位计算机)。



[ Edited ]



在32位计算机上,我尝试过:

  #include< stdio.h> 

int main(void)
{
printf( sizeof(int)%d\n,sizeof(int));
printf( sizeof(long int)%d\n,sizeof(long int));
printf( sizeof(long long int)%d\n,sizeof(long long int));
printf(%lld\n,1LL
printf( sizeof(float)%d\n,sizeof(float));
printf( sizeof(double)%d\n,sizeof(double));
printf( sizeof(long double)%d\n,sizeof(long double));
返回0;
}

结果是:

  sizeof(int)4 
sizeof(long int)4
sizeof(long long int)8
8589934592
sizeof(float )4
sizeof(double)8
sizeof(long double)12

这使我认为并非所有参数都提升为 int ,否则我将得到打印0而不是8589934592。



也许只有小于 int 的参数才被提升为 int 。浮点类型也可能类似。



[已编辑]



在64位计算机上,我运行以下命令:

  int main(void)
{
printf( sizeof(int)%lu\n,sizeof(int));
printf( sizeof(long)%lu\n,sizeof(long));
printf( sizeof(long long)%lu\n,sizeof(long long));
返回0;
}

并获得

  sizeof(int)4 
sizeof(long)8
sizeof(long long)8

如果我对标准理解得很好,则只有 char short 被提升为 int 。我不知道在较小的体系结构中会发生什么,例如16位或8位MCU。我认为 int 的大小取决于体系结构,但是我想知道 sizeof(int)能否在8位上为1建筑。在这种情况下,除非丢失一些位


short 提升为 int div class = h2_lin>解决方案

int 类型在32位计算机上应为4字节,在64位计算机上应为8字节,对?否。根据标准,,但没有其他规定。



当您将 long long int 传递给 printf()时,则不受此限制到:

printf()语句与这些促销和转化无关,除非在指定者及其相应参数的类型不匹配的情况下会出现不确定的行为。



因此,执行了整数提升,并且 float s转换为 double s,但是。



解决您的问题:这使我认为并非所有参数都提升为 int 。正确。只有整数转换等级为小于或等于 int unsigned int 的等级的整数类型才适用整数促销。对于浮点类型,它更简单; float 被提升为 double 。就是这样。



根据,存在三种实际的浮点类型, float double long double float 可以保存的值是 double 可以保存的值的子集,依次是长double 可以保存的值的子集。因此, long double 类型没有晋升的可能性。



根据:

因此,没有 long int long int 的可能性曾经被提升为 int unsigned int



最后,您担心推广在某些实现中,将简短的替换为 int 可能是不可能的,而且不会丢失一些位,请注意保证 t 必须能够包含 short ,因为 int 的转换等级必须大于 short 的值:


When a variable argument function is called in c the integer parameters are promoted to int and floating point parameters are promoted to double

int type should be 4 byte on 32 bit machines and 8 byte on 64 bit machines, is that right?
So I wonder what append when I pass a long long int to a variable argument function like printf with %lld format.
And, again, I wonder what append when I pass a long double variable to printf with %Lf format (no matter if on 32 or 64 bit machines).

[Edited]

on a 32 bit machine, I tried this:

#include <stdio.h>

int main(void)
{
    printf("sizeof(int) %d\n", sizeof(int));
    printf("sizeof(long int) %d\n", sizeof(long int));
    printf("sizeof(long long int) %d\n", sizeof(long long int));
    printf("%lld\n", 1LL<<33);

    printf("sizeof(float) %d\n", sizeof(float));
    printf("sizeof(double) %d\n", sizeof(double));
    printf("sizeof(long double) %d\n", sizeof(long double));
    return 0;
}

The result is:

sizeof(int) 4
sizeof(long int) 4
sizeof(long long int) 8
8589934592
sizeof(float) 4
sizeof(double) 8
sizeof(long double) 12

this makes me think that not all parameters are promoted to int, otherwise I would get printed 0 instead of 8589934592.

Maybe only arguments smaller than int are promoted to int. And something similar could be for floating point types.

[Edited]

on a 64 bit machine I run this:

int main(void)
{
    printf("sizeof(int) %lu\n", sizeof(int));
    printf("sizeof(long) %lu\n", sizeof(long));
    printf("sizeof(long long) %lu\n", sizeof(long long));
    return 0;
}

and get

sizeof(int) 4
sizeof(long) 8
sizeof(long long) 8

if I understand well the standard, only char and short are promoted to int. I wonder what happen in smaller architecture, such like 16 bit or 8 bit MCU. I think that int size is dependent by architecture, but I wonder if sizeof(int) can be 1 on 8 bit architecture. In this case promotion of short to int could be impossible unless loosing some bits

解决方案

"int type should be 4 byte on 32 bit machines and 8 byte on 64 bit machines, is that right?" No. According to the Standard, ints must be at least 16 bits in width (§5.2.4.2.1), but there is no further stipulation.

When you pass a long long int to printf() it is not subject to the integer promotions (§6.3.1.1 2):

If you pass a long double to printf() no conversion is made (§6.5.2.2 6):

The conversion specifiers corresponding to the arguments in the printf() statement have no bearing on these promotions and conversions, except insofar as there will be undefined behavior if the specifiers and the types of their corresponding arguments do not match.

So, the integer promotions are performed, and floats are converted to doubles, but "No other conversions are performed implicitly" (§6.5.2.2 8).

Addressing your edit to the question: "this makes me think that not all parameters are promoted to int." Correct. Only integer types with integer conversion rank "less than or equal to the rank of int and unsigned int" are subject to integer promotion. It is simpler for floating point types; floats are promoted to double. That is all.

It may be worth pointing out that, according to §6.2.5 10, there are three real floating point types, float, double, and long double. The values which may be held by a float are a subset of the values which may be held by a double, which are in turn a subset of the values which may be held by a long double. Hence, there is no possibility of promotion for long double types.

Further, according to §6.3.1.1 1:

So there is no possibility of a long long int or long int ever being promoted to int or unsigned int.

As for your final concern that promotion of a short to an int may, in some implementation, be impossible without losing some bits, note that §6.2.5 8 guarantees that an int must be able to contain a short, since the conversion rank of an int must be greater than that of a short:

这篇关于更好地理解c中可变参数的类型提升的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 08:23