1

I am trying to compile and run a simple C program from my Terminal. This is my code:

#include <stdio.h>
//integers that are 3n, 3n + 1, and 3n + 2

int main(){
  int n,i,a,b,c;
  scanf("%d", &n);
  for (;n>0;n--) {
    scanf("%d", &i);
    if(n%3==0){a+=1;}
    if(n%3==1){b+=1;}
    if(n%3==2){c+=1;}
  }
  printf("%d %d %d", &a,&b,&c);
  return 0;
}

After compiling it one time it generates this warning:

warning: format specifies type 'int' but the argument has type 'int *' [-Wformat]

I don't understand why it is generating that warning because I am not assigning any pointer variables. Why is it generating it?

Also, after compiling it a couple of times more my c file is turning into symbols. I don't understand why this is happening. The name of my file is 73.c and this is how I'm compiling it on Terminal:

gcc 73.c -o 73.c

After that my file in converted to something like this (lines and lines of this):

œ˙Ì˛����Ä��������Ö� ��������H���__PAGEZERO��������������������������������������������������������(��__TEXT����������������������������������������������������__text����������__TEXT����������0�����˝�������0���������������Ä������������__stubs���������__TEXT����������.������������.��������������Ä�����������__stub_helper���__TEXT����������<�����$�������<���������������Ä������������__cstring�������__TEXT����������`������������`�����������������������������__unwind_info���__TEXT����������l�����H�������l������������������������������__eh_frame������__TEXT����������∏�����@�������∏��������������������������������Ë���__DATA��������������������������������������������������__nl_symbol_ptr�__DATA���������������������������������������������������__la_symbol_ptr�__DATA����������������������������������������������������H���__LINKEDIT������� ������������� ������`��������������������"��Ä0���� ����� �������������  �� ���@ ��0���������∏ ����� !��@���

I really don't have any idea of what's going on. I've been at it for a long time now, I know it shouldn't be that hard but I really don't know what's wrong. Somebody have any idea of what might be happening?

gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • 1
    `&a` - what do you believe this is, if not a pointer? – Oliver Charlesworth Aug 10 '16 at 19:06
  • 1
    `gcc 73.c -o 73.c` tells the compiler to output the executable with the same name as your source file. You should use a different name for the executable, e.g. `gcc 73.c -o 73; ./73` – aschepler Aug 10 '16 at 19:09
  • @aschepler good catch, I updated my answer with that info, if you don't mind. – gsamaras Aug 10 '16 at 19:13
  • Spaces exist for a reason. Use them! Format this mess properly - and consistently. You might notice you understand your code much better and can see errors easier yourself. – too honest for this site Aug 10 '16 at 19:17
  • You would also be getting some warnings that a,b, and c are uninitialized. You should explicitly set them to zero at the start of the program. – hugomg Aug 10 '16 at 19:24
  • 1
    @hugomg well, treat warnings as errors comes in handy here, the fact about the uninitialized variables, will invoke **Undefined Behavior** in this code, I updated my answer! – gsamaras Aug 10 '16 at 19:26
  • It doesn't even compile on a Mac, are you sure this code is fine? – FlerrElectronics Aug 10 '16 at 19:30
  • @FlerrElectronics that doesn't make sense. The code should compile and generate warnings. Except if you have enabled treating warnings as errors. In fact, my answer uses a Mac. :P – gsamaras Aug 10 '16 at 19:32
  • I used the same command as you did. – FlerrElectronics Aug 10 '16 at 19:32
  • Hey @FlerrElectronics, you didn't tag me, so I didn't see your comment. If you want, you can tell me what errors you get. :) BTW, Natalia Beneitez, I have answered your question, if you haven't see.. :) – gsamaras Aug 10 '16 at 19:52

2 Answers2

4

There are two major things that are wrong here:

  1. You try to print the address of variables a, b and c.
  2. You invoke Undefined Behavior, but not initializing your counters to 0.

You want to print the integers, so change this:

printf("%d %d %d", &a,&b,&c);

to this:

printf("%d %d %d", a, b, c);

I also added some spaces, but that's just to beautify the code, to make it more readable, it won't affect the execution.

You don't want to print the addresses! That's why you get the warning. Read more here: What is the difference between the * and the & operators in c programming?


As achelper, mentioned, you don't compile your program as you should (but that's not the problem of the code), but it's something you should get used to. I will demonstrate what I did to compile me program (I also like to use -Wall flag, which enables all warnings):

C02QT2UBFVH6-lm:~ gsamaras$ nano main.c
C02QT2UBFVH6-lm:~ gsamaras$ gcc main.c -Wall -o main
main.c:13:22: warning: format specifies type 'int' but the argument has type
      'int *' [-Wformat]
  printf("%d %d %d", &a,&b,&c);
          ~~         ^~
main.c:13:25: warning: format specifies type 'int' but the argument has type
      'int *' [-Wformat]
  printf("%d %d %d", &a,&b,&c);
             ~~         ^~
main.c:13:28: warning: format specifies type 'int' but the argument has type
      'int *' [-Wformat]
  printf("%d %d %d", &a,&b,&c);
                ~~         ^~
main.c:11:16: warning: variable 'c' is uninitialized when used here
      [-Wuninitialized]
    if(n%3==2){c+=1;}
               ^
main.c:5:16: note: initialize the variable 'c' to silence this warning
  int n,i,a,b,c;
               ^
                = 0
main.c:10:16: warning: variable 'b' is uninitialized when used here
      [-Wuninitialized]
    if(n%3==1){b+=1;}
               ^
main.c:5:14: note: initialize the variable 'b' to silence this warning
  int n,i,a,b,c;
             ^
              = 0
main.c:9:16: warning: variable 'a' is uninitialized when used here
      [-Wuninitialized]
    if(n%3==0){a+=1;}
               ^
main.c:5:12: note: initialize the variable 'a' to silence this warning
  int n,i,a,b,c;
           ^
            = 0
6 warnings generated.
C02QT2UBFVH6-lm:~ gsamaras$ ./main
2
1
2
1461300256 1461300252 1461300248C02QT2UBFVH6-lm:~ gsamaras$ 

In general, when in doubt, treat warnings as errors, so let's debug that code together, it will be fun. Pro-tip: Start from the first warning and resolve it. After that, the next warnings may be related, thus gone without having you really reading them!

After applying my suggestion, all the warnings related with what you described in your question are gone. Only the uninitialized variable ones are left.

That's easy, just initialize your variables to some initial value, like -1, if that makes sense of course.

In your case though, you use a, b and c as counters! So you must initialize them to 0, otherwise you are starting adding your values to garbage values, and that invokes Undefined Behavior!

So do change this:

int n,i,a,b,c;

to this:

int n, i, a = 0, b = 0, c = 0;

Without the initialization of the counters, I am getting, on my machine, now

C02QT2UBFVH6-lm:~ gsamaras$ ./main
2
1
2
1505029184 1 1C02QT2UBFVH6-lm:~ gsamaras$

You see that printf() gives me some garbage, while after initializing my counters to 0, I got:

C02QT2UBFVH6-lm:~ gsamaras$ ./main
2
1
2
0 1 1C02QT2UBFVH6-lm:~ gsamaras$ 
Community
  • 1
  • 1
gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • 1
    I understand now, thank you! I thought the & operator acted just like a reference for the variable or something like that. Went back and did what you told me and now it runs perfectly :) Also thanks for the -Wall flag tip, it was very useful – Natalia Beneitez Aug 11 '16 at 05:11
  • @NataliaBeneitez you are welcome, glad it helped! You posted a nice first question, that's why I upvoted you (the score of your question is +1). Note that in StackOverflow, we *accept* the answer we found more useful. You received two answers, choose one and accept it, please. :) – gsamaras Aug 11 '16 at 16:03
2

The points mentioned by gsamaras are correct, you should use :

 printf("%d %d %d", a, b, c);

The syntax you were using is used in

  • scanf (pass address of the variable where the data is need to be filled.)

  • Also initialize variables while defining.

Regarding compilation: The name -o specifies the output file generated after compilation thus it is overwriting your source code (i.e., 73.c). If you omit -o, the default output file is generated as a.out. So for compiling you can use following and run the program as ./a.out:

gcc 73.c

man gcc quotes:

-o file Place output in file file. This applies to whatever sort of output is being produced, whether it be an executable file, an object file, an assembler file or preprocessed C code.

If -o is not specified, the default is to put an executable file in a.out, the object file for source.suffix in source.o, its assembler file in source.s, a precompiled header file in source.suffix.gch, and all preprocessed C source on standard output.

  • Thank you for reading my answer and providing more information! ;) +1, since you are a new user too! – gsamaras Aug 11 '16 at 00:13