Argument Processing

D

Dan Pop

In said:
Just a question - were parentheses EVER required on a 'return'
statement in C?

http://www.lysator.liu.se/c/bwk-tutor.html

What if we wanted count to return a value, say the number of
characters read? The return statement allows for this too:

int i, c, nchar;
nchar = 0;
...
while( (c=getchar( )) != '\0' ) {
if( c > size || c < 0 )
c = size;
buf[c]++;
nchar++;
}
return(nchar);

Any expression can appear within the parentheses.

This is a strong implication that, by the time this tutorial was written,
4 years before K&R1, returning a value *required* the parentheses.

Even K&R1 consistently uses them when returning values, although the
syntax specification in Appendix A doesn't require them. It must have
been a very recent change to the language syntax.

Dan
 
J

John Bode

Mike Wahler said:
"Daniel Rudy"
Thanks to everyone who replied. The code now looks like this:

strata:/home/dcrudy/c 1047 $$$ ->cat argtest.c
/*

just echos the command line arguments onto the screen
tests the format of argument processing

*/

#include <stdio.h>
#include <string.h>


int main(int argc, char *argv[])
{
int i; /* generic counter */

if (argc < 3)
{
printf("error: need more arguments.\n");
return(0);
}
printf("argc = %d\n", argc);
for (i = 0; i < argc; i++)
{
printf("argv[%d] = %s\n", i, argv);
}

/* return to operating system */
return(0);
}


So now when I run it, instead of core dumping, I get the following output:

strata:/home/dcrudy/c 1046 $$$ ->./argtest arg1 arg2 arg3
argc = 4
argv[0] = ./argtest
argv[1] = arg1
argv[2] = arg2
argv[3] = arg3

Now there is something about this that I do not understand. What
exactly is the nature of argv? I know it's an array,


Actually, it's not. Arrays cannot be passed to or returned
from functions.
but is it an array
of char?

No. It's a pointer (to an array of pointers (to char)).
This allows for arguments of varying lengths.


Actually, it's just a pointer to pointer to char, not a pointer to an
array of pointers to char (otherwise it would have to be typed char
*(*argv)[SIZE]).

Right. Logically speaking, you're passing an array of strings to
main(). Physically speaking, this translates as a pointer to a
pointer to char:

int main (int argc, char *argv[])

or

int main (int argc, char **argv)

Here's why. Remember that a "string" in C is a 0-terminated array of
char:

char a[6] = "Hello"; /* a == {'H', 'e', 'l', 'l', 'o', 0} */

Therefore, an array of strings would be an array of 0-terminated
arrays of char:

char b[2][6] = {"Hello", "World"};

Now, remember that when you pass an array as an argument to a
function, what actually happens is that you pass a *pointer* to the
first element of the array. In other words:

void foo(char *arr) {...}
....
foo(a); /* a == &a[0] */
foo(b[0]); /* b[0] == &b[0][0] */
foo(b[1]); /* b[1] == &b[1][0] */
....

Even though the actual *types* of a, b[0], and b[1] are "6-element
array of char", when an array identifier appears in any context other
than as an operand to sizeof, it is evaluated as a pointer to the
first element in the array.

Now, since b is itself an array of something, when we pass it to a
function, we are actually passing the pointer to the first element:

void bar(char **arr) {...}
....
bar(b); /* b == &b[0] */
....

In the context of a function prototype, a[] and *a are equivalent;
both indicate that a is a pointer to something. *b[] and **b are also
equivalent. Since this tends to cause no end of confusion, I stick
with the *a, **b syntax exclusively.
 
O

Old Wolf

Mike Wahler said:
Nils O. Selåsdal said:
Daniel said:
What exactly is the nature of argv? I know it's an array,

argv is char *argv[] .A n array, of pointers to char.

No, 'argv' is *not* an array, it's a pointer.
Think of it as an array of pointers to C strings.

No. It's a pointer to such an array.

If we're going to this level of ped^H^H^H detail,
it's actually a pointer to the first item of such an array.
 
T

Tim Rentsch

In said:
Just a question - were parentheses EVER required on a 'return'
statement in C?

http://www.lysator.liu.se/c/bwk-tutor.html

What if we wanted count to return a value, say the number of
characters read? The return statement allows for this too:

int i, c, nchar;
nchar = 0;
...
while( (c=getchar( )) != '\0' ) {
if( c > size || c < 0 )
c = size;
buf[c]++;
nchar++;
}
return(nchar);

Any expression can appear within the parentheses.

This is a strong implication that, by the time this tutorial was written,
4 years before K&R1, returning a value *required* the parentheses.

Even K&R1 consistently uses them when returning values, although the
syntax specification in Appendix A doesn't require them. It must have
been a very recent change to the language syntax.

This combination of observations explains a lot. Thanks Dan.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top