您的位置:首页 > 其它

常见的指针数据类型以及const用法详解

2014-04-16 23:21 453 查看
1.有关指针的数据类型小结:

int i; 定义整型变量i

int *p; p为指向整型数据的指针变量

int a
; 定义整型数组a,他有n个元素

int *p
; 定义指针数组p,它由n个指向整型数据的指针元素组成

int (*p)
; p为指向含有n个元素的一位数组的指针变量

int f; f为带回整型函数值的函数

int *p() p为带回一个指针的函数,该指针指向整型数据

int (*p)() p为指向函数的指针,该函数返回一个整型值

int **p p是一个指针变量,它指向一个指向整型数据的指针变量

大致的规则:

理解复杂声明可用的“右左法则”:从变量名看起,先往右,再往左,碰到一个圆括号就调转阅读的方向;括号内分析完就跳出括号,还是按先右后左的顺序,如此循环,直到整个声明分析完。举例:

int (*func)(int *p);

首先找到变量名func,外面有一对圆括号,而且左边是一个*号,这说明func是一个指针;然后跳出这个圆括号,先看右边,又遇到圆括号,这说明(*func)是一个函数,所以func是一个指向这类函数的指针,即函数指针,这类函数具有int*类型的形参,返回值类型是int。

int (*func[5])(int *);

func右边是一个[]运算符,说明func是具有5个元素的数组;func的左边有一个*,说明func的元素是指针(注意这里的*不是修饰func,而是修饰func[5]的,原因是[]运算符优先级比*高,func先跟[]结合)。跳出这个括号,看右边,又遇到圆括号,说明func数组的元素是函数类型的指针,它指向的函数具有int*类型的形参,返回值类型为int。

也可以记住2个模式:

type (*)(....)函数指针

type (*)[]数组指针

2.const 用法小结:

(1)限定符声明的变量只能被读 const int i = 5; int j = 0; i=j;非法,导致编译错误。j=i;合法

(2)必须初始化 const int i = 5;合法 const int j;非法,导致编译错误

(3)在另一个连接的文件中引用const常量 extern const int i; 合法,extrern const int j =10;非法。常量不可以被再次赋值(而且在定义的文件中也应有const并初始化,而非const变量默认为extern)

(4)便于进行类型检查:用const 方法可以使编译器对处理内容有更多了解。#define I=10, const long &i = 10;/*dapingguo提醒:由于编译器的优化,使 得在const long i=10; 时i不被分配内存,而是已10直接代入以后的引用中,以致在以后的代码中没有错误,为达到说教效果,特别地用&i明确地给出了i的内存分配。不过一旦你关闭所有优化措施,即使const long i=10;也会引起后面的编译错误。*/ char h=I; //没有错
,char h=i; //编译警告,可能由于数的截短带来错误赋值。

(5)可以避免不必要的内存分配:#define STRING "abc\n" ,const char string[]="abc\n" printf(STRING);为其分配了一次内存,下次仍要分配,printf(string);为string分配了内存,以后不再分配内存。由于const定义常量从汇编角度看,只是给出了对应的内存地址,而不是像#define给出立即数,所以,const定义的常量在程序运行过程中只有一份拷贝。而#define定义的常量在内存中有若干个拷贝。

(6)可以通过函数对常量进行初始化: int value(); const int i = value();假定对ROM编写程序时,由于目标代码的不可改写,本语句将会无效,不过可以变通一下:const int

&i=value(); 只要令i的地址处于ROM之外,即可实现:i通过函数初始化,而其值有不会被修改。

(7)const常量值的修改:通过强制类型转换,将地址赋给变量,再做修改即可,例如:const int i = 0; int*p = (int*)&i;p=100;

(8)const引用是指向const对象的引用,const int ival =1024;const int &refval = ival; 正确,可读取但是不能修改refval,因为不能对refval赋值,所以不能通过refval修改ival.所以 int

&ref2 = ival;错误.const引用可以初始化为不同类型的对象或初始化为右值,例如int i = 42; const int &r = 42; const int &r2 = r + i;同样的方式非const变量就是编译错误的。

原因如下:double dval = 3.14; const int &ri = dval;编译器将其转换为,int temp = dval; const int &ri = temp;因为const引用是只读的。因为如果不是const的话对ri的改变相当于

改变temp但是dval并未改变。非const引用只能绑定到与该引用同类型的对象,const引用则可以绑定到不同但相关的类型的对象或绑定到右值。

(9)指向const对象的指针:const double *cptr,不能用*cptr修改其值,不能用非const类型的指针指向一个const类型的变量地址例如 const double pi =3.14;double*ptr = π错

误不能使用void*保存const对象的地址,只能使用const void*,允许把非const对象的地址赋值给指向const对象的指针,而且不能通过指针修改其值。

(10)如果指向const的指针指向的是非const的对象,则可以通过直接给该对象赋值或间接地利用非const指针修改其值。

(11)const指针:int errNumb = 0; int *const curErr = errNumb;不能给该指针赋值

(12)指向const对象的const指针,详见下面的(引用参考)

(13)指针和typedef,例如:typedef string *pstring ; const pstring cstr;等价于string *const cstr;

参考文章:http://wenku.baidu.com/link?url=tAtw3igZisezAI2p98fNBJQTLbd8uIBrCjPzwU0zhK9DnN2nx3EaLZvxKkdPh4YXjvh61ar5b__ivhhYtNoxpTPC8jKrbe7qh23p2Exs5dG
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: