2. 指针的声明
指针(Pointer)是用来保存另外一个变量地址的变量,其值是另一个变量的内存地址。
指针的作用:
- 通过指针可以访问和修改指针指向的内存地址的数据。
- 指针可以进行运算,可以通过运算改变指向的地址。
指针变量声明的语法
变量类型 *指针变量名称1 [= 初始值1] [, *指针变量名称2 [= 初始值2]][, ...];
语法说明:
- 中括号(
[]) 括起来的内容是可选的内容,可以省略不写。 - 变量类型 不是指针的类型,是此指针可以指向的变量的类型。
- 指针的类型是 变量类型 后跟一个 星号(
*), 即:变量类型* 类型。 - 一个变量的类型如果最右侧有一个星号(
*),则这个变量一定是指针类型的变量。 - 第二个或之后的 变量名称 如果声明为指针,则前面必须加一个
*,否则它的类型是 变量类型, 不是 变量类型* 类型。
指针说明
- 指针的值实质是一个整数,这个整数是指向变量的内存地址。
- 在同一个程序中,无论什么类型的指针变量,它的内存长度都是一样的(4 字节或 8 字节)。
- 一般32位编译器和32位操作系统下指针变量的占用内存为 4 字节。
- 一般64位编译器和64位操作系统下指针变量的占用内存为 8 字节。
- 其它情况是 4 字节或 8 字节依具体编译器和操作系统来确定。
- 指针变量如果在声明时没有赋初始值,则指针的指向是不确定的。我们把这种指针通常称之为野指针。
示例:
// 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;
}
说明:
- 上述程序中指针变量 p1 是在初始化时给定了初始值是 x 变量的地址,即
&x。 - p2 开始没有给定地址,后来通过赋值表达式将 y 的地址赋值给
p2。 - p3 在声明时没有进行初始化,则 p3 的值可能是任意值(不确定的值),即野指针。
运行结果如下:
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
运行结果说明
- x 的地址
&x和 p1 的值 都是0x7ffe32b3fba8,说明 p1 的值就是 &x。 - y 的地址
&y和 p2 的值 都是0x7ffe32b3fbac,说明 p2 的值就是 &y。 - 上述结果 p3 可能是任意值,只是这里正好是 0 而已,请不要对未初始化的指针进行使用。
- p1 占用的内存数是 8 字节(这个值和操作系统有关)。
上述程序的内存结构如下:
x y p1 p2 p3
------+------+------+--------------+--------------+--------------+----
... | 1 | 2 |0x7ffee40ae95c|0x7ffee40ae958| 0x0 |
------+------+------+--------------+--------------+--------------+----
^ ^ ^ ^ ^ ^
| | | | | |
0x7ffe32b3fba8 | 0x7ffe32b3fbb0 | 0x7ffe32b3fbc0 |
0x7ffe32b3fbac 0x7ffe32b3fbb8 0x7ffe32b3fbc8
实验:
- 声明一个
char类型的指针pch1,打印此指针变量占用内存的字节数。 - 声明一个
short int类型的指针psi1,打印此指针变量占用内存的字节数。 - 声明一个
long int类型的指针pli1,打印此指针变量占用内存的字节数。