fgetc

P

pete

pete said:
lovecreatesbeauty wrote:

01 wrote:
int main ( int argc, char *argv[] )
<snip>
printf( "usage: %s filename", argv[0] ); argv[] is a char
array,
it is a wrong expression.
There's nothing wrong with it.

Is an identifier plus a pair
of square brackets of subscript operator
lacking of subscription valid? If it is correct, what does "argv[]"
mean? Is it the same as "argv"?

Your terminology needs work.

The only two "expressions" in the shown code are:
"usage: %s filename"
and
argv[0]

.... and there's also another expression
in the expression statement.
char *argv[]
is a parameter declaration, not an expression,
and in a parameter declaration context
char *argv[]
means the exact same thing as
char **argv
 
P

pete

01 said:
Richard said:
so printf("%s", argv[0])
would print the contents of argv[0] which is
a pointer.

No, if argc is > 0 the call will
print a sequence of characters starting at
the address stored in argv[0] and ending at the first null character
encountered. If argc is 0, the behaviour is undefined.

so what i am wondering is: why not to print a sequence of characters
starting at
argv[0] itself and ending at the first null character encountered?

Because argv[0] itself,
is a pointer and may or may not contain null characters,
and it certainly isn't supposed to be considered as a string.
 
H

Herbert Rosenau

pete said:
lovecreatesbeauty said:
01 wrote:
int main ( int argc, char *argv[] )
<snip>
printf( "usage: %s filename", argv[0] ); argv[] is a char
array,
it is a wrong expression.
There's nothing wrong with it.

Is an identifier plus a pair of square brackets of subscript operator
lacking of subscription valid? If it is correct, what does "argv[]"
mean? Is it the same as "argv"?

Learn to read a declaration like a C compiler does:

*argv[]

argv a variable
*argv a pointer to a variable
*argv[] an array of pointers to variables
* has higher presendce than [], so its an array of pointers
*(argv[]) a pointer to an array
() has higher presedence than *, so it is pointer to an
array.

**argv a pointer to a pointer to a variable
syntactical the same as *argv[]

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2 Deutsch ist da!
 
P

pete

Herbert said:
pete said:
lovecreatesbeauty wrote:
01 wrote:
int main ( int argc, char *argv[] )
it is a wrong expression.
There's nothing wrong with it.

Is an identifier plus a pair of square brackets
of subscript operator lacking of subscription valid?
If it is correct, what does "argv[]" mean?
Is it the same as "argv"?
*argv[] an array of pointers to variables

Not in a parameter declaration, it isn't,
which happens to be the case in point,
and the source of confusion
for both lovecreatesbeauty and 01.

The type of the argv parameter in main, is (char **).

Between Richard Heathfield and myself,
this is the eigth time
trying to get this point across
in this thread.
 
K

Keith Thompson

01 said:
argv[] is an array that contains many pointers.argv[0] is a pointer to
another char array. that char arry contains the name of this program(
if not null) . is it true?

I think this may be where you go wrong.

What do you mean when you write "argv[]"? What are the empty square
brackets supposed to mean? argv[], with the empty square brackets, is
not a legal expression (it may appear in some declarations, but we'll
leave that aside).

(We sometimes informally refer to a function named "func" as "func()"
to emphasize the fact that it's a function. We don't usually do this
for arrays.)

Given:

int main(int argc, char *argv[]) { /* ... */ }

there is an object (specifically a parameter) whose name is argv. It
is of type pointer-to-pointer-to-char. In spite of the [] syntax, no
array is declared here; in this context, "char *argv[]" means exactly
the same thing as "char **argv".

So argv is a pointer-to-pointer-to-char; it points to a
pointer-to-char. That pointer-to-char is (probably) the first element
of an array of several pointers-to-char; that array will have been
created at execution time by the environment before it invokes the
main program.

So argv is an expression, the name of an object, and its type is
pointer-to-pointer-to-char.

That means that *argv, or equivalently argv[0], is an expression of
type pointer-to-char; if argv is non-null, then *argv is a pointer to
the first character of a string containing some representation of the
program name.
so printf("%s", argv[0]) would print the contents of argv[0] which is
a pointer.

No. argv[0] is a pointer to char; it happens to point (probably) to
the first character of a string. printf() with "%s" doesn't print the
contents of the pointer; it prints the string that the pointer points
to. (More precisely, the pointer points to the first character of the
string, but the standard defines "pointing to a string" to mean
"pointing to the first character of a string".)
why not use printf("%s", *argv[0]) to print the real stuff?

Because it's illegal (actually it invokes undefined behavior).
argv[0] is a pointer-to-char, so *argv[0] (it groups as *(argv[0])) is
an expression of type char. It's probably the first character of the
program name. So this attempts to print just the first character of
the program name, but since it uses the wrong format, it won't work.

This:
printf("%c", *argv[0]);
or, equivalently:
printf("%c", **argv);
or, equivalently:
printf("%c", argv[0][0]);
or, equivalently:
putchar(**argv);
prints the first character of the program name.

I suggest reading section 6 of the comp.lang.c FAQ, at
<http://www.c-faq.com/>.
 
L

lovecreatesbeauty

pete said:
pete said:
lovecreatesbeauty said:
pete wrote:
lovecreatesbeauty wrote:
01 wrote:
int main ( int argc, char *argv[] )
printf( "usage: %s filename", argv[0] ); argv[] is a char
array,
it is a wrong expression.
There's nothing wrong with it.
Is an identifier plus a pair
of square brackets of subscript operator
lacking of subscription valid? If it is correct, what does "argv[]"
mean? Is it the same as "argv"?
Your terminology needs work.
The only two "expressions" in the shown code are:
"usage: %s filename"
and
argv[0]
... and there's also another expression
in the expression statement.

And one more you missed, as Keith Thompson pointed out later that an
illegal expression is not a legal expression.

lovecreatesbeauty
 
A

Andrew Poelstra

01 said:
Richard Heathfield wrote:
so printf("%s", argv[0]) would print the contents of argv[0] which is
a pointer.

No, if argc is > 0 the call will print a sequence of characters starting at
the address stored in argv[0] and ending at the first null character
encountered. If argc is 0, the behaviour is undefined.

so what i am wondering is: why not to print a sequence of characters
starting at
argv[0] itself and ending at the first null character encountered?

so do you mean why not something like this:-

char *cp = argv[0];
while (cp != '\0')
{
printf ("%c", *cp);
cp++;
}

because it's more code?

Yes, it's more code. And it's confusing and useless.

if (argv[0])
puts (argv[0]);

is much cleaner and is likely a lot more efficient.

Also, your while loop should be (*cp != '\0'), with the star. If that wasn't
a typo, you should think about why it should be what it should be.
 
P

pete

lovecreatesbeauty said:
pete said:
lovecreatesbeauty wrote:
pete wrote:
lovecreatesbeauty wrote:
01 wrote:
int main ( int argc, char *argv[] )
printf( "usage: %s filename", argv[0] );
argv[] is a char array,
it is a wrong expression.
Your terminology needs work.
The only two "expressions" in the shown code are:
"usage: %s filename"
and
argv[0]
... and there's also another expression
in the expression statement.

And one more you missed, as Keith Thompson pointed out later that an
illegal expression is not a legal expression.

Are you talking about the code, or his comment,
"argv[] is a char array"?
There's no illegal expression in the shown code.

N869
5.1.2.2.1 Program startup
[#1] The function called at program startup is named main.
The implementation declares no prototype for this function.
It shall be defined with a return type of int and with no
parameters:
int main(void) { /* ... */ }
or with two parameters (referred to here as argc and argv,
though any names may be used, as they are local to the
function in which they are declared):
int main(int argc, char *argv[]) { /* ... */ }
or equivalent;8) or in some other implementation-defined
manner.

8) Thus, int can be replaced by a typedef name defined as
int, or the type of argv can be written as char ** argv,
and so on.
 
H

Herbert Rosenau

Herbert said:
pete wrote:
lovecreatesbeauty wrote:
01 wrote:
int main ( int argc, char *argv[] )
it is a wrong expression.
There's nothing wrong with it.

Is an identifier plus a pair of square brackets
of subscript operator lacking of subscription valid?
If it is correct, what does "argv[]" mean?
Is it the same as "argv"?
*argv[] an array of pointers to variables

Not in a parameter declaration, it isn't,
which happens to be the case in point,
and the source of confusion
for both lovecreatesbeauty and 01.

The type of the argv parameter in main, is (char **).

What is exactly the same as *argv[].

In a definition you can't left [] empty - in a declaration you can and
you would.

By that I've written, tested and delivered more programs written the
argument *argv[] than ever **argv. Whereas I ever use main(void) when
the program has not to handle arguments in main.
Between Richard Heathfield and myself,
this is the eigth time
trying to get this point across
in this thread.

Come on, tell us why in an parameter declaration *argv[] should be
wrong.

You have to learn how a standard conforming compier reads *a[].

a a variable
*a a pointer to a variable
*a[] a pointer to an array of pointers
*(a[]) a pointer to an array
**a a pointer to a pointer

That is inependant of the number of elements in an array. When the
number is empty it is only a declaration - if not it can be a
definition.

That has absolutely nothjing to do if it is a parameter, an argument
or a declaration ([])/definition [<numer>]. It is primitive sytax.

long *a[] a declaration of an pointer to an array of pointers
as an argument, a formal parameter, on file scope or
static.

int **a a pointer to a pointer independant of it is an argument,
a formal parameter, on file scope or static.

Learn the presedence of operators and you can interpret it right.

Don't reference to Richard for that. You knows what he tells you.

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2 Deutsch ist da!
 
P

pete

Herbert said:
Herbert said:
lovecreatesbeauty wrote:
01 wrote:
int main ( int argc, char *argv[] )
it is a wrong expression.
There's nothing wrong with it.

Is an identifier plus a pair of square brackets
of subscript operator lacking of subscription valid?
If it is correct, what does "argv[]" mean?
Is it the same as "argv"?
*argv[] an array of pointers to variables

Not in a parameter declaration, it isn't,
which happens to be the case in point,
and the source of confusion
for both lovecreatesbeauty and 01.

The type of the argv parameter in main, is (char **).

What is exactly the same as *argv[].

In a definition you can't left [] empty

char string[] = "You can leave [] empty in a defintion."
- in a declaration you can and you would.

By that I've written, tested and delivered more programs written the
argument *argv[] than ever **argv. Whereas I ever use main(void) when
the program has not to handle arguments in main.
Between Richard Heathfield and myself,
this is the eigth time
trying to get this point across
in this thread.

Come on, tell us why in an parameter declaration *argv[] should be
wrong.

You have me quoted above, as taking the opposite point.
You have to learn how a standard conforming compier reads *a[].

You have to learn how to be coherent.
 
R

Richard Heathfield

Herbert Rosenau said:
The type of the argv parameter in main, is (char **).

What is exactly the same as *argv[].

Right. And pete knows that.
In a definition you can't left [] empty - in a declaration you can and
you would.

Pete knows that too.

Between Richard Heathfield and myself,
this is the eigth time
trying to get this point across
in this thread.

Come on, tell us why in an parameter declaration *argv[] should be
wrong.

He isn't saying it's wrong. He's saying it is not declaring an array of
pointers.
You have to learn how a standard conforming compier reads *a[].

*a[] a pointer to an array of pointers

Not true in the parameter context that we are discussing. T *arg[] in a
parameter context means that arg has type T **.

<snip>
 
R

Richard Heathfield

pete said:
Richard said:
Herbert Rosenau said:
In a definition you can't left [] empty
- in a declaration you can and you would.

Pete knows that too.

char string[] = "I know about some of that";

Fair cop, guv. Herbert was, of course, thinking about definition without
initialisation, and I was sucked into that same thought line. Must...
Stop... Trusting... People!
 
K

Keith Thompson

Herbert Rosenau said:
The type of the argv parameter in main, is (char **).

What is exactly the same as *argv[].

Yes, in that particular context.
In a definition you can't left [] empty - in a declaration you can and
you would.

pete already showed a counterexample.
By that I've written, tested and delivered more programs written the
argument *argv[] than ever **argv. Whereas I ever use main(void) when
the program has not to handle arguments in main.

Both
int main(int argc, char *argv[])
and
int main(int argc, char **argv)
are perfectly correct, and they're precisely equivalent. I don't
think anyone here has stated otherwise. Personally, I prefer the
latter form because it's more explicit; the former depends on a
special-case rule that, though it's enshrined in the language
definition, I don't particularly like because of the potential
confusion. (There's no real confusion if you actually understand it,
of course.)
Between Richard Heathfield and myself,
this is the eigth time
trying to get this point across
in this thread.

Come on, tell us why in an parameter declaration *argv[] should be
wrong.

It isn't.
You have to learn how a standard conforming compier reads *a[].

a a variable
*a a pointer to a variable
*a[] a pointer to an array of pointers
*(a[]) a pointer to an array
**a a pointer to a pointern

That is inependant of the number of elements in an array. When the
number is empty it is only a declaration - if not it can be a
definition.

That has absolutely nothjing to do if it is a parameter, an argument
or a declaration ([])/definition [<numer>]. It is primitive sytax.

No, it has *everything* to do with whether it's a parameter.

There is a special rule that applies only to parameter declarations.
It says that, in a parameter declaration, and only in a parameter
declaration, this:
int foo[]
really means this:
int *foo

The rule is C99 6.7.5.3p7:

A declaration of a parameter as "array of type" shall be adjusted
to "qualified pointer to type", where the type qualifiers (if any)
are those specified within the [ and ] of the array type
derivation.

The intent of
int foo[]
is that foo *should* be a pointer to the first element of an array,
but it's up to the caller to create that array and arrange for foo to
point to its first element. The caller isn't even required to do so.

Consider this program:

#include <stdio.h>

static void func(int param[])
{
if (param == NULL) {
printf("param = NULL\n");
}
else {
printf("param != NULL\n");
}
printf("sizeof param = %d\n", (int)sizeof(param));
}

int main(void)
{
func(NULL);
return 0;
}

It's perfectly legal. param is a pointer, not an array. The
reference to the value of param inside func() does not invoke the
conversion of an array expression to a pointer, because it's already a
pointer. There is no array in sight (other than the string literals).
 
P

pete

Richard said:
pete said:
Richard said:
Herbert Rosenau said:
In a definition you can't left [] empty
- in a declaration you can and you would.

Pete knows that too.

char string[] = "I know about some of that";

Fair cop, guv. Herbert was, of course,
thinking about definition without
initialisation, and I was sucked into that same thought line. Must...
Stop... Trusting... People!

I am actually unable to sum the total number of times that
we've explained the same thing over and over in this thread.
Keith Thompson is also on this thread now.
Both of you guys are much better at explaining C, than I am.
I can't take this thread anymore.
Good luck to both of you and whoever may join you!
 
C

Chris Torek

You have to learn how a standard conforming compier reads *a[].

a a variable
*a a pointer to a variable

These two are correct by themselves, but:
*a[] a pointer to an array of pointers
*(a[]) a pointer to an array

these two are wrong. The "[]" subscript operator binds more tightly
than the unary "*" indirection operator, and this applies to
declarators as well. So:

int *p[10];

defines an array of 10 elements, each element having type "int *".
So does:

int *(p[10]);

You have to write:

int (*p)[10];

to define a single pointer, pointing to an array of 10 "int"s.
**a a pointer to a pointer

This one is correct.
long *a[] a declaration of an pointer to an array of pointers
as an argument, a formal parameter, on file scope or
static.

If you write:

long *a[];

int main(void) {
...
}

then "a" really has type "array 1 of pointer to long". The reason
the array has size 1 is slighty complicated, having to do with
tentative definitions. If you rewrite the declaration line to
read:

extern long *a[];

then "a" really has type "array (of unknown size) of pointer to
long". It is not a pointer to an array of pointers, nor is it a
pointer to an array of "long"s, but rather an array -- of some
size, unspecified at the point of the declaration -- of "long".

But -- there is always a "but" in C :) -- there *is* a special
case here, involving parameter declarations. The C99 draft I keep
handy says, for instance, in section 6.7.1:

[#10] On entry to the function all size expressions of its
variably modified parameters are evaluated, and the value of
each argument expression shall be converted to the type of
its corresponding parameter, as if by assignment to the
parameter. Array expressions and function designators as
arguments are converted to pointers before the call. A
declaration of a parameter as ``array of type'' shall be
adjusted to ``pointer to type,'' and a declaration of a
parameter as ``function returning type'' shall be adjusted
to ``pointer to function returning type,'' as in 6.2.2.1.
The resulting parameter type shall be an object type.

Thus, in a function prototype or function definition (6.7.1 is
about definitions), if we write:

void f(int arg[100]) {
/* code */
}

the formal parameter (arg) "obviously" has type "array 100 of int",
but *actually* has type "pointer to int". The size -- 100 -- is
dropped entirely (except, in C99, if it is marked with the "static"
keyword, or uses the new variable length array gimmicks).
 
H

Herbert Rosenau

pete said:
Richard said:
Herbert Rosenau said:
In a definition you can't left [] empty
- in a declaration you can and you would.

Pete knows that too.

char string[] = "I know about some of that";

Fair cop, guv. Herbert was, of course, thinking about definition without
initialisation, and I was sucked into that same thought line. Must...
Stop... Trusting... People!
I'm not a native english speaker. I had learned english in german pubs
by scottish peoples and mostenly by reading english comuter scinse
books. Sometimes it is easy for me to misunderstund idiomatic
expressions.

I started programming where I was 20 years old on a computer that was
only available of 12 decimal digit words, programming business
applications, going to native 8 bit assembler, over fortran 77 to
RTL2, high level macroassembler, programming human live dependant
technical applications in C, programming an realtime OS using an
defective K&R C compiler who was really unable to build char pointers
right (casts to/from char pointer ends up with illegal result). Years
later I learned ANSI C 89 and how to write strictly conforming
applications to run them under highly different OSes. On my employers
I'm known as notorious pedant as I don't like careless mistakes in
programming.

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2 Deutsch ist da!
 
M

Morris Dovey

Herbert Rosenau (in
(e-mail address removed)-ROSENAU.DE) said:

| I'm not a native english speaker. I had learned english in german
| pubs by scottish peoples and mostenly by reading english comuter
| scinse books. Sometimes it is easy for me to misunderstund idiomatic
| expressions.

Your English is more than adequate - I'd be proud of myself if I spoke
any second language as well as you speak English. FWIW, it's not
unusual for native speakers to occasionally have difficulty with
idiomatic expressions.

| I'm known as notorious pedant as I don't like careless
| mistakes in programming.

You're known that way here, too. :-D

Please don't change - I've learned much from you.
 

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

Similar Threads

Command Line Arguments 0
Why can't use fgetc() in SWITCH with CASE? 15
getc fgetc 7
Working with files 1
How can I view / open / render / display a pdf file with c code? 0
C pipe 1
comparison error 12
Text processing 29

Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,226
Latest member
KristanTal

Latest Threads

Top