由于printf
函数每次使用时返回一个整数值(屏幕上写入的字符数),因此不应强制将此值存储在每个int
变量中时间printf
被称为?
编辑:
如果函数返回某个值,为什么C不需要在函数调用时存储该值?
答案 0 :(得分:3)
只有在必要时才可以。
如果我们 不关心 ,则不希望使用返回值。存储它是没有用的。
答案 1 :(得分:2)
如果您对如何使用x有所了解,那么您当然可以写
int x = printf( "text" );
否则,函数的返回值将被丢弃,因为它未被使用。
在大多数情况下,程序员找不到printf返回值的有用应用程序。
但有时它可用于打印具有对齐列的表格。
例如
int n = printf( "%s", SomeString );
if ( n < COLUMN_WIDTH ) printf( "%*c", COLUMN_WIDTH - n, ' ' );
考虑这个简单的程序
#include <stdio.h>
int main( void )
{
const int COLUMN_WIDTH = 20;
int n = printf( "%s", "Hello" );
if ( n < COLUMN_WIDTH ) printf( "%*c", COLUMN_WIDTH - n, ' ' );
printf( "%s", "World" );
}
它的输出是
Hello World
这是另一个例子,其中printf的返回值找到了一个有用的应用程序。
我们假设您需要输出一个用逗号分隔的数字序列,例如
1, 2, 3, 4, 5, 6, 7, 8, 9
如何仅使用单个循环输出这样的序列而不在循环外放置print语句?
这是一个程序,它显示了如何使用函数printf的返回值来完成它。 :)试试吧。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main( void )
{
size_t n = 0;
printf( "Enter the number of elements in the array (greater than 0): " );
scanf( "%zu", &n );
if ( n == 0 ) exit( 1 );
int a[n];
srand( ( unsigned int )time( NULL ) );
size_t i;
for ( i = 0; i < n; i++ ) a[ i ] = rand() % n;
i = 0;
do
{
printf( "%d", a[ i ] );
} while ( ++i < n && printf( ", ") > 0 );
return 0;
}
至于你的程序
int foo(int x) {
return x;
}
int main() {
foo(10);
}
然后调用函数foo
没有任何效果。它什么都不做,实际上可以删除。并非所有编译器都会为您的程序发出消息。您正在使用的编译器似乎有一个编译器选项,使编译器更好地考虑错误等警告。所以你的编译器希望你注意函数的调用没有任何影响。你可能犯了一个逻辑错误。
另一方面,调用函数printf具有明显的效果。
答案 2 :(得分:1)
如果需要,您可以存储返回值,例如为了确保输出所需数量的字符(听起来不太可能有人需要,特别是考虑到在生产中你通常有更全面的记录用于处理输出的模块。)
你也可以明确地说你不关心那个带有(void)
的编译器的返回值,如
(void) printf("hello world\n");
请注意,这除了抑制某些工具的警告(例如lint
)
答案 3 :(得分:1)
如果函数返回某个值,为什么C不需要在函数调用时存储该值?
从正常的C编程风格的角度来看,这可能更糟糕:您已经创建了一个带有值的局部变量,但是您没有使用它:
int x;
x = printf(...);
会发出警告,表示您没有使用x进行任何操作。你必须这样做来解决两个开放的目标:
if (printf(...)<EXPECTED_OUTPUT_BYTES) exit(1);
或类似的。幸运的是,退出不会返回任何内容。
答案 4 :(得分:1)
如果您认为您的C程序将被翻译成汇编语言(例如x86程序集),那么读取函数的返回值只需要读取存储在&#39; eax&#中的值。 39;注册你的CPU。
C编程语言在历史上被编写为一种易于在非常有限的(对于今天的标准)PDP-11计算机上进行解析和编译的语言。
早期的C编译器(好吧,其中一些)接受声明的函数没有返回类型而没有返回,如下所示:
myFunc(int *x)
{
*x = *x + *x;
}
这是早期C编译器将其解释为
的函数int myFunc(int *x)
{
*x = *x + *x;
return 0;
}
因此,您的问题的答案可能是因为遗留代码而导致的。
但是有些情况应该或必须检查返回值。
MISRA C指南第16.10条规定: &#34;如果函数返回错误信息,则应测试该错误信息&#34;。
因此,如果您需要确保printf()打印了某些内容,如果您使用返回值作为“错误信息”,则必须遵循MISRA指南,检查该值。
答案 5 :(得分:0)
正如其他人所说,你可以随意忽略任何函数调用的结果。
但是,如果您正在使用gcc,那么您可以添加一个函数属性warn_unused_result
,如果未使用函数的结果,则会导致gcc发出警告。将其与-Werror
结合使用,然后检查结果是否正在使用。
以下是gcc信息页面中的示例:
int fn () __attribute__ ((warn_unused_result));
int foo ()
{
if (fn () < 0) return -1;
fn ();
return 0;
}
这将警告(或-Werror
)关于使用fn ();
的错误。