|
Lopatir wrote: The article you read was written by someone that either referred to a different programming language, or doesn't understand the C/C++ language definitions; char* is not a type in C/C++.
Far as I can recall it was a columnist in the C++ Programmers Journal. I suspect that they did in fact have a passing familiarity with the language. And since at least two columnists in that magazine participated in the C++ ANSI committee I suspect that their opinion on that subject of C++ would have carried more weight than any other random developer. They provided a rational for why that form was more appropriate which, far as I can recall, was not grounded solely in the semantics in the language but more in common usage of type specifiers. But I could certainly be mistaken about what they actually said.
Not to mention of course "The Annotated C++ Reference Manual" written by Ellis and Stroustrup which in section 4.7 has the following code examples.
void f(char* cptr, void* vptr)
...
int* p1 =
...
char* cptr;
int* iptr;
void* vptr;
So seems like the creator of the language prefers that form as well.
My original usage was grounded in the form you are championing but that was based on K&R. I found the article I read persuasive enough that I started using the other form.
|
|
|
|
|
To remind users that
char* a , b
may not do what they intend.
|
|
|
|
|
|
Which is why I never use comma separated variable declarations.
char* a , b, c[12], *d[5];
char* a;
char b;
char c[12];
char* d[5];
www.pointwise.com
|
|
|
|
|
Nor do I. I'm of the opinion that doing so should at least raise a warning.
|
|
|
|
|
the variable is the type, and the type stays the type. The * goes with the variable because you're modifying defining how the variable will be using the type. You're not, as it were, modifying the type.
cheers
Chris Maunder
|
|
|
|
|
Chris Maunder wrote: the variable is the type, and the type stays the type. The * goes with the variable because you're modifying defining how the variable will be using accessing the type value. You're not, as it were, modifying the type.
Signature ready for installation. Please Reboot now.
|
|
|
|
|
OK, fair enough.
cheers
Chris Maunder
|
|
|
|
|
Great answer. When I define a pointer I'm using char *p; because this is pointer. It stores an address and points a char value in this address. So, '*' is serving as a pointing device for p address register, (I think) it must be declared with address register.
|
|
|
|
|
My 2 cents, I prefer
char* c; too, as I've learned years ago.
To quote Wikipedia and what I've learned (Pointers section) : "A pointer is a data type that contains the address of a storage location of a variable of a particular type."
Nevertheless, this same Wikipedia section points out that writing it is a matter of style :
char* c;
char * c; or
char *c;
All right for everyone
Not mentioning the confusing writing for arrays of pointers...
So the type of "char*" is a "pointer on a char".
The type of "int*" is a "pointer on an int".
And so on...
|
|
|
|
|
Member 10753505 wrote: arrays
int x[2];
0[x] = 1[x]; is perfectly valid and utterly disgusting in C/C++.
Software Zen: delete this;
|
|
|
|
|
Meh. They are technically a data type but they need to lean on someone else to have meaning in their lives. They're like the really needy data type the other data types only play with because he has cool toys.
cheers
Chris Maunder
|
|
|
|
|
Not always : a void pointer lives its own live and you can made point it on every type or on... nothing !
|
|
|
|
|
void pointers make me sad.
cheers
Chris Maunder
|
|
|
|
|
Chris Maunder wrote: void pointers make me sad.
cheers
Chris Maunder
So appearently, you haven't seen any void pointers lately
|
|
|
|
|
I've always liked option 3: char * c . It avoids the problems char* c, d; can cause but still keeps it separate from the name. * is just like const or any other modifier. You wouldn't write constchar* c so why mash them together just because it's a single character (and allowed)?
|
|
|
|
|
When doing more than one variable declaration makes sense to put the * correctly, or you do not get what you expect.
When writing:
char* a,b,c;
you get the equivalent of:
char *a,b,c;
and you would probably expect:
char *a,*b,*c;
|
|
|
|
|
Because that's how the compiler parses it. The * binds to the variable not the type.
Think about
char* a, b;
This suggests that b is also a char *, but actually it is only a char. Much clearer when you write
char *a, b;
(Not that I would advocate doing either - even better to have two separate declarations - but it illustrates the point).
Ian Brockbank
"Legacy systems are systems that are not protected with a suite of tests. ... You are building legacy code every time you build software without associated tests." - Mary and Tom Poppendieck, Implementing Lean Software Development.
|
|
|
|
|
If you always puts your declarations on separate lines (or separated by ';') it doesn't matter. But if you do -- be aware.
Say that you have;
char* c;
char* d;
char* e;
and, for some reason, probably even a good one, decides to put them on one line ... in a bit of hurry so that you ends up with;
char* c,d,e;
But if you had
char *c;
char *d;
char *e;
there is a pretty good chance you would end up with;
char *c, *d, *e;
This is also the reason for the typedef's of pointers, eg.
typedef char * char_p;
char_p c;
char_p d;
char_p e;
would be
char_p c, d, e;
rgds /Jonas
ps.
char* c, d, e; --> char* c; char d; char e;
|
|
|
|
|
|
Why 68? Well, it was a fun language, especially for its time. But the language did't define a concrete syntax at all (there was an Algol68 with keywords in German - fully conformant to the Algol68 standard), so you couldn't use it to settle any concrete syntax arguments.
Switching to C# is really a far better solution: Make everything pointers, so that you never say that it is a pointer. If it is an object, then a name of that object is a pointer to it. No way to avoid. That makes it so much simpler, never having to worry about this being a struct, that being a pointer to a struct and something else being a pointer to a pointer to an array of pointers to a struct...
|
|
|
|
|
Thank you for your reply. I was a programmer years ago, and don't know C# too well. I'd be interested to know how, in C#, you would do this ...
REF INT ri;
INT i1, i2;
BOOL condition;
...
( condition | ri := i1 | ri := i2 );
ri := 1;
...
It's probably blindingly obvious, but, as I say, I'm not conversant with C#
|
|
|
|
|
Simple
Its C that is the pointer not the char.
So char *c makes more sense
Or read it in reverse (a standard way to understand C/C++)
C is a pointer to char
It also looks nicer!
|
|
|
|
|
As an aside, in the last century the leading PC C++ compiler vendor was not Microsoft but Borland. One day they got too big for their boots and issued a proclamation which dictated that all users of their IDE must code in their prescribed style - which included suffixing the "*" to the type instead of K&R's prefixing "*" to the variable name. It was at this point that I stopped using Borland.
For the sake of consistency, I can't resist also applying the K&R style to references too; although I'm clearly flying in the face of convention from the majority of code examples that I see in books and on-line.
|
|
|
|
|
I still prefer Borland C/C++ when I write C; I don't recall being forced one way or the other, but I'll try it later.
None of the following compilers complained about char* a , b :
HP C V7.3-009 on OpenVMS Alpha V8.3
Borland C++ 5.5 for Win32 Copyright (c) 1993, 2000 Borland
gcc version 3.2 (mingw special 20020817-1)
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86
I expected HP C to complain because I compiled with CHECK messages enabled:
CHECK Messages reporting code or practices that,
although correct and perhaps portable, are
sometimes considered ill-advised because
they can be confusing or fragile to
maintain. For example, assignment as the
test expression in an "if" statement.
modified 31-May-18 12:40pm.
|
|
|
|