为什么我们不写int x = printf(“text”);因为printf()语句每次都返回一个整数值?

时间:2015-07-24 07:55:00

标签: c printf

由于printf函数每次使用时返回一个整数值(屏幕上写入的字符数),因此不应强制将此值存储在每个int变量中时间printf被称为?

编辑:

如果函数返回某个值,为什么C不需要在函数调用时存储该值?

6 个答案:

答案 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 ();的错误。