c_指针

文章目录

  • *(p+1)+1表示第 1 行第 1 个元素的地址。如何理解呢?
  • 下标运算符的规则
  • 括号


int a;              // 1.一个整数
int *a;             // 2.一个指向整数的指针
int **a;            // 3.一个指向指针的指针, 它所指向的指针又指向一个整数型数据 ;一个指向 整数的指针 的指针
int a[7];           // 4.包含7个整数型数据的数组; 数组的语义就是一次性定义多个元素;
int *a[7];          // 5.包含7个指针的数组, 这些指针指向整数型数据;([]的优先级高于*,所以a先和[]结合,然后它就变成数组了,接着与 * 结合,变成指针。所以说 int *a[] 是一次性定义多个指针)
int (*a)[7];        // 6.一个指针, 它指向包含7个整数型数据的数组; 也就是说它指向的宽度为7
int (*a)(int a);    // 7.一个指向函数的指针, 该函数有一个整型形参,并返回一个整型数据; 一个指向 有一个整型形参,并返回一个整型数据函数 的指针
int (*a[7])(int);   // 8.包含7个指针的数组, 该指针指向一个函数, 该函数有一个整型形参,并返回一个整型数据
#include 
int main(){
    int a[3][4] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11} };
    int (*p)[4] = a;
    printf("%d\n", sizeof(*(p+1)));
    return 0;
}
  • *(p+1) 表示取地址上的数据,也就是整个第 1 行数据。注意是一行数据,是多个数据,不是第 1 行中的第 0 个元素,下面的运行结果有力地证明了这一点:
  • 运行结果为下面所示:

16

*(p+1)+1表示第 1 行第 1 个元素的地址。如何理解呢?

  • *(p+1)单独使用时表示的是第 1 行数据,放在表达式中会被转换为第 1 行数据的首地址,也就是第 1 行第 0 个元素的地址,因为使用整行数据没有实际的含义;
  • 编译器遇到这种情况都会转换为指向该行第 0 个元素的指针
  • 就像一维数组的名字,在定义时或者和 sizeof& 一起使用时才表示整个数组,出现在表达式中就会被转换为指向数组第 0 个元素的指针;

下标运算符的规则

  • (*arrPtr)[i] 等同于 *((*arrPtr)+i) ;
  • 也就是说 下标一次表示 在 指定的地址宽度上移动下标指定的次数,并解地址/(取值);

括号

int *(p1[10]); // 指针数组,可以去掉括号直接写作 int *p1[5];
int (*p2)[10]; // 维数组指针,不能去掉括号
  • 这里需要明白一个符号之间的优先级问题。

  • “[]”的优先级比“*”要高。p1 先与“[]”结合,构成一个数组的定义,数组名为 p1,int * 修饰的是数组的内容,即数组的每个元素。那现在我们清楚,这是一个数组,其包含 10 个指向 int 类型数据的指针,即指针数组。


  • 至于 p2 ,在这里“()”的优先级比 “[]”高,“*”号和 p2 构成一个指针的定义,指针变量名为 p2;

  • int 修饰的是数组的内容,即数组的每个元素。数组在这里并没有名字,是个匿名数组。那现在我们清楚 p2 是一个指针,它指向一个包含 10 个 int 类型数据的数组,即数组指针。

  • 这里有个有意思的话题值得探讨一下:平时我们定义指针不都是在数据类型后面加上指针变量名么?这个指针 p2 的定义怎么不是按照这个语法来定义的呢?也许我们应该这样来定义 p2:int (*)[10] p2; (我就很喜欢这样理解),int (*)[10] 是指针类型,p2 是指针变量。

  • 这样看起来的确不错,不过就是样子有些别扭。其实数组指针的原型确实就是这样子的,只不过为了方便与好看把指针变量 p2 前移了而已。你私下完全可以这么理解这点。虽然编译器不这么想。

  • 参考

http://c.biancheng.net/view/368.html

https://blog.csdn.net/lirendada/article/details/122931987

你可能感兴趣的:(笔记,c语言)