473,508 Members | 2,396 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

pointers and array of pointers

Hi,
Like almost all of beginners I have problem understanding pointers.
Please, look at this piece of code, and please explain me why myswap
function doesn't work as it's supposed to do, whereas myswap2 is doing
exactly what I want it to do - swaping pointers. Where I made a mistake?
Thanks

void myswap(char *pa, char *pb){
char *tmp;
tmp=pa;
pa=pb;
pb=tmp;
}

void myswap2(char *sw[]){
char *tmp;
tmp=sw[0];
sw[0]=sw[1];
sw[1]=tmp;
}

int main(void){
char *a="1111", *b="2222", *A[]={"1111","2222"};
printf("1: %s, 2: %s\n", a,b); //stdout: 1: 1111, 2: 2222
myswap(a,b);
printf("1: %s, 2: %s\n", a,b); //stdout: 1: 1111, 2: 2222
//Not working :/

printf("2: %s, 2: %s\n", A[0],A[1]); //stdout: 1: 1111, 2: 2222
myswap2(A);
printf("2: %s, 2: %s\n", A[0],A[1]); //stdout: 1: 2222, 2: 1111
//Here it works!
return 0;
}

--
Piotrek
Apr 2 '07 #1
8 2895
Piotrek wrote:
Hi,
Like almost all of beginners I have problem understanding pointers.
Please, look at this piece of code, and please explain me why myswap
function doesn't work as it's supposed to do, whereas myswap2 is doing
exactly what I want it to do - swaping pointers. Where I made a mistake?
Thanks
First include the stdio.h header for printf.
void myswap(char *pa, char *pb){
char *tmp;
tmp=pa;
pa=pb;
pb=tmp;
}
The objects pa and pb are local to myswap, i.e. they are _copies_ of
the arguments the calling function passed to myswap, not the original
objects themselves. This method of passing parameters to functions is
called "pass by value." This is the only method C supports. To modify
the objects in the calling function, pointers to them are needed.
void myswap2(char *sw[]){
char *tmp;
tmp=sw[0];
sw[0]=sw[1];
sw[1]=tmp;
}
Arrays are always accessed by function through a pointer to their
first element. Thus the function, in this case myswap2 acts directly
on the caller's array. No copies are made.
int main(void){
char *a="1111", *b="2222", *A[]={"1111","2222"};
printf("1: %s, 2: %s\n", a,b); //stdout: 1: 1111, 2: 2222
myswap(a,b);
printf("1: %s, 2: %s\n", a,b); //stdout: 1: 1111, 2: 2222
//Not working :/

printf("2: %s, 2: %s\n", A[0],A[1]); //stdout: 1: 1111, 2: 2222
myswap2(A);
printf("2: %s, 2: %s\n", A[0],A[1]); //stdout: 1: 2222, 2: 1111
//Here it works!
return 0;
}
Just remember that a function's arguments are local objects for that
function. They're copies of whatever the calling function passed. To
modify the objects in the calling function, you need to access them
through pointers, which is what you uknowingly did, by supplying an
array argument to myswap2.

Apr 2 '07 #2
Piotrek wrote:
>
Hi,
Like almost all of beginners I have problem understanding pointers.
Please, look at this piece of code, and please explain me why myswap
function doesn't work as it's supposed to do, whereas myswap2 is doing
exactly what I want it to do - swaping pointers.
Where I made a mistake?
If you want a function to swap the values
of two objects outside the function,
then you need to give to the function
the addresses of the objects in question.
void myswap(char *pa, char *pb){
char *tmp;
tmp=pa;
pa=pb;
pb=tmp;
}
void myswap(char **pa, char **pb)
{
char *tmp;

tmp = *pa;
*pa = *pb;
*pb = tmp;
}
myswap(a,b);
myswap(&a, &b);

--
pete
Apr 2 '07 #3
Piotrek wrote:
Hi,
Like almost all of beginners I have problem understanding pointers.
Please, look at this piece of code, and please explain me why myswap
function doesn't work as it's supposed to do, whereas myswap2 is doing
exactly what I want it to do - swaping pointers. Where I made a mistake?
Thanks

void myswap(char *pa, char *pb){
char *tmp;
tmp=pa;
pa=pb;
pb=tmp;
}
void cpointer_swap(char **pa, char **pb){
char *tmp;
tmp=*pa;
*pa=*pb;
*pb=tmp;
}

[call with cpointer_swap(&ptr1, &ptr2);]
Apr 2 '07 #4
Piotrek <no*****@noreply.comwrites:
Like almost all of beginners I have problem understanding pointers.
Please, look at this piece of code, and please explain me why myswap
function doesn't work as it's supposed to do, whereas myswap2 is doing
exactly what I want it to do - swaping pointers. Where I made a
mistake?

void myswap(char *pa, char *pb){
char *tmp;
tmp=pa;
pa=pb;
pb=tmp;
}
Within the myswap function, pa and pb are local copies of the
arguments that were passed when the function was called. You swap the
local copies, which has no effect on anything outside the function.

If you want to swap two FOOs (where FOO is any arbitrary type), you
need a function that takes *pointers* to the FOOs you want to swap.
If you want to swap two pointers (of type char*), you need to pass
pointers to them (of type char**).
void myswap2(char *sw[]){
char *tmp;
tmp=sw[0];
sw[0]=sw[1];
sw[1]=tmp;
}
In a function declaration, what looks like an array parameter is
really a pointer parameter. The declaration

void myswap2(char *sw[])

means exactly the same thing as

void myswap2(char **sw)

and using the latter form can avoid confusion.

[snip]

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Apr 2 '07 #5
Piotrek <no*****@noreply.comwrites:
Like almost all of beginners I have problem understanding pointers.
[...]

I forgot to mention: if you haven't already done so, read sections 4
(Pointers) and 6 (Arrays and Pointers) of the comp.lang.c FAQ,
<http://www.c-faq.com/>.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Apr 2 '07 #6
I often think of pointers as a VARIABLE that contains a reference to
an address. So when you are calling myswap, you are passing in copies
of the references. Want you want to do in myswap is pass the pointers
by reference so you can change it. You do this by passing in type char
** and passing the address of the pointers instead. In myswap2, you
are already effectively passing by reference, which is why the swap is
reflected when it returns.

Apr 3 '07 #7
Klarth wrote:
>
I often think of pointers as a VARIABLE that contains a reference
to an address. So when you are calling myswap, you are passing in
copies of the references. Want you want to do in myswap is pass the
pointers by reference so you can change it. You do this by passing
in type char ** and passing the address of the pointers instead. In
myswap2, you are already effectively passing by reference, which is
why the swap is reflected when it returns.
What, if anything, does this mean? See below.

--
If you want to post a followup via groups.google.com, ensure
you quote enough for the article to make sense. Google is only
an interface to Usenet; it's not Usenet itself. Don't assume
your readers can, or ever will, see any previous articles.
More details at: <http://cfaj.freeshell.org/google/>

--
Posted via a free Usenet account from http://www.teranews.com

Apr 3 '07 #8
In article <eu**********@news.task.gda.pl>
Piotrek <no*****@noreply.comwrote:
>Like almost all of beginners I have problem understanding pointers.
In my experience, the usual underlying cause of problems with
understanding pointers is that they seem "special" and "magical".
The trick, then, is to realize: pointers are not special or
magical at all, in any way.

Consider an ordinary integer:

#include <stdio.h>

void silly(int x) {
x = 0;
}

int main(void) {
int i = 42;

silly(i);
printf("i is %d\n", i);
return 0;
}

The function silly() is indeed pretty silly (it does nothing useful,
setting x to 0 and then returning), but, after you get used to
by-value parameters, it is no longer surprising that it has no
effect on the variable "i" in main(). The function silly() gets
a *copy* of the value of i -- a copy of the 42, in other words --
and it changes the copy, not the original.

Pointers are not special! Pointer variables, like ordinary "int"
variables, hold values. If you change a *copy*, the original is
unchanged:

#include <stdio.h>

void silly_2(int *xp) {
xp = NULL;
}

int main(void) {
int i = 42;
int *ip = &i;

silly_2(ip);
printf("i is %d\n", i);
if (ip == &i)
printf("ip still points to i\n");
return 0;
}

Here, silly_2() gets a *copy* of the value in ip. It changes xp
-- the copy -- which affects neither ip itself, nor *ip.

On the other hand, we can make a less-silly function:

void less_silly(int *xp) {
*xp = 0;
}

and call that (instead of silly_2()) from main():

int main(void) {
int i = 42;
int *ip = &i;

less_silly(ip);
printf("i is %d\n", i);
if (ip == &i)
printf("ip still points to i\n");
return 0;
}

The call to less_silly() again gives out a *copy* of the value in
ip, but now less_silly() uses that copy (in xp) to find the place
the pointer points -- which is main()'s variable "i" -- and change
that. So less_silly() changes main()'s "i". Since less_silly()
has only a copy of the value in ip, it cannot change the value in
ip -- but it can change the value in *ip: the copy in *xp points
to main()'s "i", and the original in *ip also points to main()'s
"i".
>Please, look at this piece of code, and please explain me why myswap
function doesn't work as it's supposed to do, whereas myswap2 is doing
exactly what I want it to do ...
Here you are running into something that *is* tricky, in C. While
pointers are simple (once you understand the gimmick, i.e., that
pointers are not special at all), *arrays* in C *are* special. And
the part that is most special of all is what happens when you declare
a function's formal parameter as an array type, as in myswap2()
below:
>void myswap(char *pa, char *pb){
char *tmp;
tmp=pa;
pa=pb;
pb=tmp;
}
Here, myswap() does not work because it gets copies of the original
values (as always) and then changes the two copies. So pa and pb,
in myswap(), change; but those copies are then thrown away and the
changes vanish.
>void myswap2(char *sw[]){
Here you get the Secret Extra-Special Feature of C.

The myswap2() function has one parameter, which is named "sw".
This part is straightforward and normal. It *looks* like sw2 has
type "array (of unknown size) of pointer to char", but this part
is *not* normal.

Whenever a formal parameter has type "array N of T", for any integer
constant N and type T, the constant N is thrown away and the formal
parameter's type is rewritten as "pointer to T". (The constant N
is thrown away, so it can even be omitted, as in this case.) This
is part of The Rule about arrays and pointers in C -- for more on
that, see, e.g., <http://web.torek.net/torek/c/pa.html>.

In this case, it means that "sw" -- which *seems* to have type
"array ? of pointer to char" -- *really* has type "pointer to
pointer to char". In other words, the "true" type of myswap2()
is:

void myswap2(char **sw) {
char *tmp;
tmp=sw[0];
sw[0]=sw[1];
sw[1]=tmp;
}
So, now that we know that myswap2() really takes a "char **",
consider also what sw[0] "means". The subscript operator takes
one pointer, and one integer. It adds the two and then does
an indirection. The pointer here is "sw", and the integer is
zero. Adding 0 has no effect, so sw[0] "means" the same thing
as "*sw". Hence, the first three lines can be written as:

void myswap2(char **sw) {
char *tmp;
tmp = *sw;
*sw = ... the rest goes here ...

(With sw[1], things are a little less simple. Adding 1 *does* have
an effect, so this is the same as *(sw + 1). This relies on the
way arrays are laid out -- which is not surprising after all: it
just means that C's arrays rely on the way C's arrays work, so C's
arrays have to work for C's arrays to work. Well, of course they
do.)

If we stop relying on arrays, though, we can write a myswap3():

void myswap3(char **ppa, char **ppb) {
char *tmp;

tmp = *ppa;
*ppa = *ppb;
*ppb = tmp;
}

and now we can call myswap3() from main(), passing &a and &b,
or passing &A[0] and &A[1]:
>int main(void){
char *a="1111", *b="2222", *A[]={"1111","2222"};
printf("1: %s, 2: %s\n", a,b); //stdout: 1: 1111, 2: 2222
myswap(a,b);
printf("1: %s, 2: %s\n", a,b); //stdout: 1: 1111, 2: 2222
//Not working :/

printf("2: %s, 2: %s\n", A[0],A[1]); //stdout: 1: 1111, 2: 2222
myswap2(A);
printf("2: %s, 2: %s\n", A[0],A[1]); //stdout: 1: 2222, 2: 1111
//Here it works!
return 0;
}
Note that passing "A" is, by The Rule, the same thing as passing
&A[0]. "The Rule" about arrays and pointers in C tells us that
the "value" of an array object like "A", whenever we try to use
its value anyway -- such as in a function call -- is just a pointer
to the first element of the array. So myswap2(A) "means" myswap2(&A[0])
-- these are just two ways to write the same thing.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Apr 6 '07 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

388
21411
by: maniac | last post by:
Hey guys, I'm new here, just a simple question. I'm learning to Program in C, and I was recommended a book called, "Mastering C Pointers", just asking if any of you have read it, and if it's...
20
2904
by: fix | last post by:
Hi all, I feel unclear about what my code is doing, although it works but I am not sure if there is any possible bug, please help me to verify it. This is a trie node (just similar to tree nodes)...
19
14491
by: gaga | last post by:
I can't seem to get this to work: #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char *names; char **np;
3
3431
by: ozbear | last post by:
This is probably an obvious question. I know that pointer comparisons are only defined if the two pointers point somewhere "into" the storage allocated to the same object, or if they are NULL,...
1
1594
by: ketema | last post by:
Hello, I was wondering if someone could help me with a function I am trying to write. The purpose of the function is to read in text from a file in the following format: FIRSTNAME LASTNAME...
5
3112
by: Paminu | last post by:
Why make an array of pointers to structs, when it is possible to just make an array of structs? I have this struct: struct test { int a; int b;
36
2798
by: raphfrk | last post by:
I have the following code: char buf; printf("%lp\n", buf); printf("%lp\n", &buf); printf("%lp\n", buf); printf("%lp\n", buf); printf("%d\n", buf-buf);
64
3368
by: Zytan | last post by:
I know there are no pointers in C#, but if you do: a = b; and a and b are both arrays, they now both point to the same memory (changing one changes the other). So, it makes them seem like...
25
12989
by: J Caesar | last post by:
In C you can compare two pointers, p<q, as long as they come from the same array or the same malloc()ated block. Otherwise you can't. What I'd like to do is write a function int comparable(void...
2
2963
by: StevenChiasson | last post by:
For the record, not a student, just someone attempting to learn C++. Anyway, the problem I'm having right now is the member function detAddress, of object controller. This is more or less, your...
0
7118
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7323
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7379
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
4706
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3192
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3180
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1550
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
763
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
415
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.