- #include <stdio.h>
- int main(void)
- {
- int a = 3;
- int *one_ptr = &a; //相当于int *one_ptr;one_ptr = &a;
- int **two_ptr = &one_ptr; //相当于int **two_ptr; two_ptr = &one_ptr;
- printf("&a = %p, one_ptr = %p, *two_ptr = %p\n", &a, one_ptr, *two_ptr);
- printf("&one_ptr = %p, *two_ptr = %p\n", &one_ptr, two_ptr);
- printf("a = %d, *one_ptr = %d, **two_ptr = %d\n", a, *one_ptr, **two_ptr);
- return 0;
- }
1、指针的定义和本质
如例子中的第7行,它的意思是声明一个指针变量one_ptr并给此指针变量赋值整型变量a的地址值。
注意:(1)其中的星号(*)仅仅用来表示变量one_ptr是一个指针变量(一定要特别注意,one_ptr才是指针变量,而不是*one_ptr);(2)星号(*)在C语言中有三种用法,乘法运算符、间接运算符和在声明中用来表示指针,后两种的用法都与指针有关;(3)这里的数据类型关键字int与指针变量本身没有任何关系(指针变量本身也是有数据类型的,但在C语言中它没有相关的关键字来表示,我们只知道在32位的机器中指针变量通常是4个字节的,用来存储一个32位的字节地址),仅表示指针变量one_ptr只能用来存储某个整型数据(如a)的首地址,否则会警告类型不匹配。
同理,例子中的第9行,它的意思是声明了一个指针变量two_ptr并给此指针变量赋值像int *这样的数据类型变量(如one_ptr)的首地址。
总结来说,在一个指针变量声明中,靠近指针变量名字的星号(*)是星号的第三种用法,其他部分都是所声明的这个指针变量将要指向的变量的数据类型。如指针变量one_ptr将要指向的变量的数据类型为int型,指针变量two_ptr将要指向的变量的数据类型为int *型。也就是说int 和*共同决定了变量one_ptr的所有特性并有两层含义,星号(*)表示变量one_ptr是指针变量,关键字int表示这个指针变量one_ptr将要指向的变量的数据类型为整型,类似的道理,int *和*共同决定着变量two_ptr的所有特性。
2、指针变量的地址和值
在C语言中,任何类型的变量都有两个基本属性:地址和数值。地址也是一个数值,在32位的机器中,地址就是一个32位的无符号整型数。一般通过取地址运算符(&)来获取一个变量的地址值。
如例子中,变量a的数值为3,地址为&a;变量one_ptr的值为&a,地址为&one_ptr;指针变量two_ptr的值为&one_ptr,地址为&two_ptr(例子中并没有打印出这个值)。
例子结果输出:
- &a = 0xbfac7f28, one_ptr = 0xbfac7f28, *two_ptr = 0xbfac7f28
- &one_ptr = 0xbfac7f24, *two_ptr = 0xbfac7f24
- a = 3, *one_ptr = 3, **two_ptr = 3
*one_ptr和**two_ptr都相当于在使用整型变量a,*two_ptr就相当于在使用指针变量one_ptr。
思考:指针变量的数据类型是什么?