C语言之指针

没有内存就没有指针

CPU 只能通过地址来取得内存中的代码和数据,程序在执行过程中会告知 CPU 要执行的代码以及要读写的数据的地址。如果程序不小心出错,或者开发者有意为之,在 CPU 要写入数据时给它一个代码区域的地址,就会发生内存访问错误。这种内存访问错误会被硬件和操作系统拦截,强制程序崩溃,程序员没有挽救的机会。

CPU 访问内存时需要的是地址,而不是变量名和函数名!变量名和函数名只是地址的一种助记符,当源文件被编译和链接成可执行程序后,它们都会被替换成地址。编译和链接过程的一项重要任务就是找到这些名称所对应的地址。

指针的长度由地址总线决定,也就是说CPU的寻址能力。
不要说是字长,字长是根据数据总线决定的。有的机器数据总线和地址总线不一定都是一样的
像现在64位机器中很对地址总线都是32位的

指针运算符 * (常和去地址操作符&一起出现)

  • 表示乘法,例如int a = 3, b = 5, c; c = a * b;,这是最容易理解的。
  • 表示定义一个指针变量,以和普通变量区分开,例如int a = 100; int *p = &a;。
  • 表示获取指针指向的数据,是一种间接操作,例如int a, b, *p = &a; *p = 100; b = *p;
  • 指针也有地址,指向指针的指针被称为二级指针,以此类推

数组指针,和指针数组

  • 指针数组比较好理解 intp[2];[]优先级高于,所以首先这是个数组,其次数组里面元素的类型是int*
  • 数组指针,指向数组的指针(即代表它的基本单位是数组,即运算的步长是一个数组的大小),也叫二维数组指针(当然一维也可以用,但是没有实际意义)
    #include <stdio.h>
    int main(void) {
    int arr2[2][2] = {{1,2},{3,4}};
    printf("%x\n",arr2);
    int arr1[2] = {1,2};
    int (p)[2] = arr2;
    printf("%x\n",p);
    printf("%d\n",
    p[0]);
    printf("%d",*(++p)[0]);
    return 0;
    }
    输出结果
    1908fec0
    1908fec0
    1
    3

可以看到int (*p)[2] = arr2;(数组名弱化成指针,即数组首地址)两者是一致的
p[0]即是数组第一列首地址首个元素arr2[0][0]的地址,取值就是1
p++指向arr2[1],即是数组第二列首地址首个元素arr2[1][0]的地址,取值就是3

void*和NULL

  • void*只代表一个地址信息,没有任何类型信息
  • void*可以接收任何类型的指针
  • void*赋值给别的类型指针(看标准),C++是需要强转的
  • NULL不等价于0,虽然有时候一样
  • NULL是系统极小的一部分不被使用的地址空间,依操作系统而定
上一篇:二维数组问题:从键盘输入二维数组行列值,往数组中随机填充0-50之间的数字,二维数组中数据先行后列方式从大到小的顺序排列后以矩阵形式输出,并且计算两条对角线的数字之和。


下一篇:40.在两个长度相等的排序数组中找到上中位数