深入理解c指针概述
一、 指针的声明
1、通过在数据类型后面跟星号,再加上指针的名字可以声明指针。星号两边的空白符无关紧要,下面的声明都是等价的。
指针声明后,需要初始化赋值:指向未初始化的内存的指针可能会产生地址,如果将这个指针解引,指针的内容可能并不是一个合法的地址,那个地址也可能没有包含合法的数据。程序没有权限访问不合法的地址。
如下图所示,因为只声明了指针,没有初始化赋值,所以指针的内容并不是一个合法的地址,更谈不上合法的数据。
指针的声明的意义:
Ptr的内容最终应该赋值为一个整数变量的地址;
Ptr如果没有被初始化,那么就包含的是垃圾数据;
指针有类型,如果没有正确使用,会报错。
2、指针声明的阅读
Ptr是一个变量;
Ptr是一个指针变量;
Ptr是一个指向整数的指针变量;
Ptr是一个指向常整数的指针变量;
二、 指针的解引
使用操作符*镜像解引指针,将返回指针变量指向的值,一般称为解引指针。
三、 指向函数的指针
指针可以声明为指向函数,声明的写法有点难记。下面的代码说明如何声明一个指向函数的指针,函数没有参数也没有返回值,指针的名字是foo:
四、 NULL
NULL被赋值给指针,就意味着指针不指向任何东西。Null概念是指针包含了一个特殊的值,和别的指针不一样,它没有指向任何内存区域,两个null指针总是相等的。
NULL与0等价,可以将声明的指针赋值为NULL或0或一个地址,但是不能赋值其他值。
五、 void指针
void指针是通用指针,用来存放任何数据类型的引用。下面的例子就是一个void指针:
它有两个有趣性质:
(1) void指针具有与char指针相同的形式和内存对齐方式;
(2) void指针和别的指针永远不会相等,不过,两个赋值为NULL的void指针是相等的。
(3) 任何指针都可以被赋给void指针,它可以被转换回原来的指针类型,这样的话,指针的值和原指针的值是相等的。(如下图所示)
(4) void指针只做数据指针,不能用作函数指针。Sizeof可以用在void指针上,却不可以用在void上。
六、 全局和静态指针
全局和静态指针如果只是声明,没有初始化,那么系统自动会初始化为NULL;在下图中pp被声明为全局指针变量。
七、 指针的长度
取决于操作系统和编译器,里面存储的是地址,就是一个地址的长度。
(1) 给指针加上整数
实际上加的数是这个整数和指针数据类型对应字节数的乘积。
(2) void指针加上整数可能导致语法错误。
(3) 给指针减去整数,物理意义与加上一个整数相同。
(4) 两个指针相减,没有什么意义,不过在数组中,可以判断顺序。
八、 指针和常量
(1) 指向常量的常量指针
可以将指针定义为指向常量,这一位置不能通过指针修改它所引用的值。
(2) 指向非常量的常量指针
声明一个指向非常量的常量指针,这么做意味着指针变量的值不可变,但是它引用的值可变,也就是说地址指向的值是可以变的。
注意:pr必须被初始化为指向非常量的变量;
Pr不能被修改;
Pr指向的数据可以被修改;
下面将会报错: