c指针的简单理解

没事,看了看c, 发现c里面的指针果然是很饶人, 看了很长时间才发现或许可以, 以一种简单的说法,帮助理解。

普通变量

先来看一段代码

 #include <stdio.h>

 int main(){
     int a = 1;
     int *b = &a;
     int **c = &b;
     int ***d = &c;
     printf("The value of a is %d \n", ***d);
     printf("The value of a is %d \n", **c);
     printf("The value of a is %d \n", *b);
 }

结果是

The value of a is 1
The value of a is 1
The value of a is 1

我觉的这种是可以这么理解的, 当我们声明指针变量的时候,*的个数,代表了,寻找最终值需要跳转的次数。当我们声明***d 的时候代表需要三次跳转, 我们知道, 指针变量中存储的是变量的地址, 那么d 里面存储的是c的地址值, *d表示一次寻址操作, 找到了c中存储的b的地址值; **c ,表示两次寻址操作, 找到了存储在b中变量a的地址值, ***c 则是3次寻找操作, 直接找到了变量a的值。

通过上面我们可以看到, 其实等号左边的*与右边的&的个数是相等的。

数组&字符串

我们知道, c语言中的字符串, 其实是个字符数组, 数组的存储是内存中一片连续的地址, 而数组的地址其实就是数组第一个元素的地址。可以来段代码看下。

一维数组

 #include <stdio.h>

 int main(){
     int a[] = {1,2,3,4,5};
     printf("The addr of a is %p\n", &a);
     printf("The addr of a[0] is %p\n", &a[0]);
 }

结果

The addr of a is 0x7ffc6f876f50
The addr of a[0] is 0x7ffc6f876f50

看来的确是如此, 既然这然, 那么我们取数组值的时候, 也可以换种取法了

 printf("The value of a[1] is %p\n", *(a+1)); //The value of a[1] is 2
 printf("The value of a[0] is %p\n", *(a)); //The value of a[1] is 1

理解了这个, 我们再来二维数组

二维数组

 #include <stdio.h>

 int main(){
     int a[3][3] = {\{1,2,3}, {4,5,6},{7,8,9}};  // github报错, 猜测是因为{\{
     printf("The addr of a is %p\n", &a);
     printf("The addr of a[0] is %p\n", &a[0]);
     printf("The value of a[1][1] is %d\n", *((*(a+1))+1));  //等价于a[1][1]
 }

结果

The addr of a is 0x7ffcf109bc40
The addr of a[0] is 0x7ffcf109bc40
The value of a[1][0] is 5

其实和以为数组差不多, 只不过这时候*(a+1) 取得是二维数组中第二个数组的值, *((*(a+1))+1)取的是第二个数组的第二个值。 由此我们可以想到, 我们使用的[]其实也是一次寻址过程, 与*等价。

字符串

 #include <stdio.h>

 int main(){
     int arr[] = {1,2,3,4,5,6};
     char *name = "bob";
     printf("The addr of name %p\n", name);
     printf("The addr of character b %p, value: %c\n", &name[0], *(name));
     printf("The addr of character o %p, value: %c\n", &name[1], *(name+1));
     printf("The addr of character b %p, value: %c\n", &name[2], *(name+2));
     printf("the size of char %d\n", (int)sizeof(name[0]));
     printf("The addr of age%p\n", arr);
     printf("The addr of int 0 %p, value: %d\n", arr, *(arr));
     printf("The addr of int 1 %p, value: %d\n", &arr[1], *(arr+1));
     printf("The addr of int 2 %p, value: %d\n",&arr[2], *(arr+2));  // *(arr+2)
     printf("the size of int %d\n", (int)sizeof(arr[0]));
    return 0;
 }

结果为

The addr of name 0x4007a8
The addr of character b 0x4007a8, value: b
The addr of character o 0x4007a9, value: o
The addr of character b 0x4007aa, value: b
the size of char 1
The addr of age0x7fff9ed60780
The addr of int 0 0x7fff9ed60780, value: 1
The addr of int 1 0x7fff9ed60784, value: 2
The addr of int 2 0x7fff9ed60788, value: 3
the size of int 4

字符串数组

字符串数组和二维数组是很相似的。就不说了

再也不用为多重指针发愁了, 现在是暂时的理解, 可能是错误的, 以后会验证的。