|
Actually, the reason is that 'char*' is not a type. A '*' belongs to the variable. In other words, this is valid C code:
char *pch, ch;
ch = 'A';
pch = &ch;
I'm a pure C programmer. I don't know how it works for C++ though.
|
|
|
|
|
The K&R answer is probably good enough. But I also taught it as the algebraic expression, that
* = 1/& (or * is the inversion of &).
Therefore declaring "char *c" says "*c" is a character, and &(*c) => Pointer, but & and * cancel.
Therefore c is a pointer to a character.
So, if you view it as *c is a the char in question, I think it explains that approach pretty clearly.
Having learned C a VERY long time ago, I have always used, and mostly saw "char *c" or "char c[]"!
the scary part in the old days was explaining how:
13[c] = 'x';
would be handled, as it DID compile!
and according to the answer definition of [] at the time, it was converted to:
*(13+c) = 'x';
and therefore was the same as c[13] = 'x';
|
|
|
|
|
char *c better aligns with C/C++ philosophy, but char* c is safer.
The syntax char *c says *c (c dereferenced) is a char , which makes c a pointer to char . However, teaching/learning this syntax/philosophy can be hard when people are just getting introduced to pointers.
Also, the declaration char *c, d makes c a char* , but d a char . This confuses beginners who are used to declarations such as int a, b which makes both a and b int s.
Thus, the declaration char* c is preferred: easier to learn and safer.
|
|
|
|
|
nullusDefectus wrote: Also, the declaration char *c, d makes c a char* , but d a char . This confuses beginners who are used to declarations such as int a, b which makes both a and b int s.
Thus, the declaration char* c is preferred: easier to learn and safer.
Your claim and conclusion are backwards! It's writing char* c, d; that confuses beginners for the exact reason that you give.
Writing char *c, d; is the correct way to teach, learn, and remind yourself and readers of your code that the * applies to c only.
Given the language grammar...
simple-declaration ::= decl-specifier-seq init-declarator-list(optional) ;
Note the space ---^
... writing...
char *c;
---^
... also demonstrates that you know what you're doing. This is how you explain it to beginners and they will remember...
|
|
|
|
|
I always the * next to the variable since you can convert most types into a pointer with the * modifier. Otherwise, this looks inconsistent:
char *p0;
char *p1, *p2;
Uwe Baemayr
Senior Software Developer
Micro Focus
|
|
|
|
|
char *c; matches the structure of the C grammar. If you declare three pointers, the declaration looks like char *c, *d, *e;
But people think of the '*' as belonging with the type, so they write char* c;
|
|
|
|
|
modified 29-May-18 12:20pm.
|
|
|
|
|
There are indeed pointer types, but there are no pointer type specifiers. The pointer-ness of something is specified by a combination of the type specifier(s) and the declarator. For a pointer like
char *p;
the type of p is "pointer to char " or char * , but that type is obtained by the combination of the type specifier char and the pointer declarator *p . Sure, you can write it as char* p; , but it will be parsed as char (*p); .
Something like
T *p1, *p2, *p3; should be perfectly understandable to anyone who understands C and C++ declaration syntax, but nobody does because it's not taught properly for some bizarre reason. It's such a fundamental part of the language, but it's invariably glossed over in every introductory text so as not to scare off beginners. So people inevitably bluescreen the first time they see something like a pointer to an array or a pointer to a function because the simplistic-to-the-point-of-being-wrong version of C declaration syntax they were taught doesn't account for it.
Yes, pointers are scary and difficult to understand at first. They're also a fundamental part of C programming (less so C++, but still important). C (and C++) declaration syntax needs to be taught properly and completely. But since it isn't, we need to come up with a bunch of coding standards to make up for it. So, no more than one declaration per line, because it's too hard to explain how char* a, b; really works.
Once you understand the rules, pointer declarations (including pointers to arrays, pointers to functions, pointers to arrays of functions returning pointers to arrays of pointers to int) make perfect sense. But apparently nobody understands the rules, so the language looks arbitrary and capricious.
|
|
|
|
|
I've noticed you italicized a lot of things relating to "understanding" how the language works. Many who do understand it feel the declaration syntax sucks inherited from C is a PITA.
If only programmers were taught declaration syntax, they'd come across this and the intention would be clear:
int (*f(int x))[3]
{
}
Also, I think my argument is somewhat supported by:
using T = char*;
T a, b;
Yes, I understand the grammar, and yes, I understand how this is different vis-a-vis grammar, but I'm not arguing about the grammar, I'm arguing about what _style_ is more "C++-esque". Here, T is the type specifier with no pointer declarator. The _type_ is actually now `char*` So when declaring these two names, they have the same types. That's the more natural use case one would expect from a programming language. Clearly, this is a matter of taste, but again, I'll point out that Bjarne Stroustrup is clearly on my side of this disagreement. Here's a funny quote from one of the links I included in my first post:
"The flip side of this is that you have to deal with old mistakes and with compatibility problems. For example, I consider the C declarator syntax an experiment that failed"
From this interview: Slashdot | Interviews | C++ Answers From Bjarne Stroustrup
|
|
|
|
|
I didn't realize most preferred 'char* c' as opposed to 'char *c'. My initial intro to C was K&R so I started out with the former, but long ago switched to the latter, it just feels better somehow. I will say this in regards to 'char *c', though I realize this is wholly a religious debate and do not wish to antagonize, but it makes this look better: 'char *a, *b, *c;' Full disclosure, I use the 'goto' statement too.
|
|
|
|
|
Consider also multi level pointers:
char **ppCh;
char *c[];
etc.
|
|
|
|
|
.jpg wrote: char is a type and c is a name, to me, it always make more sense to put the name alone and have the type together, like "char* c", I can tell immediately that it is a pointer to a char, so its always goes like [type] [name].
But in contrast, most C/C++ code I found prefer the other way around, like "char *c". Is there any specific reasons why this is so?
My guess is that most C programmers hail from the K&R (Kernighan and Ritchie) days and I believe that char *c is the form they would have used. (I lost my dear old K&R years ago). Beyond that, it's probably just personal habit.
If you think hiring a professional is expensive, wait until you hire an amateur! - Red Adair
|
|
|
|
|
My $0.02.
In general variables are declared as:
type varname;
So ask the questions:
What is the type of varname?
What is the varname?
char c;
char* c;
double d;
float f;
double* d;
float* f;
Ultimately, BOTH ARE CORRECT.
As long as all devs in a team/organization use the same code format style guide, IT DOESN'T MATTER.
Just be consistent.
www.pointwise.com
|
|
|
|
|
Because that's how both the C and C++ grammars work. The asterisk binds to the thing being declared, not the type.
A declaration like
int* a, b;
is parsed as
int (*a), b;
Declarations in C (and simple declarations in C++) are a sequence of declaration specifiers followed by one or more (optionally initialized) declarators. The declarator is what specifies the name along with the the pointer-ness, array-ness, and/or function-ness of the thing being declared. Given a sequence of declaration specifiers D 1, then the following are all true:
D *p;
D a[N];
D f();
D *ap[N];
D *fp();
D (*pa)[N];
D (*pf)();
D (*fpa())[N];
D (*apf[N])();
The things following D are the declarators. *p is a declarator, as is a[N] , as is *ap[N] , as is (*pa)[N] . Since both [] and () operators have higher precedence than unary * , an expression like *a[N] parses as *(a[N]) . To declare a pointer to an array or a pointer to a function, you must explicitly group the * operator with the thing that points to the array or function.
This is why the common convention (at least among C programmers) is char *c; and not char* c; .
I understand where the type* name and type& name conventions came from in C++, and when I write C++ I follow that convention. But I feel dirty every time I do it.
1. Declaration specifiers include storage class specifiers like static , auto , and typedef , type specifiers like int , double , struct foo , and type qualifiers like const or volatile
modified 30-May-18 12:28pm.
|
|
|
|
|
To me, char* c looks badly formatted, same as if someone did x+ 3 .
Traditionally, I would use char *c , but after using java for several years, I prefer to use char * c now.
|
|
|
|
|
Because of this:
char *c, *p, a, *b, d;
or a better way to write that:
char *c = nullptr,
*p = nullptr,
a = 5,
*b = nullptr,
d = 10;
(it took out my tabs...)
modified 31-May-18 10:07am.
|
|
|
|
|
Replaced the blown PSU, put machine back together.
all running happily, 3 hours and counting.
Methinks OK, (these ASUS boards are meant to have some extra protection.)
Another backup - onto my new SSD external drive. Man these things are fast, and now well priced.
The only cheap thing in this build was the case + PSU combo, it failed, rest is fine.
Lesson learned: pay for the quality top-to-bottom. (It's my work machine).
Sub lesson learned: I'm never going to spin again. SSD Rocks!
Signature ready for installation. Please Reboot now.
|
|
|
|
|
And the next step after the PSU is the UPS (no not the delivery service)
|
|
|
|
|
They are well worth having!
Mine can (in theory) run my PC, two monitors, the NAS, and the router for an hour - in practice most powercust here last less than ten minutes, So I have ample time to save and shut down cleanly, and ride out the short cutouts we tend to get as "after shocks" once the power is restored.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
modified 26-May-18 7:04am.
|
|
|
|
|
Quote: Mine can (in theory) ruin my PC Am I glad I don't have an UPS
|
|
|
|
|
Fixed ... but not so far from the truth.
Last century I was working at the weekend - we all were, big hardware contract and we were building kit like crazy - when we got a local ground strike by lightning. Fred was earthed at the time and he ... um ... noticed it.
Took out the telephone exchange, the fax, and the IDE card in every computer that was plugged into the mains, regardless of if it was powered up or not. 24 hours later and we we back up and running.
Not so the company down the road who has a big UPS to run their VAX. The lead/acid batteries exploded and sprayed the computer with sulphuric acid. Nasty.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
OriginalGriff wrote: a big UPS to run their VAX. The lead/acid batteries exploded and sprayed the computer with sulphuric acid.
Sorry but I could only laugh when I read that.
Imagine how reassured they felt installing the UPS for just the sort of event.
Signature ready for installation. Please Reboot now.
|
|
|
|
|
For the next two weeks I will be keeping a low profile, going to Sicily to pay my respects to "il padrone". See if maybe I can interest him in my pirating skills.
So don't worry if I will be a bit quiet in the CodeProject forums
[Edit]
One of my tires was also keeping a low profile, it was flat, luckily discovered it before we had to go to Schiphol airport tomorrow and could change it in time !
modified 26-May-18 10:06am.
|
|
|
|
|
Quote: So don't worry if I will be a bit quiet Omertà, that's it.
Enjoy Sicily!
|
|
|
|
|
Grazie mille per il suggerimento
Started practicing my Italian on this nice site: Duolingo[^]
|
|
|
|
|