Pointers in C: when to use the ampersand and the a

2019-01-02 21:55发布

I'm just starting out with pointers, and I'm slightly confused. I know & means the address of a variable and that * can be used in front of a pointer variable to get the value of the object that is pointed to by the pointer. But things work differently when you're working with arrays, strings or when you're calling functions with a pointer copy of a variable. It's difficult to see a pattern of logic inside all of this.

When should I use & and *?

标签: c pointers
9条回答
孤傲高冷的网名
2楼-- · 2019-01-02 21:59

Ok, looks like your post got editted...

double foo[4];
double *bar_1 = &foo[0];

See how you can use the & to get the address of the beginning of the array structure? The following

Foo_1(double *bar, int size){ return bar[size-1]; }
Foo_2(double bar[], int size){ return bar[size-1]; }

will do the same thing.

查看更多
贼婆χ
3楼-- · 2019-01-02 22:03

Yeah that can be quite complicated since the * is used for many different purposes in C/C++.

If * appears in front of an already declared variable/function, it means either that:

  • a) * gives access to the value of that variable (if the type of that variable is a pointer type, or overloaded the * operator).
  • b) * has the meaning of the multiply operator, in that case, there has to be another variable to the left of the *

If * appears in a variable or function declaration it means that that variable is a pointer:

int int_value = 1;
int * int_ptr; //can point to another int variable
int   int_array1[10]; //can contain up to 10 int values, basically int_array1 is an pointer aswell which points to the first int of the array
//int   int_array2[]; //illegal, without initializer list..
int int_array3[] = {1,2,3,4,5};  // these two
int int_array4[5] = {1,2,3,4,5}; // are indentical

void func_takes_int_ptr1(int *int_ptr){} // these two are indentical
void func_takes int_ptr2(int int_ptr[]){}// and legal

If & appears in an variable or function declaration, it generally means that that variable is an reference to an variable of that type.

If & appears in front of an already declared variable, it returns the address of that variable

Additionally you should know, that when passing an array to a function, you will always have to pass the array size of that array aswell, except when the array is something like a 0-terminated cstring (char array).

查看更多
虎瘦雄心在
4楼-- · 2019-01-02 22:07

Actually, you have it down pat, there's nothing more you need to know :-)

I would just add the following bits:

  • the two operations are opposite ends of the spectrum. & takes a variable and gives you the address, * takes an address and gives you the variable (or contents).
  • arrays "degrade" to pointers when you pass them to functions.
  • you can actually have multiple levels on indirection (char **p means that p is a pointer to a pointer to a char.

As to things working differently, not really:

  • arrays, as already mentioned, degrade to pointers (to the first element in the array) when passed to functions; they don't preserve size information.
  • there are no strings in C, just character arrays that, by convention, represent a string of characters terminated by a zero (\0) character.
  • When you pass the address of a variable to a function, you can de-reference the pointer to change the variable itself (normally variables are passed by value (except for arrays)).
查看更多
Bombasti
5楼-- · 2019-01-02 22:11

I think you are a bit confused. You should read a good tutorial/book on pointers.

This tutorial is very good for starters(clearly explains what & and * are). And yeah don't forget to read the book Pointers in C by Kenneth Reek.

The difference between & and * is very clear.

Example:

#include <stdio.h>

int main(){
  int x, *p;

  p = &x;         /* initialise pointer(take the address of x) */
  *p = 0;         /* set x to zero */
  printf("x is %d\n", x);
  printf("*p is %d\n", *p);

  *p += 1;        /* increment what p points to i.e x */
  printf("x is %d\n", x);

  (*p)++;         /* increment what p points to i.e x */
  printf("x is %d\n", x);

  return 0;
}
查看更多
We Are One
6楼-- · 2019-01-02 22:15

You have pointers and values:

int* p; // variable p is pointer to integer type
int i; // integer value

You turn a pointer into a value with *:

int i2 = *p; // integer i2 is assigned with integer value that pointer p is pointing to

You turn a value into a pointer with &:

int* p2 = &i; // pointer p2 will point to the address of integer i

Edit: In the case of arrays, they are treated very much like pointers. If you think of them as pointers, you'll be using * to get at the values inside of them as explained above, but there is also another, more common way using the [] operator:

int a[2];  // array of integers
int i = *a; // the value of the first element of a
int i2 = a[0]; // another way to get the first element

To get the second element:

int a[2]; // array
int i = *(a + 1); // the value of the second element
int i2 = a[1]; // the value of the second element

So the [] indexing operator is a special form of the * operator, and it works like this:

a[i] == *(a + i);  // these two statements are the same thing
查看更多
可以哭但决不认输i
7楼-- · 2019-01-02 22:15

Put simply

  • & means the address-of, you will see that in placeholders for functions to modify the parameter variable as in C, parameter variables are passed by value, using the ampersand means to pass by reference.
  • * means the dereference of a pointer variable, meaning to get the value of that pointer variable.
int foo(int *x){
   *x++;
}

int main(int argc, char **argv){
   int y = 5;
   foo(&y);  // Now y is incremented and in scope here
   printf("value of y = %d\n", y); // output is 6
   /* ... */
}

The above example illustrates how to call a function foo by using pass-by-reference, compare with this

int foo(int x){
   x++;
}

int main(int argc, char **argv){
   int y = 5;
   foo(y);  // Now y is still 5
   printf("value of y = %d\n", y); // output is 5
   /* ... */
}

Here's an illustration of using a dereference

int main(int argc, char **argv){
   int y = 5;
   int *p = NULL;
   p = &y;
   printf("value of *p = %d\n", *p); // output is 5
}

The above illustrates how we got the address-of y and assigned it to the pointer variable p. Then we dereference p by attaching the * to the front of it to obtain the value of p, i.e. *p.

查看更多
登录 后发表回答