PoorLuzer
PoorLuzer

Reputation: 25056

Differences between pointer initializations

I am speaking in Standard, K&R C.

Given:

const char a[] = {1, 2, 3};
const char *p = NULL;

Are these two statements equivalent:

  1. *p = a;

  2. p = a;

Each of them would be on the third line of the snippet.

1 and 2 certainly don't look the same.

What's the difference between the two then?

Upvotes: 1

Views: 430

Answers (7)

Bruno Reis
Bruno Reis

Reputation: 37822

The * operator is what we call the dereference operator. To understand what it does, you must understand exactly what a pointer is.

When you do

char *p;

the "variable" p does not use the same amount of memory as a normal char, it uses more memory: it uses the amount of memory needed to correctly identify a memory position in your computer. So, let's say you use a 32-bit architecture, the variable p occupies 4 bytes (not the 1 byte you would expect from a char).

So, when you do

p = a;

you see clearly that you are changing the contents of the variable p, that is, you are putting another 32-bit number inside it: you are changing the address it is pointing to.

After that line executes, the value of p is the memory address of the character array a.

Now for the dereference operator. When you do

*p = 'Z';

you are telling the compiler that you want to store the value 'Z' ON THE ADDRESS pointed by p. So, the value of p remains the same after this line: it continues to point to the same address. It's the value of this address that has changed, and now contains 'Z'.

So, the final effect of

char a[] = {'a', 'b', 'c'};
char p = a;
*p = 'Z';

is the same as changing the first position of the array a to 'Z', that is:

char a[] = {'a', 'b', 'c'};
a[0] = 'Z';

NOTE: there is a difference when making a pointer point to an array: the variable that contains the array contains only the address of the first element, so a is the same as "the starting address of the array".

Usually you will see the & operator. It is an operator used to obtain the memory address of a variable. For example:

int number = 42;
int pointer = &number;
printf("%d", *pointer);

Here we have them all. The first line creates an integer variable and stores 42 inside it.

The second line creates a pointer to an integer, and stores the address of the variable number inside it.

The third line reades the value on the address pointed by the pointer.

So, the trick is to read *x as on the address pointed by x and &x as the address of x.

Upvotes: 2

Bill K
Bill K

Reputation: 62769

Here's a trick I used when I learned C (and still use today).

Whenever you see the * in front of a variable in your code, automatically read it as "what is pointed to by".

So you should be able to easily see that setting "p" to "a" is very different from setting "what is pointed to by p" to "a".

Also, since p is supposed to be pointing at a char, setting that char p is pointing at (currently the "char" at memory location 0 assuming null is 0) to a char pointer (a) is probably going to fail at compile time if you are lucky (depending on your compiler and lint settings it may actually succeed.)

from comment:In a function declaration like f(char c), I usually try to separate out the variable name from the rest of it--so it would be f( (char) c). so c is a char*. Exactly like a variable definition.

Also & usually reads as "The address of", but that gets even more iffy. A few examples of how I read things to myself. May or may not help you.

int a[] = {1,2,3}; // I mentally parse this as (int[]) a, so a is an int array.
int *p;            // p is a pointer to "integers"
int i;
p=a;               // p acts exactly as a does now. 

i=*p;          // i is "What is pointed to by" p (1)
i=p;           // i is some memory address
i=*a;          // i is what is pointed to by a (1)
i=p[1];        // Don't forget that * and [] syntax are generally interchangable.
i=a+1;         // Same as above (2).
p=&i;          // p is the address of i (it can because it's a pointer)
               // remember from hs algebra that = generally reads as "is", still works!
*p=7;          // what is pointed to by p (i) is 7;
a=*i;          // whoops, can't assign an array.  This is the only difference between
               // arrays and pointers that you will have to deal with often, so feel
               // free to use which ever one you are more comfortable with.

char c='a';
char *  d = &c;// d is a char pointer, and it is the address of c
char ** e ;    // e is a pointer to a memory location containing
               // a pointer to a char!
e=&d;          // gets d's address. a pointer to a pointer gets
               // the address of a pointer.  Messy but gets the job done

**e=5;         // what is pointed to by what is pointed to by e is 5.
*e=&'f';       // what is pointed to by e (which is a char * itself, and is still d!)
               // is set to the address of the memory location holding the value 'f'.
               // does not change c or e, just d! 

I haven't touched c in 10 years, so some of this may be a bit wrong, but it helps me to read it out loud that way.

Upvotes: 1

user14554
user14554

Reputation:

I think you are mistaking:

char a[8];
char *p=a;

which is legal and does the same as:

char a[8];
char *p=NULL;
p=a;

with:

char a[8];
char *p=NULL;
*p=a;

which as others said would generate a compile error or a segmentation fault.

 In the left side of declarations you should read *x as pointer(x) while in
 statements it must be read as value_pointed_by(x). &x on the other hand
 would be pointer_to(x)

Upvotes: 1

GManNickG
GManNickG

Reputation: 503855

The first dereferences a null pointer, and tries to assign it the address of the array. This will be a compiler error, because char != char []. If it weren't, it would likely crash.

The second sets p to point to the the array.

Upvotes: 1

Nippysaurus
Nippysaurus

Reputation: 20378

  1. Because "*p" dereferences the pointer wouldnt this make "p" a "char**" ?
  2. This would point "p" to the first array as expected.

I guess they are not the same.

Upvotes: 0

cmcginty
cmcginty

Reputation: 117018

No, they are not equivalent

If p = NULL, then doing *p = a will give you a segmentation fault.

Upvotes: 0

jkeys
jkeys

Reputation: 3955

No.

p = a initializes the pointer to point to something else (usually it copies another pointer or you will point to a reference, ala p = &a.

*p = a initializes what p refers to. You are "dereferencing" (looking at) what p points to. If p points to NULL as in your example, you will crash (this is good! you do not want to accidentally access something and mess your program up).

In this case, p = a will point to the first of the array a[], and *p = a will attempt to change the first of the array (it won't work; you have it declared const).

Here is a small example program in C++, with almost identical syntax to C.

#include <iostream>

int main()
{
    char arr[5] { 'a', 'b', 'c' }; // arr[3] and arr[4] are set to 0
    char *ptr = arr; //point to 'a'

    for (int i = 0; i != 5; i++)
    {
       *ptr = 'f'; //this changes the array
       ptr++; //this changes what the pointer points to; moves it to next in array
    }

    for (int i = 0; i != 5; i++)
    {
        std::cout << *ptr << " ";
    }

    //outputs f f f f f
}

Upvotes: 4

Related Questions