0

Code:

#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;
}

Output:

11
1
4210693

My Question: b is a static variable, so how come its value changed in the second printf() function used? The third printf() function makes sense because it has given an error.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
user134613
  • 109
  • 4
  • 3
    It changes value because you explicitly did so in the line `b = b-1;` - `static` does not mean immutable – UnholySheep Feb 05 '21 at 18:59
  • 1
    The value may be changed due to *undefined behavior*, which allows anything to happen. – MikeCAT Feb 05 '21 at 18:59
  • 1
    As @UnholySheep suggested, I think you're confusing `static int b=2;` with `const int b=2;` – Super Symmetry Feb 05 '21 at 19:20
  • 2
    You have a `printf` call where you provide 3 parameters for a format string that only contains 1 format specifier. If your compiler did not tell you about that mismatch, you need to increase warning level. For GCC you can do this with `-Wall -Wextra`. If your compiler did tell you about that, listen to your compiler! – Gerhardh Feb 05 '21 at 19:26
  • Thank you for your comments. @Gerhardh I'm using Codeblocks and I will look for a way to increase its warning level because it hasn't warned me. – user134613 Feb 05 '21 at 21:26

2 Answers2

3

For starters in the beginning of the program you changed the static variable b

b = b-1;

the keyword static does not have the meaning as the keyword const.

On the other hand, in this call of printf there is evidently a typo

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

In fact you are trying to output a pointer to the string literal "%d" as an integer.

That is the function has four arguments and only one conversion specifier in the first argument.

The compiler could issue a warning that there are redundant arguments in the call of printf.

You could write for example like :)

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

In this case the output would be

11
1

Because the above call is equivalent to

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

But it seems you mean

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

So neither static variable is changed spontanno.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Thank you. So, if I removed "static" and kept the declaration as int b, then it would be the same as static int b. so what is the use of static variable if it's going to change the value anyway? – user134613 Feb 05 '21 at 20:38
  • 1
    @user134613 A static variable declared in a function keeps its value between function calls. It has static storage duration opposite to other variables declared within the function that have automatic storage duration. – Vlad from Moscow Feb 05 '21 at 20:40
  • so if the static variable was declared inside a function then we can't change its value inside the function but we can do so outside the function? – user134613 Feb 05 '21 at 20:56
  • 1
    @user134613 No you are wrong. A variable declared in a function is its local variable that is not visible outside the function where it is declared. But it keeps its value between calls of the function. – Vlad from Moscow Feb 05 '21 at 20:58
  • What do you exactly mean "between calls of the function" ? – user134613 Feb 05 '21 at 20:59
  • 1
    @user134613 If you will run this program #include void f( void ) { static int x = 0; printf( "x = %d\n", x ); ++x; } int main(void) { f(); f(); f(); return 0; } then the program output will be x = 0 x = 1 x = 2 – Vlad from Moscow Feb 05 '21 at 21:00
2

printf signature is

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

The first parameter is the format string and all the following parameters are the format specifiers (subsequences beginning with %).

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

The code above invokes undefined behaviour because the first format specifier %d is used to present decimal integer value while the parameter matching this specifier is "%d" which has type const char *.

You should change it to:

printf("%d %d\n",a,b);
Alex Lop.
  • 6,810
  • 1
  • 26
  • 45