const char*

J

Jrdman

hi,
in some function prototypes why they use const char* instead of
const char what's the need for const here is?
if we must use const
and why they don't use char *const instead because it's the right way
to designate a const string (i think)?
 
P

Peter Nilsson

Jrdman said:
hi,
in some function  prototypes why they use const  char*
instead of const char

Because a single character passed by value is not the same
thing as a pointer to an array of characters.
what's the need for const here is?

In const char * it signifies that the characters being
pointed to are const.
if we must use const and why they don't use char *const
instead because it's the right way
to designate a const string (i think)?

What do you think of when you say 'constant string'?
Is it a string that never moves, or a string that
shouldn't change?

Strictly speaking, const means 'can't write'. It doesn't
mean 'can't change'. The purpose of const is to guard
against attempting to change data you do not have (or
give yourself) permission to change.
 
S

santoshsy

hi,
in some function  prototypes why they use const  char* instead of
const char what's the need for const here is?

1.
void display(const char*);
int main(void)
{
display("hello"); // In this case, you cannot use "const char".

return 0;
}


2.
const char* tString = "world"; //This means the string pointed to
by tString is constant
and cannot be modified.
 
B

Barry Schwarz

1.
void display(const char*);
int main(void)
{
display("hello"); // In this case, you cannot use "const char".

It is certainly permissible to pass a non-constant string to a
function expecting a pointer to const char (e.g., strcmp). What did
you really mean to say?
return 0;
}


2.
const char* tString = "world"; //This means the string pointed to
by tString is constant
and cannot be modified.

The only restriction is that the object pointed to cannot be modified
by dereferencing this pointer.

char arr[] = "world";
const char *p1 = arr;
char *p2 = arr;
p1[2] = 'u'; /* invalid */
p2[2] = 'u'; /* should be fine */
 
N

Nick Keighley

note the OP asks why you can't substitute "const char" for
"const char*". Because one's a pointer and one isn't...
He may have meant "char*" for "const char*"

It is certainly permissible to pass a non-constant string to a
function expecting a pointer to const char (e.g., strcmp).  What did
you really mean to say?

exactly what he said!

return 0;
}
2.
  const char* tString = "world";  //This means the string pointed to
by tString is constant
                                    and cannot be modified.

The only restriction is that the object pointed to cannot be modified
by dereferencing this pointer.

    char arr[] = "world";
    const char *p1 = arr;
    char *p2 = arr;
    p1[2] = 'u'; /* invalid */
    p2[2] = 'u'; /* should be fine */


--
Nick Keighley

"Merely corroborative detail, intended to give artistic
verisimilitude
to an otherwise bald and unconvincing narrative."
W.S.Gilbert
 
J

James Kuyper

Jrdman said:
hi,
in some function prototypes why they use const char* instead of
const char what's the need for const here is?

Because 'const char' designates a single character whose value cannot be
changed, while "const char*" means a pointer to a character which cannot
be changed; a character which is often the first one of a
null-terminated string of characters.
if we must use const
and why they don't use char *const instead because it's the right way
to designate a const string (i think)?

When 'const' appears before the '*', it means that the thing pointed-at
is const. When 'const' appears after the *, it means that the pointer
itself is const. Maybe this example will make it clear:

void func(const char *p, char * const q)
{
*p = 'c'; // Constraint violation
*q = 'c'; // Permitted
p = "Hello"; // Permitted
q = "Hello"; // Constraint violation
}

Which one should be used depends upon what the function needs to do with
the pointer.
 
R

Richard

James Kuyper said:
When 'const' appears before the '*', it means that the thing
pointed-at is const. When 'const' appears after the *, it means that
the pointer itself is const. Maybe this example will make it clear:

void func(const char *p, char * const q)
{
*p = 'c'; // Constraint violation
*q = 'c'; // Permitted
p = "Hello"; // Permitted
q = "Hello"; // Constraint violation
}

Which one should be used depends upon what the function needs to do
with the pointer.

Nice example.

And don't forget

const char * const *p;

Here cdecl comes in handy. e.g

rrob@debian:~$ cdecl explain "const char * const *p;"

declare p as pointer to const pointer to const char

frankly I cant even begin to figure out if that is right ...
 
A

arnuld

When 'const' appears before the '*', it means that the thing pointed-at
is const. When 'const' appears after the *, it means that the pointer
itself is const. Maybe this example will make it clear:

void func(const char *p, char * const q)
{
*p = 'c'; // Constraint violation
*q = 'c'; // Permitted
p = "Hello"; // Permitted
q = "Hello"; // Constraint violation
}

Which one should be used depends upon what the function needs to do with
the pointer.



hey James, it took me 12 months to understand it :). No, I am serious.
 
R

Richard

arnuld said:
hey James, it took me 12 months to understand it :). No, I am serious.

I wonder if its as simple as "the const element is the one to the right
of the const keyword"?

const char *p : the char is const
char * const q : q is const

I would be a liar if I didn't say I always highlight such and call up
cdecl in my editor to be sure to be sure. But then I always have to
check the syntax for typedef and struct combos to see which is the type
and which is the object created .... (primarily since I generally never use
typedef unless its in other peoples code ans am always language hopping
which causes its own problems when coming back to C)
 
R

Richard Tobin

void func(const char *p, char * const q)
{
*p = 'c'; // Constraint violation
*q = 'c'; // Permitted
p = "Hello"; // Permitted
q = "Hello"; // Constraint violation
}
[/QUOTE]
Nice example.

And don't forget

const char * const *p;

Here cdecl comes in handy. e.g

rrob@debian:~$ cdecl explain "const char * const *p;"

declare p as pointer to const pointer to const char

frankly I cant even begin to figure out if that is right ...

It's not that hard... Just as "char *p" can be read as saying "*p is
a char", so "const char *p" can be read as "*p is a const char",
and "char * const q" as "* (const q)" is a char". So in the first
case it's *p that's const, and in the second it's q.

So in "const char * const *p", *p (which is const) is a pointer to
a const char. Note that p itself isn't const.

-- Richard
 
B

Ben Bacarisse

Richard said:
I wonder if its as simple as "the const element is the one to the right
of the const keyword"?

const char *p : the char is const
char * const q : q is const

Not if people use odd orders like char const *p;

There is a simple rule the everyone sing C should know. It is one of
those simple rules that is hard to write down in exact detail (I have
done in some old posts) but the gist of it is:

(1) Find the identifier (i.e. the thing being declared/defined).

(2) Read the declaration outwards from the name, always going to
right if you can and then going left when you can't. Imagine
crossing off the symbol as you voice them so you never voice a
symbol or keyword ore than once.

(3) Bracket nesting has to be respected. I.e. when you hit a ")"
going right, you must read anything left inside these brackets
(by reading to the right now) before you cross them off as done.

So for the odd:

char const *p
^ "p is a" (now we can't go right)
^ "pointer to (a)"
^ "constant"
^ "char"

char *const p
^ "p is a"
^ "constant"
^ "pointer to (a)"
^ "char"

You can say "read-only" for "const" if you prefer to get slightly
closer the real meaning.

Let's try a more complicated one:

int *const *p[6]
^ "p is an" (here we can go right so we do)
^ "array of 6"
^ "pointers to"
^ "constant"
^ "pointers to"
^ "int"

int (*f)(int)
^ "f is a" (we can't go right until the () are done)
^ "pointer to a" (the () are not done so we go right)
^ "function taking"
^ "an int"
^ "and returning"
^ "int"
I would be a liar if I didn't say I always highlight such and call up
cdecl in my editor to be sure to be sure.

No need if use this rule. You need to do it a few times (with cdecl at
hand) to work out the wrinkles of how you like to say each symbol but
then you can read any C type with ease.

The trickiest part is when you are reading what the syntax calls a
type name -- the bit in the brackets of a cast and in some sizeof
expressions. Here, the name will be missing so you have to work out
where the name would be. I don't find that hard, but it helps to try
a few to get the hand of it.

[This lead to another hand rule: a C type name is a declaration with
the name missing.]
 
R

Richard

Ben Bacarisse said:
Not if people use odd orders like char const *p;

cecl says this is a syntax error!
There is a simple rule the everyone sing C should know. It is one of
those simple rules that is hard to write down in exact detail (I have
done in some old posts) but the gist of it is:

(1) Find the identifier (i.e. the thing being declared/defined).

(2) Read the declaration outwards from the name, always going to
right if you can and then going left when you can't. Imagine
crossing off the symbol as you voice them so you never voice a
symbol or keyword ore than once.

(3) Bracket nesting has to be respected. I.e. when you hit a ")"
going right, you must read anything left inside these brackets
(by reading to the right now) before you cross them off as done.

So for the odd:

char const *p
^ "p is a" (now we can't go right)
^ "pointer to (a)"
^ "constant"
^ "char"

char *const p
^ "p is a"
^ "constant"
^ "pointer to (a)"
^ "char"

You can say "read-only" for "const" if you prefer to get slightly
closer the real meaning.

Let's try a more complicated one:

int *const *p[6]
^ "p is an" (here we can go right so we do)
^ "array of 6"
^ "pointers to"
^ "constant"
^ "pointers to"
^ "int"

int (*f)(int)
^ "f is a" (we can't go right until the () are done)
^ "pointer to a" (the () are not done so we go right)
^ "function taking"
^ "an int"
^ "and returning"
^ "int"
I would be a liar if I didn't say I always highlight such and call up
cdecl in my editor to be sure to be sure.

No need if use this rule. You need to do it a few times (with cdecl at
hand) to work out the wrinkles of how you like to say each symbol but
then you can read any C type with ease.

The trickiest part is when you are reading what the syntax calls a
type name -- the bit in the brackets of a cast and in some sizeof
expressions. Here, the name will be missing so you have to work out
where the name would be. I don't find that hard, but it helps to try
a few to get the hand of it.

[This lead to another hand rule: a C type name is a declaration with
the name missing.]

Interesting. Thanks.

--
 

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,756
Messages
2,569,540
Members
45,024
Latest member
ARDU_PROgrammER

Latest Threads

Top