【问题标题】:static variable changing value with no error displayed? [closed]静态变量更改值而不显示错误? [关闭]
【发布时间】:2024-01-16 19:59:01
【问题描述】:

代码:

#include <stdio.h>

int main()
{
    int a=10;
    static int b=2;
    a = a+1;
    b = b-1;
    printf("%d \n",a);
    printf("%d \n",b);
    printf("%d \n","%d",a,b);
    return 0;
}

输出:

11
1
4210693

我的问题: b 是一个静态变量,那么它的值在第二个使用的 printf() 函数中是如何变化的呢?第三个 printf() 函数是有意义的,因为它给出了一个错误。

【问题讨论】:

  • 它会改变值,因为你在b = b-1; - static 行中明确这样做并不意味着不可变
  • 值可能会因未定义的行为而改变,这允许任何事情发生。
  • 正如@UnholySheep 所建议的,我认为您将static int b=2;const int b=2; 混淆了
  • 您有一个printf 调用,您可以在其中为仅包含 1 个格式说明符的格式字符串提供 3 个参数。如果您的编译器没有告诉您该不匹配,您需要提高警告级别。对于 GCC,您可以使用 -Wall -Wextra 执行此操作。如果您的编译器确实告诉了您,请听听您的编译器!
  • 感谢您的 cmets。 @Gerhardh 我正在使用 Codeblocks,我会寻找一种方法来提高其警告级别,因为它没有警告我。

标签: c printf string-literals conversion-specifier


【解决方案1】:

对于程序开头的初学者,您更改​​了静态变量b

b = b-1;

关键字static没有关键字const的含义。

另一方面,在printf 的调用中,显然有一个错字

printf("%d \n","%d",a,b);
               ^^^^

实际上,您正在尝试将指向字符串文字 "%d" 的指针作为整数输出。

即函数有四个参数,第一个参数中只有一个转换说明符。

编译器可能会发出警告,指出在 printf 的调用中存在冗余参数。

你可以这样写:)

printf("%d \n" "%d",a,b);

在这种情况下,输出将是

11
1

因为上面的调用等价于

printf("%d \n%d",a,b);

但你的意思似乎是

printf("%d %d\n", a, b);

所以两个静态变量都不会自发改变。

【讨论】:

  • 谢谢。因此,如果我删除“static”并将声明保留为 int b,那么它将与 static int b 相同。那么静态变量如果要改变值有什么用呢?
  • @user134613 在函数中声明的静态变量在函数调用之间保持其值。它的静态存储持续时间与函数内声明的其他具有自动存储持续时间的变量相反。
  • 所以如果静态变量是在函数内部声明的,那么我们不能在函数内部改变它的值,但是我们可以在函数外部这样做?
  • @user134613 不,你错了。在函数中声明的变量是其局部变量,在声明它的函数之外不可见。但它在函数调用之间保持其值。
  • @user134613 如果你将运行这个程序 #include void f( void ) { static int x = 0; printf("x = %d\n", x); ++x; } int main(void) { f(); F(); F();返回0; } 那么程序输出将是 x = 0 x = 1 x = 2
【解决方案2】:

printf签名是

int printf ( const char * format, ... );

第一个参数是格式字符串,后面的所有参数都是格式说明符(以%开头的子序列)。

printf("%d \n","%d",a,b);

上面的代码调用未定义的行为,因为第一个格式说明符%d 用于表示十进制整数值,而与此说明符匹配的参数是"%d",其类型为const char *

你应该把它改成:

printf("%d %d\n",a,b);

【讨论】: