1

I have searched for any reference to this for quite a bit now but I haven't had any success, so I thought I would ask here. Basically, I am trying to understand a C written program for creating a shell in linux and I am having problems with this piece of code

...
else if (args[0][0]-'!'==0){
      int x = args[0][1]-'0';
      int z = args[0][2]-'0';
...
}

The args is storing the command's entered by the user. For instance, later the address space of the child (parent process reads the commands, child executes them) is replaced using a call to execvp(args[0], args). The definition of args is as follows: char *args[MAX_LINE/2 +1];

What I have been having trouble understanding is the ways in which the array is accessed; specifically what is meant by these expressions in this context: args[0][0]-'!'==0 args[0][1]-'0'; args[0][2]-'0';

Elemental
  • 7,365
  • 2
  • 28
  • 33
Bendemann
  • 735
  • 11
  • 31
  • It is an array of arrays, so one index tells you which array to grab, and the other index tells you which element of that array you are grabbing. – Christian Gibbons Mar 29 '18 at 17:37
  • First of all, remember that `char` is just a small `int`. And character constants like `'!'` actually are `int` values. And when a `char` is used in an arithmetic operation it is promoted to an `int`. Now considering all of that, when the first character of the first string in `args` is equal to `'!'`, what do you think will happen when you subtract `'!'`? What will the result be? – Some programmer dude Mar 29 '18 at 17:38
  • Or shorter, it's just an obfuscated way of saying `if (args[0][0] == '!')` – Some programmer dude Mar 29 '18 at 17:38
  • The code is examining the first three characters of the first (supposed) string. But `if (args[0][0]-'!'==0)` is a strange way to write `if (args[0][0] == '!')` – Weather Vane Mar 29 '18 at 17:39
  • As for the initializations of `x` and `z`, my first comment should have helped you with that. Looking at an [ASCII table](http://en.cppreference.com/w/c/language/ascii) might also be useful. This is less obfuscated and quite common way to get the integer value of a character digit. – Some programmer dude Mar 29 '18 at 17:40
  • Lastly, if you want to know what's so special about an initial `'!'` in a command, then you should read more about shells. – Some programmer dude Mar 29 '18 at 17:43
  • @Someprogrammerdude Thank you very much, that was exactly what I needed. – Bendemann Mar 29 '18 at 17:48

2 Answers2

4

Judging by the name of the variable, args stands for a list/array of arguments.

arg[0] is the first element of that array.
args[0][0] is the first character of the first element of that array.

The expression args[0][0]-'!'==0 checks whether that character is equal to '!'. That could have been written better as args[0][0] == '!'. It's as if instead of using if ( i == 10 ), you decide to use if (i-10 == 0).

The next two lines

  int x = args[0][1]-'0';
  int z = args[0][2]-'0';

expect that the second and third characters of the first argument are digits and extract the decimal values they correspond to. If the first argument is "!26", then x will have the value 2 and z will have the value 6.

That logic depends on the guarantee that the encoding used for the characters '0' - '9' are required to be contiguous.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • To clarify, section 5.2.1 of the C standard guarantees that the characters for `'0'` to `'9`' are contiguous. It's not dependent on the particular encoding. – dbush Mar 29 '18 at 17:50
  • @Bendemann, you are welcome. Glad I was able to help. – R Sahu Mar 29 '18 at 18:59
1

Probably args is a reference to

int main(int argc, char **argv);

Then args[0] is the name of the program and in the following args you would find the Arguments of the Programm, see e.g. Arguments to main in C

Thus args[0[0] is the first character of the name of the program.

milbrandt
  • 1,438
  • 2
  • 15
  • 20