字符是否作为整数传递给被调用的函数?

Are characters passed as integers to called functions?

我在下面编写了 C 程序来调用参数数量可变的函数。

#include<stdio.h>
#include<stdarg.h>

void display(int, int, ...);

int main()
{
    display(1,5,1,2,3,4,5);
    display(2,3,'A','B','C');
    printf("\n");
    return 0;
}

void display(int type, int tot_num, ...)
{
    int i, j;
    char c;

    va_list ptr;
    va_start (ptr, tot_num);

    switch(type)
    {
            case 1:
            for (j=0; j<tot_num; j++)
            {
                    i = va_arg (ptr, int);
                    printf("%d ",i);

            }
            break;

            case 2:
            for (j=0; j<tot_num; j++)
            {
                    c = va_arg(ptr, char);
                    printf("%c ",c);
            }
    }
}

然而,当我编译程序时,我收到来自 gcc 的警告。

-bash-4.1$ gcc varArg3.c
varArg3.c: In function âdisplayâ:
varArg3.c:41: warning: âcharâ is promoted to âintâ when passed through â...â
varArg3.c:41: note: (so you should pass âintâ not âcharâ to âva_argâ)
varArg3.c:41: note: if this code is reached, the program will abort
-bash-4.1$

第 41 行是 c = va_arg(ptr, char);

当我阅读 va_arg 的 man 3 页面时,提到如下:

如果没有下一个参数,或者类型与实际下一个参数的类型不兼容(根据默认参数提升),将发生随机错误。

当我读到这篇文章时,我认为 c = va_arg(ptr, char); 是正确的,因为可变参数列表中的数据是 characters 。然而上面 gcc 的警告表明传递的变量参数不是真正的字符而是整数。

根据 gcc 的建议,我将其更改为 c = va_arg(ptr, int);,现在我没有收到任何警告。当我 运行 程序时,我也得到了预期的输出。

那么,字符(在 main() 中对 diplay() 的第二次调用中)是否作为整数传递给 display()

谢谢。

是的 'A' 的类型是 int,试试这个

printf("typeof('A') == typeof(int) -> %s\n", 
         (sizeof('A') == sizeof(int)) ? "YES" : "NO");

自己查一下。

编辑
根据Jonathan Leffler的评论,即使您这样做也会发出警告

char a = 'A';

然后传给a,因为无论如何都会升为int,所以也就意味着

int arg = va_arg(ptr, int);

总是正确的,评论中提到的标准部分如下

§6.5.2.2

7. If the expression that denotes the called function has a type that does include a prototype, the arguments are implicitly converted, as if by assignment, to the types of the corresponding parameters, taking the type of each parameter to be the unqualified version of its declared type. The ellipsis notation in a function prototype declarator causes argument type conversion to stop after the last declared parameter. The default argument promotions are performed on trailing arguments.