2. 指针的声明

指针(Pointer)是用来保存另外一个变量地址的变量,其值是另一个变量的内存地址。

指针的作用:

  1. 通过指针可以访问和修改指针指向的内存地址的数据。
  2. 指针可以进行运算,可以通过运算改变指向的地址。

指针变量声明的语法

变量类型 *指针变量名称1 [= 初始值1] [, *指针变量名称2 [= 初始值2]][, ...];

语法说明:

  1. 中括号([]) 括起来的内容是可选的内容,可以省略不写。
  2. 变量类型 不是指针的类型,是此指针可以指向的变量的类型。
  3. 指针的类型是 变量类型 后跟一个 星号(*), 即:变量类型* 类型。
  4. 一个变量的类型如果最右侧有一个星号(*),则这个变量一定是指针类型的变量。
  5. 第二个或之后的 变量名称 如果声明为指针,则前面必须加一个 *,否则它的类型是 变量类型, 不是 变量类型* 类型。

指针说明

  1. 指针的值实质是一个整数,这个整数是指向变量的内存地址。
  2. 在同一个程序中,无论什么类型的指针变量,它的内存长度都是一样的(4 字节或 8 字节)。
    • 一般32位编译器和32位操作系统下指针变量的占用内存为 4 字节。
    • 一般64位编译器和64位操作系统下指针变量的占用内存为 8 字节。
    • 其它情况是 4 字节或 8 字节依具体编译器和操作系统来确定。
  3. 指针变量如果在声明时没有赋初始值,则指针的指向是不确定的。我们把这种指针通常称之为野指针。

示例:

// file: pointer_declaration.c
#include <stdio.h>

int main(int argc, char *argv[]) {
    int x = 1, y = 2;  // x, y都是普通的变量,类型为:int
    int *p1 = &x, *p2, *p3; // p1、p2、p3是指针,类型为:int*。

    p2 = &y;  // p2 指向 y, 即 p2 的值为 y 的地址

    // 打印 x、y 的地址
    printf("&x:%p, &y:%p\n", &x, &y);
    // 打印 p1、p2、p3的值
    printf("p1:%p, p2:%p, p3:%p\n", p1, p2, p3);

    // 打印 p1 指针占用内存的字节数
    printf("sizeof(p1):%ld\n", sizeof(p1));

    return 0;
}

说明:

运行结果如下:

weimingze@mzstudio:~$  gcc -o pointer_declaration pointer_declaration.c
weimingze@mzstudio:~$  ./pointer_declaration
&x:0x7ffe32b3fba8, &y:0x7ffe32b3fbac
p1:0x7ffe32b3fba8, p2:0x7ffe32b3fbac, p3:0x7ffe32b3fcb0
sizeof(p1):8

运行结果说明

  1. x 的地址 &x 和 p1 的值 都是 0x7ffe32b3fba8,说明 p1 的值就是 &x。
  2. y 的地址 &y 和 p2 的值 都是 0x7ffe32b3fbac,说明 p2 的值就是 &y。
  3. 上述结果 p3 可能是任意值,只是这里正好是 0 而已,请不要对未初始化的指针进行使用。
  4. p1 占用的内存数是 8 字节(这个值和操作系统有关)。

上述程序的内存结构如下:

     x      y                p1             p2             p3
  ------+------+------+--------------+--------------+--------------+----
    ... |   1  |   2  |0x7ffee40ae95c|0x7ffee40ae958|      0x0     |
  ------+------+------+--------------+--------------+--------------+----
        ^      ^      ^              ^              ^              ^
        |      |      |              |              |              |
0x7ffe32b3fba8 |  0x7ffe32b3fbb0     |       0x7ffe32b3fbc0        |
        0x7ffe32b3fbac        0x7ffe32b3fbb8              0x7ffe32b3fbc8

实验: