//v is a random number 0 or 1
const char *str;
//str = 48 + v; //how to set??
I tried memcpy and sprintf and get issues with it being "const char*"
I want to set "str" to 0 or 1 as defined by "v". But it must be of type " const char* "
My guess is you want to change the value of the const char after you first declare it, correct? While you cannot change the value of the const char* directly, you may be able to change the pointer value to a normal variable.
For example look at this page here: Constants in C and C++
This is what you can and cannot do using your pointers to change const values: (Adopted from link above):
const int x; // constant int
x = 2; // illegal - can't modify x
const int* pX; // changeable pointer to constant int
*pX = 3; // illegal - can't use pX to modify an int
pX = &someOtherIntVar; // legal - pX can point somewhere else
int* const pY; // constant pointer to changeable int
*pY = 4; // legal - can use pY to modify an int
pY = &someOtherIntVar; // illegal - can't make pY point anywhere else
const int* const pZ; // const pointer to const int
*pZ = 5; // illegal - can't use pZ to modify an int
pZ = &someOtherIntVar; // illegal - can't make pZ point anywhere else
This also works for chars like you're trying to do.
Here's the deal with const char *. It is a pointer to const char. const char means that the characters cannot change. The pointer is not const, so it can change.
When you do this:
str = 48 + v;
You are attempting to change a pointer to either 48 or 49, depending on what v is. This is nonsensical. If it compiled, it would point to random memory. What you want is to change what `str' points to to 0 or 1.
Since it can only point to constant characters, it can only point to something defined as a value, in quotes. So, for example, it can be set to point to "0", which is a constant character or "1", which is a constant character. So you can do something like this:
str = "0"; // point to a constant character string "0"
if( v )
str = "1"; // point to a constant character string "1"
Note that since str points to constant characters, you cannot modify what it points to:
*str = '1'; // Won't work because you are trying to modify "0" directly.
Related
This question already has answers here:
What is the difference between const int*, const int * const, and int const *?
(23 answers)
Closed last year.
I have a program like below and expect that:
with function void myFunc1 ( const int *x) ==> I cannot change the value of at the memory location that x points to, but can change the memory location that x points to.
with function void myFunc2 ( int const *x) ==> I cannot change the location that x points to as it is a const pointer. But I could change the value at the memory location that x points to.
However, upon compiling the code, I don't see the difference between const int *x vs int const *x:
in both function, the lines *x=8 in both function return error. I didn't expect error from myFunc2 because it is a const pointer, not a pointer to a const value.
in myFunc1, I expected to see value 5 after myFunc1 is close.
Could the experts here explain my 2 unexpected results above ? Here is my code:
#include "stdio.h"
int a = 5; // declared a global,
void myFunc1 ( const int *x) { // const parameter: pointer to a const int value.
// *x= 8; // error: assignment of read-only location ‘* x’ ==> cannot change the value at the location pointed by pointer. This is expected
printf("%d \n ", *x);
x = &a; // can change where the pointer point to.
// a is global and is not loss after closing myFunc2
printf("value in myFunc1: %d \n ", *x);
}
void myFunc2 ( int const *x) { // const parameter: const pointer, cannot change the address that x points to.
// *x= 8; // error: assignment of read-only location ‘* x’
printf("%d \n ", *x);
x = &a; // no compiling error here. This is not expected.
printf("value in myFunc2: %d \n ", *x);
}
int main() {
int *y;
int z = 6;
y = &z;
printf("value before myFunc1: %d \n", *y);
myFunc1(y);
printf("value after myFunc1: %d \n", *y); // expect to print 5. Result: print 6.
printf("value before myFunc2: %d \n", *y);
myFunc2(y);
printf("value after myFunc2: %d \n", *y); // expect to print 8 if the line *x=8 could be compiled . Result: print 6.
return 1;
}
I don't see the different between having 2 parameters (const int *x) vs (int const *x):
That's because int const* and const int* are the same thing.
If you want to make the pointer const, you have to put a const on its right, like this: int * const, a constant pointer to (non-constant) integer.
Unrelated (is it?) note on East const
I am one of those in favour of the so called East const, which means I prefer writing the const always on the right of what it applies to. For instance,
for a "pointer to constant int", I write int const *,
for a "constant pointer to constant int", I write int const * const.
As you see, the sentences in quotes map to the types if you read them right-to-left:
// 1 2 3 4 4 3 2 1
int const * const // constant pointer to constant int
Furthermore, always thinking of const as something that can be put on the right of what it applies to has also other advantages, sometimes in terms of peculiarities of the language that you can discover.
For instance, the following is how I discovered something more about references.
Take the declaration of a function parameter taken by reference to constant: int const& p. If you write it like this and think of it the East const way, it is clear that it declaring a p which is a reference to a constant int, not a constant reference to int.
After all, thinking East const, what would a constant reference to int look like? It'd be int & const, with the const on the right of what we'd like it to apply to, the reference &. However, this syntax is incorrect.
Why is that? Why can't I make a reference constant? Because it always is, as references cannot rebind. The standard simply doesn't let you write something totally redundant as a const applied to a reference.
Take a look at this function signature:
AudioBlock (SampleType *const *channelData, size_t numberOfChannels, size_t startSampleIndex, size_t numberOfSamples)
from here
The main type used if float* so let's think of the signature as
AudioBlock (float *const *channelData, size_t numberOfChannels, size_t startSampleIndex, size_t numberOfSamples)
What does float *const *channelData mean? channelData should be a const pointer to a float pointer? What is a const* something? I don't see the type of the inner pointer.
Suppose I want to create a vector of zeros so I can pass to AudioBlock:
std::vector<float> v(bufferOriginal.getNumChannels()*bufferOriginal.getNumSamples(), 0);
How do I get a float *const *channelData to this vector data?
What does float* const* mean?
float is a fundamental floating point type. T* is a pointer to T. const is a qualifier that applies to whatever is on the left side of it (except when it is the left most token in which case it applies to right). Since both qualifier and the pointer apply to left, it is easies to read from right to left (there are more complicated cases where this simplified rule of thumb is wrong):
float * const * // original
* const * float // reversed
* | const * | float // added spaces and separators
non-const pointer to | const pointer to | non-const float // translated to english
Arrays are an example of more complex cases where just right to left doesn't work. For the more complex rule that works with all compound types, see "clockwise rule" or "spiral rule".
So it's not possible to get a float* const * to the vector data then, right?
You could, if you had a vector like this:
std::vector<float*> vector_of_pointers;
float* const* ptr = vector_of_pointers.data();
You could make element of that vector point to your vector of floats.
vector_of_pointers.push_back(v.data());
This parameter declaration
float *const *channelData
means that the variable channelData (read from tight to left) is a pointer to a constant pointer (the pointer itself that is constant) to a non-constant object of the type float.
To make it more clear consider the following demonstrative program.
#include <stdio.h>
int main(void)
{
float x = 1.1f;
float y = 2.2f;
printf( "x = %f\n", x );
float * const px = &x;
// px = &y; // error: assignment of read-only variable ‘px’
*px = y;
printf( "x = %f\n", x );
float * const * ppx = &px;
// *ppx = &y; // error: assignment of read-only location ‘*ppx’
**ppx = 3.0f;
printf( "x = %f\n", x );
return 0;
}
Its output is
x = 1.100000
x = 2.200000
x = 3.000000
As you can see as the pointer px is a constant variable it has to be initialized when it is declared. You can not change it such a way that it will point to another variable. But you can use pc to change the value of the object pointed to by px. The variable ppx is a pointer to such a pointer.
Dear Stackoverflow community
I am trying to understand pointers better and have come across a question:
Q: When can we use a constant pointer? Give an example with a real scenario and give some code.
I had a problem trying to find and understand where a constant pointer code be used in real-life and the code involved. I am not sure if my code meets the standard of my example. I tried the following:
My Answer:
1- Definition:
A constant pointer is a pointer that cannot change the address it is holding.
2- Example:
If you want to find a specific number stored in your phone`s contacts. Rather than duplicating your entire contacts list (and al its numbers) and then checking for that specific number. Just hold its address and check the original contacts list if the number is there.
3- Code:
int main(){
const int* number = 032 ... ;
bool found = false;
Vector<int> contactList = { 031 ... , 032 ... , 072 ... };
for(int i=0; i < contactList.size(); i++){
if( *number == contactList[i]){
valid = true;
}
}
if(valid){
cout<< "Number found"<<endl;
} else{
cout<< "Number NOT found"<<endl;
}
}
Firstly a const pointer and a pointer to const are different things:
a const pointer itself is const. It cannot be pointed to anything other than the thing it is already pointing to, be the thing it points to might be altered:
int i = 5;
int *const p1 = &i; // a const pointer
++*p1; // valid code. i is now 6
int j = 0;
p1 = &j; // error
a pointer to const itself may point to different things, but it assumes everything it points to is const, so it won't allow altering them:
int i = 5;
const int * p2 = &i; // a pointer to const
++*p2; // error
int j = 0;
p2 = &j; // valid code. p2 is now pointing to j
I assume your question is "Why would anyone use a pointer which assumes everything is const?". There may be many reasons. One of them is, when you see const int * as a function parameter, you know this function is not going to mess with your variable. It's going to stay the same after the function returns. This is essentially why we use const anyway. We could just not change variables instead, but by declaring them as const we know compiler is going to make sure our variables are not changed by mistake or misunderstanding or anything else.
Pointer to const or const pointer ?
You need to be careful about the way to define a const pointer. Because a const pointer is not a pointer to const.
static int table[10];
const int* number = table; // non const pointer to const
int * const number2 = table; // const pointer to non const
number++; // this is allowed because the pointer is not const
*number += 2; // this is NOT allowed because it's a pointer to const
number2++; // this is NOT allowed because the pointer is const
*number2 +=2; // this is allowed because the const pointer points to a non const
By the way, be careful with leading 0 since they mean octal notation:
cout << 032 <<endl; // displays 26 in decimal since 032 is octal notation
Pointers, addresses and values
Be aware of the difference between a pointer and the value pointed to. Fortunately C++ protects you in forbidding this:
const int* number = 032; // compiler error
If you want to keep a pointer to a specific value:
int myvalue=032;
const int* number = &myvalue; // ok as long as you remain in scope
Caution when pointing to vector elements
Last but not the least, if you'd be tempted to use a pointer to a vector element, be aware that the address of a vector element may change (and pointers be invalid) in certain cases, for example when the vector needs to grow.
Example of what you're trying to do
Now let's put all this together, and here a slightly modified program:
const int * number; // const to avoid accidental overwrite
int search; // value to search for
cout<<"What number are you looking for ? ";
cin>>search;
for(int i=0; i < contactList.size(); i++){
if( contactList[i] == search){ // compare values
number = &contactList[i]; // set pointer
found = true;
}
}
// if the vector is not modified, you may use the pointer.
if(found){
cout<< "Number found: "<< *number <<endl;
}
else{
cout<< "Number NOT found"<<endl;
}
I am surprised that the following behavior of C++ (Visual Studio 2012 compiler).
char * * PointerToPointerToChar = NULL;
char * const * PointerToConstPointerToChar = NULL;
char const * * PointerToPointerToConstChar = NULL;
PointerToPointerToConstChar = PointerToPointerToChar; // Assignment 1: Gives compiler error as I would expect
PointerToConstPointerToChar = PointerToPointerToChar; // Assignment 2: NO COMPILER ERROR ???
PointerToPointerToChar = PointerToPointerToConstChar; // Assignment 3: Gives compiler error as I would expect
PointerToPointerToChar = PointerToConstPointerToChar; // Assignment 4: Gives compiler error as I would expect
I understand the const keyword in C++, specifically how it's placement affects what is considered const (the entity to the left).
It seems like the compiler tries to protect the user of the RHS variable from a const-stripping alias at either level of indirection (assignments 3 and 4). But the LHS is only protected from a const-stripping alias at one level of indirection (assignment 1) and not the other level of indirection (assignment 2). In other words, given that the following is prevented by the compiler
PointerToPointerToConstChar = PointerToPointerToChar; // Assignment 1: Gives compiler error as I would expect
PointerToPointerToChar[0][0] = 'A'; // The user of the LHS variable was effectively lied to about the constness of the *characters* - second level of indirection
then why isn't the following also prevented by the compiler
PointerToConstPointerToChar = PointerToPointerToChar; // Assignment 2: NO COMPILER ERROR ???
PointerToPointerToChar[0] = NULL; // The user of the LHS variable was effectively lied to about the constness of the *pointers* - first level of indirection
Is this correct C++, and if so what is the rationale? It seems inconsistent. Thanks!
The type const* doesn't mean the value won't change, it means you can't change it using that pointer.
Because if you could do that, you could assign to the *PointerToPointerToConstChar any const char* - while PointerToPointerToChar relies on it being normal char*. If that was allowed:
PointerToPointerToConstChar = PointerToPointerToChar; // assume PointerToPointerToChar is pointing to a valid memory block
const char str[] = "Hello world!";
*PointerToPointerToConstChar = str;
(*PointerToPointerToChar)[0] = 'X'; // Oops, we just modified a const array
You have a Pointer to something that is const. The pointer is not const, just what it points to. You assign to that pointer a pointer to something that is not const. That is fine. The pointer is not const and the const in this case just tells us, that the object pointed to will not be changed through this pointer. It doesn't have to be const anywhere else.
char* c = someCharPointerSomewhere;
PointerToConstPointerToChar = PointerToPointerToChar;
*PointerToConstPointerToChar = c // const violation
*PointerToPointerToChar = c // this is fine
// now *PointerToConstPointerToChar will be c as well.
Then why can you not assign to a pointer to a pointer to const? Well, the pointer to const is a different type than a pointer to non const. The implicit conversion we have above does not apply in this case. You could use this pointer to let the pointer it points to point to something, that actually is const. Then the original pointer would allow to modify the const value indirectly.
const char c = 'c';
PointerToPointerToConstChar = PointerToPointerToChar;
*PointerToPointerToConstChar = c;
**PointerToPointerToChar = 'a'; // const violation!
It is a bit confusing, when you just read the explanations, but take your time and think it through. It really is logically consistent that way.
Assigning a char** to a char* const* is analogous to assigning a char* to a const char*. It makes perfect sense.
char array[] = "foo";
char* ptr1 = array; // Can change array through ptr1
char const* ptr2 = ptr1; // Can't change array through ptr2
Use of char** and char* const* complicates what can and what can't be changed a bit more.
char** ptrptr1 = &ptr1;
// Can change where ptr1 points to through ptrptr1
*ptrptr1 = <some other char*>; // OK
// Can change the value of what ptr1 points to through ptrptr1.
(*ptrptr1)[0] = 'x'; // OK
char* const* ptrptr2 = ptr1;
// Can't change where ptr1 points to through ptrptr2
*ptrptr2 = <some other char*>; // Not OK
// Can change the value of what ptr1 points to through ptrptr2.
// (*ptrptr2) is still of type 'char*'.
(*ptrptr2)[0] = 'x'; // OK
From my understanding, const modifiers should be read from right to left. From that, I get that:
const char*
is a pointer whose char elements can't be modified, but the pointer itself can, and
char const*
is a constant pointer to mutable chars.
But I get the following errors for the following code:
const char* x = new char[20];
x = new char[30]; //this works, as expected
x[0] = 'a'; //gives an error as expected
char const* y = new char[20];
y = new char[20]; //this works, although the pointer should be const (right?)
y[0] = 'a'; //this doesn't although I expect it to work
So... which one is it? Is my understanding or my compiler(VS 2005) wrong?
Actually, according to the standard, const modifies the element directly to its left. The use of const at the beginning of a declaration is just a convenient mental shortcut. So the following two statements are equivalent:
char const * pointerToConstantContent1;
const char * pointerToConstantContent2;
In order to ensure the pointer itself is not modified, const should be placed after the asterisk:
char * const constantPointerToMutableContent;
To protect both the pointer and the content to which it points, use two consts.
char const * const constantPointerToConstantContent;
I've personally adopted always putting the const after the portion I intend not to modify such that I maintain consistency even when the pointer is the part I wish to keep constant.
It works because both are same. May be you confused in this,
const char* // both are same
char const*
and
char* const // unmutable pointer to "char"
and
const char* const // unmutable pointer to "const char"
[To remember this, here is a simple rule, '*' affects its whole LHS first]
That is because the rule is:
RULE: const binds left, unless there is nothing on the left, then it binds right :)
so, look at these as:
(const --->> char)*
(char <<--- const)*
both same! oh, and --->> and <<--- are NOT operators, they just show what the const binds to.
(from 2 simple variable initialization question)
A really good rule of thumb regarding const:
Read Declarations Right-to-Left.
(see Vandevoorde/Josutiss "C++ Templates: The Complete Guide")
E.g.:
int const x; // x is a constant int
const int x; // x is an int which is const
// easy. the rule becomes really useful in the following:
int const * const p; // p is const-pointer to const-int
int const &p; // p is a reference to const-int
int * const * p; // p is a pointer to const-pointer to int.
Ever since I follow this rule-of-thumb, I never misinterpreted such declarations again.
(: sisab retcarahc-rep a no ton ,sisab nekot-rep a no tfel-ot-thgir naem I hguohT :tidE
Here is how I always try to interpret:
char *p
|_____ start from the asterisk. The above declaration is read as: "content of `p` is a `char`".
char * const p
|_____ again start from the asterisk. "content of constant (since we have the `const`
modifier in the front) `p` is a `char`".
char const *p
|_____ again start from the asterisk. "content of `p` is a constant `char`".
Hope it helps!
In both of your cases you're pointing to a constant char.
const char * x //(1) a variable pointer to a constant char
char const * x //(2) a variable pointer to a constant char
char * const x //(3) a constant pointer to a variable char
char const * const x //(4) a constant pointer to a constant char
char const * const * x //(5) a variable pointer to a constant pointer to a constant char
char const * const * const x //(6) can you guess this one?
By default, const applies to what is inmediately at is left, but it could apply to what is inmediately at its right if there's nothing preceeding it, as in (1).