I have the following function which is part of the Trie structure implementation:
int alpha_char_strlen (const AlphaChar *str) {
const AlphaChar *p;
for (p = str; *p; p++) ;
return p - str;
}
Can any one help me and explain how does the condition for the for loop hold, and precisely what is the condition in this case?
Note: AlphaChar is simply a typedef with unsigned int type and the function counts the AlphaChar characters.
The condition *p is identical to *p != 0 (if *p is of a primitive type). That is, you keep incrementing the pointer p until it points to a zero. In other words, you treat str as the pointer to a zero-terminated array.
The condition is *p, which is short for *p!=0.
So it simply scans the AlphaChar array for an occurrence of 0.
Related
Stroustrup C++ 4th Ed Page 197 has the following examples, which result in an incrementing stream of characters printed until null and not "abc". Questions: how is the ++*p being evaluated? ++ and * are the same precedence and evaluation right-to-left, therefore it's my understanding *p is evaluated first, leading to the character p points to, then this character is incremented by ++. Is this understanding correct? Thanks
#include <iostream>
using namespace std;
void fp(char* p)
{
while (*p)
cout << ++*p;
}
void fr2(char& r)
{
char* p = &r;
while (*p)
cout << ++*p;
}
int main(int argc, char *argv[])
{
char s[] = "abc";
char *p = s;
fp(p);
fr2(*p);
return 0;
}
Yes, you are right about the precedence and the associativity. This expression:
++*p;
is parsed as
++(*p);
i.e. first the indirection of p is done, and then the value returned is incremented.
This means that in the while loop:
while (*p)
cout << ++*p;
the pointer p is never actually incremented. This results in an infinite loop where just the value of p[0] is incremented forever.
Here's a demo, which shows the output as a very long sequence of ascii values starting from a. Note that abc is not printed.
By the same reasoning, the expression:
*++p;
is parsed as:
*(++p);
which is fine, since the pointer is incremented first, and then the pointer is dereferenced.
I have code that looks like this:
char* talk[516] = {(char*)1};
#define testValue (*(int*)talk[0])
I receive a null pointer exception when the following line of code is then called.
testValue = 0;
Why is that? Haven't all value of the talk[] been initialised?
EDIT
What I want to do is, there are 516 number values (floats and ints) which are stored in char* array. testValue should point to the int value that is stored in the first element of the array. The next value along might be #define testValue2(*(float*)talk[1]).
For char* talk[516] = {0};, all the elements (i.e char*) of talk are initialized with value 0 (i.e. null pointer).
For char* talk[516] = {(char*)1};, the 1st element of talk is initialized with value 1, which is not a valid value for pointer. (And the other elements are still initialized as null pointer.) *(int*)talk[0] fails, because you're trying convert a char* to int*, which points to memory address 1, and then dereference on it.
You should initialize elements with valid value, such as:
int i;
float f;
void* talk[516] = {&i, &f, /*...*/};
#define testValue (*(int*)talk[0])
#define testValue2 (*(float*)talk[1])
testValue = 1;
testValue2 = 1.5;
1. Note if use new to initialize elements of talk, you need to delete them at last.
2. You could use loop to initialize talk too.
3. Using char* instead of void* is confusing, IMO.
4. Consider about using std::map instead of macro magic.
char* talk[516] = {0};
This means that the elements of the array talk are all NULL pointers. So when you try to deference it you get that exception.
See the following substitution sequence
testValue = 0;
#
(*(int*)talk[0]) = 0;
#
char* c = talk[0]; // == 1
(*(int*)c) = 0;
#
char* c = talk[0];
int* i = (int*)c; // == ? (*)
(*i) = 0;
* Alignment issues on pointer casting
Casting a char* to int* results in undefined behavior, since int* has stricter alignment requirements than char*.
How do you access/dereference with arrays in c++??
for example, if I have this code
int num[] = {0,1,2,3};
int *p = #
I thought p was point to the first element in num array?
For some reason, I get a compiler error.
I want to use pointers and increments to access and change the value that is pointing,
for example, p gets the address of the first variable in the int array num and if I increment p, I get the address of the second variable in the int array num.
Any tips would be appreciate it.
I thought p was point to the first element in num array?
No. int *p = # is wrong, since &num is not a pointer to an int, i.e. int*, but is actually a pointer to an array of ints, i.e. int (*) [4].
To get a pointer to the first element, you can use int *p = num;, or int *p = &num[0]; instead.
Playing with pointers in c++. I have come across something unexpected. I have the code:
int main(){
char p=0;
char* ptr=&p;
cout<<"This is the pointer: "<<ptr;
return 0;
}
When I run this code the output of ptr is blank. If I change the value of p to any other value it seems to output a random pointer, e.g. value changes between runs, as I would expect. The question then is what is different about assigning a char value to 0.
Extra info: compiling with g++ 4.8.4
char p=0;
Your variable is defined as character and assigned an integer value zero, so internally you are assigning a null terminated character on variable p.
If you correct above statement as follows and print more details it may be clear to you.
char p='0';
std::cout<<"This is the pointer: "<<&ptr<<" ---"<<*ptr <<"----"<<ptr;
&&ptr- > getting the address of ptr
*ptr-> getting the value assigned to the ptr
ptr-> getting the string from ptr until it see a null terminating character, so expects garbage value as output.
Demo: http://coliru.stacked-crooked.com/a/2d134412490ca59a
char p = 0;
char* ptr=&p;
here ptr is a pointer of a zero length string. Because it is a char* pointer which point to a zore(\0) which is considered as the end of a string.
The program has undefined behaviour in case when p is not set to 0. To make it well-formed write
int main(){
char p=0;
char* ptr=&p;
cout<<"This is the character: ";
// ^^^^^^^^^^^^^^
cout.write( ptr, 1 );
return 0;
}
Or
int main(){
char p=0;
char* ptr=&p;
cout<<"This is the pointer: "<<( const void * )ptr;
return 0;
}
Otherwise this statement
cout<<"This is the pointer: "<< ptr;
simply outputs an empty string only when p is set to 0.. In other cases it will output some garbage after character p until a zero character is encountered.
Another approach can look like
int main(){
char p[2]= { 0 };
char* ptr=&p;
cout<<"This is the pointer: "<< ptr;
return 0;
}
This statement
cout<<"This is the pointer: "<< ptr;
outputs the string pointed to by ptr. A string is a sequence of characters terminated with zero character. So you should define a character array with at least two characters where the second character will be always set to 0.
Your pointer is pointing to a char which has a value of zero.
The pointer is perfectly valid.
cout is printing a zero length string.
So I know that a pointer is:
int *someNumber;
but I have run accross some code with:
int* pOutputData = nullptr;
byte* pOutputDataByte = nullptr;
What does int* mean?
Is that some kind of array of int? Is it a pointer to the type?
int * and int* are the same thing. The whitespace doesn't change anything.
int * can be used either as a pointer to int or as a pointer to the first element of an array of ints. How a variable is used is context-dependent. Judging by the variable names, I'd guess that someNumber points to a single int and pOutputData points to an array.
Both are same
White space does not mean anything in c
int * num ;
int *num;
int* num;
All the above statements are same!
We use int* as default; mainly in data structure, to avoid confusion.
Always read pointer variables from right to left
int *p means p is a pointer to an int
char *p means p is a pointer to a char
const int *p means p is a pointer to an integer constant
int * const p means p is constant pointer to an int