我正在用K&R学习C语言,下面是一个练习:
练习3-5:编写函数itob(n,s,b),将整数n转换为字符串s中的基b字符表示,特别是itob(n,s,16)将n格式为十六进制整数。
所以我写了这样的程序:
#include <stdio.h>
#include <string.h>
#define MAXLINE 1000
void reverse(char );
void itob(int , char , int );
main()
{
char line[MAXLINE];
int n, i;
printf("integer: ");
scanf_s("%d",&n);
printf("base: ");
scanf_s("%d",&i);
itob(n, line, i);
printf("%s", line);
}
void itob(int n, char s[], int b)
{
int i, sign;
if ((sign = n) < 0)
n = -n;
i = 0;
do
{
n % b < 10 ? (s[i++] = n % b + '0') : (s[i++] = n % b + '7');
}
while ((n /= b) > 0);
if (sign < 0)
s[i++] = '-';
s[i] = '\0';
reverse(s);
}
void reverse(char s[])
{
int c, i, j;
for (i = 0, j = strlen(s)-1; i < j; i++, j--)
{
c = s[i];
s[i] = s[j];
s[j] = c;
}
}我以为一切都好。但是,当我运行程序时,在输入整数和基值后会出现错误,如下所示:
未处理的异常0x10022050 (msvcr110d.dll)在练习3-5.exe: 0xC0000005:访问冲突读取位置0x000000EC。
所以这个程序在函数itob调用上有问题。
然后经过大约两个小时的调试,我发现原因是反向需要包含如下参数名的函数原型:
void reverse(char s[]);
void itob(int , char , int );我所做的唯一改变就是在反向功能原型中添加了s[],然后程序正常工作。
我很困惑,因为我学到的只是函数原型的参数名称是可选的。为什么参数名必须包含在反向功能原型中?为什么itob的函数原型不需要参数名,并且没有弹出错误?我的IDE是2012。
谢谢大家的时间和帮助。
发布于 2015-05-31 00:06:54
您的问题中的代码有许多错误,其中许多您的编译器至少应该警告您。
当我复制代码并使用gcc编译它时,即使没有任何额外的参数,第一个错误消息是:
c.c: In function ‘main’:
c.c:16:5: warning: passing argument 2 of ‘itob’ makes integer from pointer without a cast [enabled by default]
itob(n, line, i);
^
c.c:6:6: note: expected ‘char’ but argument is of type ‘char *’
void itob(int , char , int );
^错误信息是正确的。您用第二个char类型的参数声明了char,然后用第二个char*类型的参数调用它(这是数组line的隐式转换的结果)。
稍后,使用itob类型的第二个参数(因为它是一个参数,实际上是char*类型)定义了char*。这与之前的声明不兼容,编译器也应该对其进行标记。
要回答标题中的问题,在独立的原型(不是函数定义的一部分)中,参数名是可选的。这两种原型是等价和有效的:
void itob(int, char, int);和
void itob(int x, char y, int z);就我个人而言,我喜欢指定参数名,因为它使代码更清晰。
对于作为函数定义一部分的原型,需要使用名称,因为参数对象就是这样定义的。
但是,首先,修复代码中的错误。
https://stackoverflow.com/questions/30552300
复制相似问题