C++指针心得
来源:互联网 发布:藏文输入法软件下载 编辑:程序博客网 时间:2024/06/07 01:58
指针定义的时候是指向一个地址,如:
int a = 10;
int *b = &a;
b中存储的是a的地址,解引用可以得到地址为a的变量的值,即*b
既然指针存储的是地址,那么二维指针指向的就是地址的地址,如:
int a = 10;
int *b = &a;
int **c = &b;
因为解引用得到的是值,那么指针存放的就是地址,因此c中存的是b的地址,*c就是b中的值,即a的地址
所以,如下代码:
int *p = *c;
因为*c是a的地址
那么代码等同于
int *p = &a;
或
int *p = b;
引用的用法是:
int a = 10;
int &b = a;
当对b复制的时候,如:
b = 30;
此时不是像对变量复制的过程那种在堆栈中新增加一个变量,找到变量b所在的地址,b地址存放的值是变量a的地址,因此给b赋值的过程如下:
找到变量b的地址,读取该地址下的值,即a的地址,之后通过a的地址,修改a地址下的值为30
如果引用过程中涉及类型转换,如:
double a = 3.14;
int &b = a;
b = 7;
实际上b没有改变a的值,因为对于有类型转换的引用,编译器实际是这样处理的:
int temp = a;
int &b = temp;
b = 7;
所以b更改的是临时的中间变量temp,而不是a
指向const的指针和const指针:
指针的读法是从右向左读,如:
int *a;
读成a是一个指针,指向int,同理,如下指针:
const int *a;
读成a是一个指针,指向int,int是const的,也就是说,指针所指向的值不会变而指针可以自由移动,成为指向const的指针
const指针是这样的,如:
int *const a;
读成a是一个const指针,指向int,这就说明a指针指向int型的数据后就不能移动了,而所指向的数据可以修改,因此声明const指针的时候不许进行初始化
这样就可以理解指向const的const指针,如:
const int *const a;
这就说明a要指向固定的值不能动,而指向的值也不能被修改
char指针
const char *a = “abcdefg”;
用字符串常量初始化指向const char的指针a时,字符串的结尾会自动添加\0空白符
如果用数组声明的话,如:
char a[4] = “abcd”;
会报错,说为数组进行初始化的值过长,因为这时候实际常量后面有了\0空白符,因此数组长度应该是5
如果这样声明,如:
char a[4] = “abc”;
就对了
用循环进行初始化的时候,如
char a[4];
for(int i = 0;i < 4;i++)
{
a[i] = ‘b’;
}
cout<<a<<endl;
运行后打印出来的结果在bbbb后面还有一堆乱码的值,这是因为没有在结尾添加\0空白符
在循环中加上
if(i == 3)
{
a[i] = ‘\0’;
break
}
就可以正确的打印出结果了
对于一维数组
int a[5];
当访问相应的下标a[i]的时候,相当于对指针a进行解引用相当于*(a + i)
所以a中存放的是数组开始的地址,因此可以通过指针进行赋值访问,如:
int *p = a;
对于二维数组
int b[3][4]
该数组有3行4列,既然b[3][4]是一个解引用的结果,那么b[i]里存储的是指第i+1个长度为4的数组的地址,b就是指向指针的指针,即二维数组开始的地址
但是二维数组不能通过二维指针进行索引,如:
int **p = b;
的做法是错误的,因为没有表示指向的是一个数组,缺少了列数,不能进行索引
对于,指向二维数组第n行地址的指针,可以用如下表示法
int (*p)[4] = &b[n-1];
其中n为行数,这样p就指向了第n个以为数组的开始元素
因为a[n]是地址b解引用的结果,所以
int (*p)[4] = &b[0];
和
int (*p)[4] = b;
是等价的
同理下面的代码
int b[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
int (*p)[4] = b
p++;
cout<<p[0][0];
p首先指向了第1行,之后p++,因为p是二维数组,所以自增后指向的是&a[1],因此p[0][0]得到的结果是第二行第一列的元素5
指针操作符优先级问题
指针*操作符的优先级小于于自增++操作符,但都小于()操作符,因此
(*p)++是得到p的解引用的值,之后对解引用的值++
*(p++)和*p++等价,都是先把指针p++后再对递增前的地址解引用,因为p++先返回原地址,之后在对地址++,因此解引用的是递增前的地址
()操作符只影响运算顺序,不影响返回结果的顺序
数组中的[]操作符优先级大于指针*操作符
int *p[4]声明的是p是一个长度为4的数组,数组中的每一个元素都是一个指向int的指针,即p[0]到p[3]都是指针
int (*p)[4]声明的是p是一个指针,指向的是列为4的int型二维数组
数组动态建立的时候,对于一维数组
int *a = new int[4];
表明动态创建一个长度为4的int型数组,删除的时候用
delete [] a;
对于二维数组a[3][4]的动态建立,如:
int **a = new int *[3];
for(int i = 0;i < 3;i++)
{
a[i] = new int[4];
}
首先动态创建一个长度为3,每个元素都是指向int的指针,之后为每个数组动态建立一个长度为4的存储int值的数组
对于二维数组的删除
首先要删除每个int指针数组的元素
for(int i = 0;i < 3;i++)
{
delete [] a[i];
}
之后长度为3的指针数组
delete [] a;
如果有如下代码:
typedef string *s_string;
const s_string a;
a不是一个指向cons string的指针,而是一个const的string指针,即等同于
string *const a;
因为const修饰的是s_string,所以s_string是一个const,即一个const指针
指向函数的指针
如果一个函数是这样的:
void coutFunc(string a)
{
cout<<a<<endl;
}
打印出一个传入函数的string型变量a
如果用一个指针指向countFunc函数,则称为指向函数的指针,如:
void (*p)(string) = countFunc;
这里p是一个指向以string为参数,返回void值的函数countFunc的指向函数的指针,这里函数名作为地址,这种定义等同于
void (*p)(string) = &countFunc;
通过函数指针调用函数,可以通过
p(“abcd”);
或
(*p)(“abcd”);执行
即调用了countFunc函数
当指向函数的指针作为函数参数传递时,可以这样声明:
void func_a(void (*)(string));
即函数func_a的参数是一个以string为参数返回值为void的指向函数的指针,func_a返回值是void,定义实现如下:
void func_a(void (*p)(string))
{
p(“abc”);
}
同理,以指向函数的指针作为返回值的函数可以定义为
void (*func_b())(string)
{
void (*p)(string) = countFunc;
return p;
}
func_b的参数为空,返回一个指向参数为string返回值为void的函数的指针
对于指向函数的指针,用typedef来声明会容易理解些
typedef void(*p_func)(string);
p_func p = countFunc;
这里,p_func是一个指向参数为string返回值为void的函数的指针类型,可以定义一个指向函数的指针p,并赋值为函数countFunc
同样,可以定义函数
p_func test_func()
{
void (*p)(string) = countFunc;
return p;
}
test_func函数参数是空,返回一个指向参数为string返回值为void的函数的指针
- C语言指针心得(一)
- 学习C指针的心得随笔
- c和指针 前三章的阅读心得
- 指针心得
- 心得 指针
- 黑马程序员-c语言学习之指针的心得
- C语言「指针、链表」入门心得
- c语言中关于数组与指针的一点心得
- .c心得
- 指针的使用心得
- C++指针心得
- 心得分享:C类成员指针默认不为NULL的原因
- <<C和指针>>第1章之编程练习心得20140702
- <<C和指针>>第1章之编程练习心得20140703
- <<C和指针>>第1章之编程练习心得20140704
- <<C和指针>>第1章之编程练习心得20140705
- <<C和指针>>第2章之编程练习心得20140709
- 近来对指针基础、一二维数组的心得和linux下c语言的编程
- LCD帧缓存设备驱动
- hdu 1333 Smith Numbers
- LCD驱动的实现
- bash shell脚本之查看当前日期以及登陆用户
- 架构师:要成为百科全书式的智者
- C++指针心得
- bash shell脚本之查看系统环境变量
- TFT显示屏参数设置
- 数据结构第一章思维导图
- bash shell脚本之成员变量
- linux帧缓冲设备驱动的上层建筑Fbmem.c文件
- 【SoftKeyboard研究系列】自己动手做最简单的SoftKeyboard
- wordpress插入bilibili视频
- poj-1852