-2

I'm mainly an electronics hardware guy, but I've learned the basics of D from a friend, so I decided I'd pick up a more standard language like C. So, any advice would be great. Basically, I'm using the integer 'phew' as a counter, to reverse all numbers. Super basic, but I'm having trouble finding the way to do this in C. My code:

#include <stdio.h>

int main()
{
     int input;
     int phew;
     printf("Binary Number: ");
     scanf("%d", &input);
     while(phew < sizeof(input))
     {
          if(input[phew] == 0)
               printf("1");
          else
               printf("0");
          phew++;
      }
      return 0;
}

And the compiler error was:

helloworld.c: In function ‘main’:
helloworld.c:11:11: error: subscripted value is neither array nor pointer nor vector
if(input[phew] == 0)
        ^
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • 5
    `[]` is a subscript operator and can only be used with array and pointer datatypes, `input` is neither. – haccks Jan 19 '16 at 13:17
  • 4
    The compiler tells you `input` is not an array, which is how you are trying to use it. You also have *undefined behaviour* by using `phew` before it has been given a value. Local (automatic) variables are not initialised. – Weather Vane Jan 19 '16 at 13:18
  • Also, variable `phew` is uninitialized. Consider doing `int phew = 0`. – V. Kravchenko Jan 19 '16 at 13:19
  • 1
    Even if `input` *was* an array, `while(phew < sizeof(input))` is incorrect, that is not the number of elements. – Weather Vane Jan 19 '16 at 13:20
  • An int isn't an array of bits though you can use bitwise operators to extract the individual bits. Reading a book is a very good idea. With your hardware background you should pick it up fairly easily. – John Coleman Jan 19 '16 at 13:28
  • Try [this question](http://stackoverflow.com/questions/111928/is-there-a-printf-converter-to-print-in-binary-format) about printing in binary. – Weather Vane Jan 19 '16 at 13:30
  • 1
    I'd suggest using more precise language in your question, as "reverse all numbers" doesn't really make sense. Reverse what? The digits? The order? it looks like what you are trying to do is "print the bits of an integer in ascending order of place value", so I've written an answer based on that assumption. – trent Jan 19 '16 at 13:49
  • 1
    I did a rollback since rants about site usage should not go into questions/answers. If you feel that you have a different definition of what this site is about than other users, then raise debate at http://meta.stackoverflow.com/ and not inside your own technical question. – Lundin Jan 19 '16 at 13:55
  • 1
    That being said I would suspect that you might be coming from VHDL, Verilog and similar hardware languages? If so, then that's the source of all the problems. High-level programming languages are very different, since they are sequential rather than parallel. – Lundin Jan 19 '16 at 14:00
  • still, I did not get the logic for printing `1` when the match is `0`. hmmm.. – Sourav Ghosh Jan 19 '16 at 14:14
  • @SouravGhosh Ah, possibly "invert" was intended instead of "reverse". I missed that. – trent Jan 19 '16 at 14:18
  • @trentcl no, you're right. I myself missed that. :) – Sourav Ghosh Jan 19 '16 at 14:21

2 Answers2

3

First of all, in the below statement,

 while(phew < sizeof(input))
  • invokes undefined behavior as phew is an automatic local variable and not initialized. You need to initialize phew like int phew = 0;

  • In this scenario, sizeof(input) is valid, but does not make any sense.

That said, you can only use the [] operator on an array type. In your case, input is an int, so you are not allowed to write input[n].

to elaboate, quoting the C11 standard, chapter §6.5.2.1

Syntax

postfix-expression [ expression ]

and the description

One of the expressions shall have type pointer to complete object type, the other expression shall have integer type, and the result has type type.

So, clearly, in your case input is not a "pointer-to-type", hence the error.

To solve the issues,

  1. You can change the type of input as char input[32] = {0};

  2. change the scan statement as `scanf("%29s", input);

  3. add while(phew < strlen(input))

to make sense. You'll be needing string.h header file for that. Check details about strlen() here.

You have to change it like

while(phew <  strlen(input) )
 {
      if(input[phew] == '0')  //ASCII 48, decimal
           printf("1");
      else
           printf("0");
      phew++;
  }
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
0

You cannot use [] to get bits of an integer in C; that operator only works on pointer values and an int is not a pointer. You may be familiar with Verilog, where bit vectors and integers are the same thing; but C doesn't have a syntax for accessing bits of an object and [] is only for accessing members of an array.

One correct way to do this is using a bit mask. For example:

for (size_t i = 0; i < (sizeof input)*CHAR_BIT; i++) {
    unsigned mask = 1 << i;
    if (input & mask) {
        putchar('1');
    } else {
        putchar('0');
    }
}
putchar('\n');

What this code does on each iteration of the loop is create an unsigned integer mask by shifting the number 1 into the ith place of the integer. Then mask is bitwise-ANDed with input to give a value that is 0 if that bit is 0 in input (and otherwise some nonzero value equivalent to the place value of the bit). Don't forget to print out a newline at the end or the output may not be visible.

I'm using unsigned arithmetic here because << can have implementation-defined or undefined behavior on signed numbers in C. input can be a regular (signed) int because it will be promoted to unsigned by the & operator.

Also notice that I had to multiply sizeof input by CHAR_BIT (which is defined in <limits.h>) to get the number of bits; sizeof always measures sizes in bytes.

Also see this C FAQ (20.7) about bit manipulations.

trent
  • 25,033
  • 7
  • 51
  • 90