c pointers notation basic question

E

Eric Sosman

If you coding style says that the first should really be:

double sumx; // The Sum of the X values
double sumy; // The Sum of the Y values
double sumxx; // The Sum of the square of the X values
double sumyy; // The Sum of the square of the Y values
double sumxy; // The Sum of the product of the X and Y values

Then also allowing only one variable per line isn't as big of a limitation.

Many years ago -- many decades ago, in fact -- I had a colleague
who wrote his code in a style that minimized keypunching time. (See
"many decades," above.) One space, not several, separated his
assembler opcodes from the operands, and from the label if there
was one. Registers were referred to by number, not name, and of
course comments were not to be found anywhere:

L 0,X
L 1,Y
CR 0,1
BNL STORE
LR 0,1
STORE ST 0,MAX

The Management was not happy. "Use register names, not numbers.
Line up the columns. And write comments, dammit, comments!" So
he wrote himself a neatener program that took in his usual source
code and spat out

L R0,X LOAD R0 FROM X
L R1,Y LOAD R1 FROM Y
CR R0,R1 COMPARE R0 TO R1
BNL STORE BRANCH TO STORE IF NOT LOW
LR R0,R1 LOAD R0 FROM R1
STORE ST R0,MAX STORE R0 TO MAX

Dunno why, but something about the added value of the comments
you exhibit reminds me of my long-ago colleague's exploit.
 
S

Shao Miller

Agreed. On the other hand, I still prefer
char *p;
over
char* p;
because it reflects the grammar.

Where whitespace causes the mind to instinctively partition the latter
into two pieces and where 'char*' isn't a type-specifier. But in the
former, we have:

char *p;
^^^^ ^^-- [init-declarator-list_opt], [init-declarator],
| [declarator], [pointer_opt direct-declarator]
+- [declaration-specifiers],
[type-specifier declaration-specifiers_opt]

But one more space could "split up" [pointer_opt direct-declarator].

char * p;
^^^^ ^ ^

I usually see the argument that this is undesirable because it's not
consistent with a convention of applying the indirection operator
without any whitespace. (Although we know that it's not that operator
in this particular declaration context.)

*p + 1; /* A tight fit */
* p + 1; /* What?! */
On the other other hand, if I always followed that rule, my if /
else / else if statements would crawl across the screen.

if (foo)
do_this();
else
if (bar)
do_that();
else
if (baz)
do_thother();
else
help();
 
S

Shao Miller

Roberto Waltman said:
bpascal123 wrote:
char *pc;
pc points to a type char data

Is there any difference with this notation?
char* pc;

No.

"White space" (spaces, tabs, new-lines, etc.) is not relevant, so all
of the following are equivalent: [snip]
It is recommended to use the form "char *pc;" to make clear what is a
pointer and what is not when declaring more than one variable in a
single statement.

char *yes_a_pointer, not_a_pointer;

It's also recommended not to declare more than one variable in a single
declaration (not statement):

char *yes_a_pointer;
char not_a_pointer;

Yah. Shrug. Whaddevah.

double sumx;
double sumy;
double sumxx;
double sumyy;
double sumxy;

*So* much better than

double sumx, sumy, sumxx, sumyy, sumxy;

It's a crying shame the grammar permits the latter, don't you think?

double
sumx,
sumy,
sumxx,
/* Ooh, this next one's a good one */
sumyy,
sumxy,
* summingelse,
/* Could probably do without this */
* summore,
** sumtimetoday;
 
Ö

Öö Tiib

It might be often, but not often when considering C89/C90 compatibility,
of course.

On such case I would likely use CLang to translate the code from C99 to C89
immediately prior to compiling. Are those 20 years old C compilers used a
lot in practice?
 
S

Shao Miller

On such case I would likely use CLang to translate the code from C99 to C89
immediately prior to compiling. Are those 20 years old C compilers used a
lot in practice?

It's still in use for Windows compilers, and possibly will be for as
long as there is a Windows C compiler. Someone at Microsoft explained
this to me.
 
S

Stephen Sprunk

Of if you prefer to declare and initialise them at the point of first
use.

Some coding styles require declaring all variables at the top of a
block. This is mandatory if your code must work with MSVC, which is
permanently stuck at C89.

S
 
S

Stephen Sprunk

Bjarne Stroustrup, as I recall, advocates "char* pc;"

Really? Bizarre. If he thought that was better, he should have changed
the syntax and semantics so that actually worked in practice.

Yes, that would cause a gratuitous difference between C and C++, but
there are plenty of those already anyway.
(and avoiding multiple declarations per line),

An annoying kludge that is probably a direct result of the above
problem, which he could have fixed if he wanted to.

S
 
K

Keith Thompson

Shao Miller said:
On 3/16/2013 19:37, Keith Thompson wrote: [...]
On the other other hand, if I always followed that rule, my if /
else / else if statements would crawl across the screen.

if (foo)
do_this();
else
if (bar)
do_that();
else
if (baz)
do_thother();
else
help();

If I consistently followed the rule of having layout reflect syntax, I'd
write the above as:

if (foo)
do_this();
else
if (bar)
do_that();
else
if (baz)
do_thother();
else
help();

or, with braces:

if (foo) {
do_this();
}
else {
if (bar) {
do_that();
}
else {
if (baz) {
do_thother();
}
else {
help();
}
}
}

Instead, I pretend that "else if" is part of the grammar rather
than just one case of the other rules, and I write, as most C
programmers do:

if (foo) {
do_this();
}
else if (bar) {
do_that();
}
else if (baz)
do_thother();
}
else {
help();
}

(Some languages make "elseif", "elsif", or "elif" a keyword for just
this reason).
 
K

Keith Thompson

Stephen Sprunk said:
Really? Bizarre. If he thought that was better, he should have changed
the syntax and semantics so that actually worked in practice.

It actually does work in practice.

char* ptr;

defines ptr as a pointer to char in both C and C++.
Yes, that would cause a gratuitous difference between C and C++, but
there are plenty of those already anyway.


An annoying kludge that is probably a direct result of the above
problem, which he could have fixed if he wanted to.

A reasonable stylistic preference, IMHO.

I don't agree with Stroustrup on this point, but I haven't found his
recommendations to cause any real problems, as long as you're aware of
the language rules.
 
P

Phil Carmody

Keith Thompson said:
Roberto Waltman said:
bpascal123 said:
char *pc;
pc points to a type char data

Is there any difference with this notation?
char* pc;

No.

"White space" (spaces, tabs, new-lines, etc.) is not relevant, so all
of the following are equivalent: [snip]
It is recommended to use the form "char *pc;" to make clear what is a
pointer and what is not when declaring more than one variable in a
single statement.

char *yes_a_pointer, not_a_pointer;

It's also recommended not to declare more than one variable in a single
declaration (not statement):

Only by wusses.

Anyone who submits a patch containing:

+ int i;
+ int j;
+ int k;

to me is going to get a NACK and a patronising comment to assist them
in remembering not to do the same thing again. And you all wonder why
Greg KH doesn't want your code, eh?

Phil
 
I

ImpalerCore

It actually does work in practice.

    char* ptr;

defines ptr as a pointer to char in both C and C++.



A reasonable stylistic preference, IMHO.

I don't agree with Stroustrup on this point, but I haven't found his
recommendations to cause any real problems, as long as you're aware of
the language rules.

The issue in my opinion is that the interpretation of '*' is different
between variable declarations and other interpretations when applying
'*' to a type.

Most people interpret '*' as a type modifier, like in contexts like
sizeof.

For example, sizeof (double) is different from sizeof (double*), where
'*' modifies the type, and is interpreted as 'double' and 'double*'
respectively.

In variable declarations, that interpretation isn't held anymore.

double *x, y;

The '*' in this situation is now a variable modifier, where 'x' is now
a pointer variable to type double, and 'y' is a normal variable of
type double. The grammar betrays the common vernacular that applying
'*' to a type modifies the type.

All in all it's not a big deal, but I still prefer 'double* x' over
'double *x' for that reason.

Best regards,
John D.
 
S

Shao Miller

The issue in my opinion is that the interpretation of '*' is different
between variable declarations and other interpretations when applying
'*' to a type.

Most people interpret '*' as a type modifier, like in contexts like
sizeof.

For example, sizeof (double) is different from sizeof (double*), where
'*' modifies the type, and is interpreted as 'double' and 'double*'
respectively.

You can also do 'sizeof (double(*))'.
In variable declarations, that interpretation isn't held anymore.

double *x, y;

The '*' in this situation is now a variable modifier, where 'x' is now
a pointer variable to type double, and 'y' is a normal variable of
type double. The grammar betrays the common vernacular that applying
'*' to a type modifies the type.

You can also do 'double (* x), (y);'
All in all it's not a big deal, but I still prefer 'double* x' over
'double *x' for that reason.

There's also 'double * x'.
 
8

88888 Dihedral

Shao Milleræ–¼ 2013å¹´3月20日星期三UTC+8上åˆ2時37分08秒寫é“:
You can also do 'sizeof (double(*))'.










You can also do 'double (* x), (y);'








There's also 'double * x'.



--

- Shao Miller

--

"Thank you for the kind words; those are the kind of words I like to hear..



Cheerily," -- Richard Harter

Nowadays a PC system with the 64 bit OS with a 2 to 4 core
cpu and a hard disc of tera bytes and giga bytes of DRAM is selling in the street under 2000 USD.

Well, the pointer part can be taught as a key to
a declared object. The pointer offers another way other than
the slow deep copy method for an object to be passed around
functions efficiently in the time critical applications.
 
G

Geoff

Keith Thompson said:
Roberto Waltman said:
bpascal123 wrote:
char *pc;
pc points to a type char data

Is there any difference with this notation?
char* pc;

No.

"White space" (spaces, tabs, new-lines, etc.) is not relevant, so all
of the following are equivalent: [snip]
It is recommended to use the form "char *pc;" to make clear what is a
pointer and what is not when declaring more than one variable in a
single statement.

char *yes_a_pointer, not_a_pointer;

It's also recommended not to declare more than one variable in a single
declaration (not statement):

Only by wusses.

Anyone who submits a patch containing:

+ int i;
+ int j;
+ int k;

to me is going to get a NACK and a patronising comment to assist them
in remembering not to do the same thing again. And you all wonder why
Greg KH doesn't want your code, eh?

Phil

It depends a lot in which shop you're working.

AV Rule 62
The dereference operator ‘*’ and the address-of operator ‘&’ will be
directly connected with the type-specifier.

Rationale: The int32* p; form emphasizes type over syntax while the
int32 *p; form emphasizes syntax over type. Although both forms are
equally valid C++, the heavy emphasis on types in C++ suggests that
int32* p; is the preferable form.

Examples:
int32* p; // Correct
int32 *p; // Incorrect
int32* p, q; // Probably error. However, this declaration cannot
occur
// under the one name per declaration style required by AV Rule 152.

AV Rule 152
Multiple variable declarations shall not be allowed on the same line.

Rationale: Increases readability and prevents confusion (see also AV
Rule 62).

Example:
int32* p, q; // Probably error.
int32 first button_on_top_of_the_left_box, i; // Bad: Easy to
overlook i
 
J

John Bode

Hi

Can someone help me out remember basic pointer notation?

p points to a type int data
int *pi;

char *pc;
pc points to a type char data

Is there any difference with this notation?
char* pc;
No.

Is pc is still pointing to type char data above?
Yes.

I understand notation '*' operator means pointer. So if it's following the
variable type declaration like int* or char*, is it a different meaning as
if there is a space like int *var ?

No.

It's an accident of C (and C++) syntax that you can write it either way, or
with any amount of whitespace in between:

T *p;
T* p;
T * p;

All three of the above declarations will be interpreted as though they had
been written

T (*p);

IOW, the '*' is always bound to the declarator. If you write a declaration
like

T* a, b;

only a will be declared as a pointer to T; b will be declared as a regular T.

Declarations in C (and C++) are based on the types of *expressions*, not
objects. For example, if we have a pointer to int named p, and we want to
access the value that p points to, we use the '*' operator to dereference it:

x = *p;
printf("value = %d\n", *p);

The type of the *expression* '*p' is int, so the declaration is written as

int *p;

If we had an array of pointers to int, and we want the value being pointed
to by the i'th element, we'd write

x = *ap;
printf("value = %d\n", *ap);

The type of the *expression* '*ap' is int, so the declaration is written as

int *ap[N];

In both declarations above, '*p' and '*ap[N]' are known as *declarators*; they
introduce the name of the thing being declared, along with additional type
information not provided by the type specifier. The int-ness of 'ap' is given
by the type specifier 'int', while the array-ness and pointer-ness are given by
the declarator '*ap[N]'. We *could* write the above as

int* ap[N];

but that's discouraged for a number of reasons.

Note that many C++ programmers use the 'T* p;' style, as opposed to 'T *p;',
because there are times in C++ where you really do want to emphasize the type
of the object. The problem with this style is that it only works for simple
pointers; once you start getting into arrays of pointers, or pointers to arrays,
or pointers to functions returning pointers to arrays, or arrays of pointers to
functions returning pointers to functions returning pointers to arrays of
pointers to pointers to int, etc., that style stops being useful.

As an example, suppose we have a pointer to an array of pointers to functions
returning pointers to 'int'. To get to an integer value, we have to deference
the pointer to the array, retrieve the i'th element, dereference that pointer,
call the pointed-to function, and then dereference the result:

x = *(*(*fp))();
printf("value = %d\n", *(*(*fp))());

Again, the type of the *expression* '*(*(*fp))()' is int, so the declaration
is written as

int *(*(*fp)[N])(void);

which reads as

fp -- fp
*fp -- is a pointer
(*fp)[N] -- to an N-element array
*(*fp)[N] -- of pointers
(*(*fp)[N])( ) -- to functions
(*(*fp)[N])(void) -- taking no parameters
*(*(*fp)[N])(void) -- returning pointers
int *(*(*fp)[N])(void) -- to int

Now, if you *really* *really* *really* wanted to use the 'T* p;' convention
with something like the above, you could create some typedefs:

typedef int *ipf(void);
typedef ipf *iparr[N];

iparr* fp;

but frankly, that doesn't make anything any clearer. You won't usually types
that obnoxious in the wild, but they do crop up occasionally.
 
J

James Kuyper

....
It's an accident of C (and C++) syntax that you can write it either way, or
with any amount of whitespace in between:

It's not really an accident. C declarations were deliberately designed
to mirror the way the declared identifier could be used. "* p" and
" *p" are equally valid expressions, with precisely the same meaning,
resulting in a value of type T, so "T* p" and "T *p" should be equally
valid ways of declaring p.
NB: not all of the declarational freedom that could be inferred by
abusing this argument actually exists in C declarations.
 
I

Ian Collins

88888 said:
Nowadays a PC system with the 64 bit OS with a 2 to 4 core
cpu and a hard disc of tera bytes and giga bytes of DRAM is selling in the street under 2000 USD.

All that hardware and you still can't quote correctly.
 
8

88888 Dihedral

(e-mail address removed)æ–¼ 2013å¹´3月20日星期三UTC+8下åˆ2時54分54秒寫é“:
You really need to find a better place to buy PCs. You can get a

brand name system with those specs for $500 (including a Windows

license), a white-box shop ought to be able to do one for $300 with

Linux.

As an engineer I prefer just quoting the upper bound of
my budgets.

It is cheap to write programs plus a dedicated machine
to those professionals with high hourly wages to save their time.
 

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

Forum statistics

Threads
474,077
Messages
2,570,566
Members
47,202
Latest member
misc.

Latest Threads

Top