c-预期参数的警告消息



我的编译器上似乎有此警告[警告]格式"%s"需要类型为"char*"的参数,但参数2的类型为"int"[-Wformat=]。我不太明白它说参数2的类型是"int",因为我认为数据类型应该是"char"。有人知道为什么我的代码有这个警告吗?

#include <stdio.h>
typedef struct {
int ID;
char model;
float price;
}car;
car cardetails[5];
int main()
{

int i;

for (i = 1; i < 6; i++)
{
printf("nCar[%d] ID: ", i); 
scanf("%d", &cardetails[i].ID);

printf("Car[%d] Model: ", i); 
scanf("%s", &cardetails[i].model);

printf("Car[%d] Price: ", i); 
scanf("%f", &cardetails[i].price);
}

float average = 0;

for (i = 1; i < 6; i++){
average =+ cardetails[i].price;
}

average = average / 5;

for(i = 1; i < 6; i++){
printf("Car ID: %d", cardetails[i].ID);
printf("Model: %s", cardetails[i].model);
printf("Price: %f", cardetails[i].price);
i = i + 2;
}

return 0;
}

char model;只能容纳一个字符;模型名称通常由多个字符组成。您需要char model[32];或类似的定义。

printf("Model: %s", cardetails[i].model)行将单个字符传递给printf(),但%s行告诉printf()期待char *

之所以引用int,是因为传递给变差函数的值默认升级,尤其是char会自动升级为int。参见C标准§6.5.2.2函数调用¶6:

¶6如果表示被调用函数的表达式的类型不包括原型,则对每个参数执行整数提升,并且将类型为float的参数提升为double。这些被称为默认参数提升。如果参数的数量不等于参数的数量,则行为是未定义的。如果函数是用包含原型的类型定义的,并且原型以省略号(, ...(结束,或者升级后的参数类型与参数类型不兼容,则行为是未定义的。如果函数是用不包括原型的类型定义的,并且升级后参数的类型与升级后参数类型不兼容,则行为是未定义的,以下情况除外:

  • 一个提升的类型是有符号的整数类型,另一个提升类型是相应的无符号整数类型,并且该值在两种类型中都是可表示的
  • 这两种类型都是指向字符类型或CCD_ 14的合格或不合格版本的指针

¶7如果表示被调用函数的表达式具有包含原型的类型,则参数将隐式转换为相应参数的类型,就像通过赋值一样,将每个参数的类型作为其声明类型的非限定版本。函数原型声明符中的省略号表示法会导致参数类型转换在最后一个声明的参数之后停止。默认的参数提升是对尾随参数执行的。

整数提升在§6.3.1.1布尔值、字符和整数¶2:中定义

…如果int可以表示原始类型的所有值(对于比特字段,受宽度限制(,则该值被转换为int;否则将其转换为unsigned int。这些被称为整数促销

58(§3整数提升保留包括符号在内的值。如前所述,"闲置"char是否被视为已签名由实现定义。

58(58(整数提升仅适用于:作为常规算术转换的一部分,适用于某些参数表达式,适用于一元+-~运算符的操作数,以及移位运算符的两个操作数,由其各自的子类指定。


代码中还有其他问题。访问数组超出了界限,数组索引从0开始,而不是从1开始。

car cardetails[5];
…
for (i = 1; i < 6; i++)
{
printf("nCar[%d] ID: ", i); 
scanf("%d", &cardetails[i].ID);
…
}
…
for(i = 1; i < 6; i++){
printf("Car ID: %d", cardetails[i].ID);
printf("Model: %s", cardetails[i].model);
printf("Price: %f", cardetails[i].price);
i = i + 2;
}

最后一个循环打印数组的元素14——由于i++i = i + 2,它们恰好是有效索引。第一个循环远远超出了最后一个有效索引(即cardetails[4](。C中惯用的for循环使用:

for (int i = 0; i < 5; i++)
{
…cardetails[i].whatever…
}

其中5是数组中元素的数量——循环使用索引0。。CCD_ 30。理想情况下,不要重复5;您可以使用枚举或#define来定义数组的大小。

您应该测试对scanf()的每个调用是否成功,如果不成功,则采取适当的操作。您应该限制使用%31s读取的数据量(例如,假设数组大小为32(。

我还没有通过编译器运行过代码,可能还有其他问题需要解决。

相关内容

  • 没有找到相关文章

最新更新