二级指针与取地址运算符

来源:互联网 发布:jxl读取5万条数据 编辑:程序博客网 时间:2024/04/29 13:05
  接下来,我们结合下面的例子来理解二级指针的概念。
[cpp] view plaincopy
  1. #include <stdio.h>  
  2.   
  3. int main(void)  
  4. {  
  5.     int a = 3;  
  6.   
  7.     int *one_ptr = &a; //相当于int *one_ptr;one_ptr = &a;  
  8.   
  9.     int **two_ptr = &one_ptr; //相当于int **two_ptr; two_ptr = &one_ptr;  
  10.   
  11.     printf("&a = %p, one_ptr = %p, *two_ptr = %p\n", &a, one_ptr, *two_ptr);  
  12.     printf("&one_ptr = %p, *two_ptr = %p\n", &one_ptr, two_ptr);  
  13.     printf("a = %d, *one_ptr = %d, **two_ptr = %d\n", a, *one_ptr, **two_ptr);  
  14.   
  15.     return 0;  
  16. }  

     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(例子中并没有打印出这个值)。

    例子结果输出:

[cpp] view plaincopy
  1. &a = 0xbfac7f28, one_ptr = 0xbfac7f28, *two_ptr = 0xbfac7f28  
  2. &one_ptr = 0xbfac7f24, *two_ptr = 0xbfac7f24  
  3. a = 3, *one_ptr = 3, **two_ptr = 3  

    *one_ptr和**two_ptr都相当于在使用整型变量a,*two_ptr就相当于在使用指针变量one_ptr。

    思考:指针变量的数据类型是什么?