Reputation: 3413
Can someone explain to me why this doesn't work. I'm java developer and new to c/c++
As far as i understood pointer of array is actually pointer of arrays first element, is that correct?
void test(char *tmp)
{
test2(tmp);
//*tmp++ = '1';
//*tmp++ = '2';
*tmp++ = '3';
*tmp++ = '4';
*tmp = 0;
}
void test2(char *tmp)
{
*tmp++ = '1';
*tmp++ = '2';
}
int main(int argc, char **argv)
{
char tmp[5];
test(tmp);
printf("%s", tmp);
return 0;
}
only 34
gets printed. When i debug this code in function test2
pointer of tmp
is incremente by one but back in function test
after test2 is called, pointer of tmp
is back to its initial value.
If i just put all of the code in single function like this, it works:
void test(char *tmp)
{
*tmp++ = '1';
*tmp++ = '2';
*tmp++ = '3';
*tmp++ = '4';
*tmp = 0;
}
Also what does the *tmp = 0
on the last line do. I copied it from some other code. Without it there is some junk on the end of the array.
Upvotes: 3
Views: 4637
Reputation: 310930
Function parameters are its local variables. Arguments are passed to functions by values that means that copies of the arguments are passed.
So in function test2
there is used a copy of pointer tmp
of function test
. Any changes of a copy of an object do not influence on the object itself.
The call of test2 can be imagine the following way
void test(char *tmp)
{
// test2(tmp);
char *new_ptr = tmp;
test2( new_ptr );
// ...
}
void test2(/*char *tmp*/)
{
char *tmp = new_ptr;
*tmp++ = '1';
*tmp++ = '2';
}
If you declared the parameter of test2
as a reference to pointer then in this case the pointer itself could be changed. For example
void test(char *tmp)
{
test2( &tmp );
// ^^^^
//*tmp++ = '1';
//*tmp++ = '2';
*tmp++ = '3';
*tmp++ = '4';
*tmp = 0;
}
void test2(char **tmp)
// ^^^^^^^^^^
{
*( *tmp )++ = '1';
*( *tmp )++ = '2';
}
As for arrays then an array used in expression with rare exceptions as for example using an array in operator sizeof
is implicitly converted to pointer to its first element.
So if for example you have an array of type T
T a[N];
then the following declaration
T *p = a;
is valid and the pointer is initialized by the address of the first element of the array a
.
Another example
char *s = "Hello";
Here is string literal "Hello"
is used in an expression as an initializer. The string literal that includes terminating zero '\0'
has type char[6]
is implicitly converted to pointer to its first character 'H'
.
In C++ string literals have types of constant character arrays. So the string literal "Hello"
in C++ has type const char[6]
.
So in C++ you have to write
const char *s = "Hello";
But in the both languages string literals are immutable.
Upvotes: 1
Reputation: 948
The 0 is a nul terminator, the string ends with a 0 or nul byte so that functions like printf() know where the string ends, because - how long is a piece of string?
Since you're passing the pointer to test2() and test2() is incrementing the pointer - but not actually passing the altered/incremented pointer back to the calling function...as far as test() is concerned the pointer hasn't changed so subsequent alterations are overwriting previous changes.
#include <stdio.h>
#include <stdlib.h>
char *test2(char *tmp)
{
*tmp++ = '1';
*tmp++ = '2';
return tmp;
}
void test(char *tmp)
{
tmp = test2(tmp);
//*tmp++ = '1';
//*tmp++ = '2';
*tmp++ = '3';
*tmp++ = '4';
*tmp = 0;
}
int main(int argc, char **argv)
{
char tmp[5];
test(tmp);
printf("%s", tmp);
return 0;
}
Here test2 is returning the altered/incremented pointer to the caller, tess() will receive the updated char. Since you're adding the 0 or nul byte at teh end you need an array of at least 5 elements here.
the above code should work fine for you.
Upvotes: 1
Reputation: 745
It's normal that if you write all in 1 function you get 1234, but if you write 2 function passing always the same pointer the second one overwrite what the first has already done.
test:
tmp -> Point to [100]
call test2 giving [100] as parameter
write 3 in [100]
increment pointer from [100] to [101]
write 4 in [101]
increment pointer from [101] to [102]
test2:
tmp -> Point to [100]
write 1 in [100]
increment pointer from [100] to [101]
write 2 in [101]
increment pointer from [101] to [102]
Now I imagine you can see the error.
Upvotes: 0
Reputation: 17678
In function test2
, pass-by-pointer means you can modify what tmp
points to, but test2
does not modify the pointer itself.
void test2(char *tmp)
{
*tmp++ = '1';
*tmp++ = '2';
}
So in the caller function test
, after calling test2
the pointer does not move forward by 2 positions as you would expect, instead tmp
remains the same (which is pointing the the very first value of the array). So what actually happens is test2
assign 1
and 2
for the first two elements, and then test
overwrite those two values with 3
and 4
.
void test(char *tmp)
{
test2(tmp);
*tmp++ = '3';
*tmp++ = '4';
*tmp = 0;
}
Also what does the *tmp = 0 on the last line do.
That's string terminator.
Upvotes: 4
Reputation: 24847
Incrementing the 'tmp' in test2() does not increment the 'tmp' in test(). After the test2() call returns, the '1' and '2' written by test2 are overwritten by '3' and '4'.
The zero is the '\0' c-style 'string' terminator.
Upvotes: 2