C++ 指针基础理解
2015-11-08 12:23
309 查看
抽象看存储编译
如:我们定义 int a= 10,则a需要存储在计算机里面,我们把其看成2段值=(内存地址,值)。 假如 a 的内存地址为 001EFECO,即在计算机中a被存为 =(内存地址,值)=(001EFECO,10)。 则计算机编译时: 获得a的内存地址:001EFECO。 获得内存地址所对应的值:10 根据初始我们的定义 int,计算机得知 当前地址所对应的值为 int型 (int的定义是为了告诉计算机,某个地址所对应的值为int型)。 即:计算机获得这个内存地址,找个这个内容,再根据 内容的定义,把内容显示出来。
指针定义:
简单地说,指针是存储内存地址的变量。用上面的流程来说:
计算机获得这个内存地址(指针的),找个这个内容(指针的),再根据 内容的定义(发现还是个内存地址),没办法,计算机只好再来1次, 计算机获得这个内存地址,找个这个内容,再根据 内容的定义,把内容显示出来把内容显示出来。
如:
int ptr = &a; &a是获得a的内存地址 = 0023FEF4。 仅仅是告诉计算机,ptr是个指针(它的内存地址所对应的值还是个内存地址)。
假如 ptr初始为 (001EFOOO,NULL);
*ptr = &a的语义为: 将 &a赋值给 ptr,即ptr =(001EFOOO,0023FEF4);
举例说明
列1 简单赋值:#include <iostream> using namespace std; int main() { int a=12; int *ptr = &a; cout << "ptr at:"<< ptr << endl ; cout << "ptr ="<< *ptr << endl ; return 0; }
输出结果:
*ptr输出时,先获得ptr所对应的地址,即:0023FEF4。
再根据内存 0023FEF4的定义(int a=12),获得0023FEF4 代表int型,值为12. 即:
ptr=(001EFOOO,0023FEF4),而在内存0023FEF4处有: (0023FEF4,12)
列2 中间改变赋值
在列1的基础上,再赋值1次,如:
#include <iostream> using namespace std; int main() { int a=12; int *ptr = &a; cout << "a ="<< a<< endl ; *ptr =13;//中途改变赋值 cout << "ptr at:"<< ptr << endl ; cout << "ptr ="<< *ptr << endl ; cout << "a ="<< a<< endl ; return 0; }
输出结果:
然后我们发现:
初始的时候 a=12.但是中间对ptr赋值后,a = 13了。
因为执行 *ptr =13 这句话时,流程为;
获得: ptr=(001EFOOO,0014F9F8),注:每次执行a值的内存地址是变化的。
而a = (0014F9F8,12)
执行:*ptr =13 ,即 0014F9F8 =13. 即执行后,是把0014F9F8 进行了变化。故而a也发生了变化。
若: 将 *ptr =13 替换成: ptr =13,得到结果:
e:\源码\hello\hello.cpp(9): error C2440: “=”: 无法从“int”转换为“int *”
这是因为:
指针的类型 和 指针所指向的类型是2码事情,注意区分,具体可参考博客:
http://www.cnblogs.com/ggjucheng/archive/2011/12/13/2286391.html
*和&复合运用
研究如下情况:**ptr (列3)
*&ptr(列4)
&*ptr(列4)
&&ptr(列5)
下面分别举例说:
**ptr的意思是,ptr是指向指针的指针,如: ptr = (001EFOOO,0014F9G9)。
则: 0014F9G9必须是一个指针的地址。
列3
#include <iostream> using namespace std; int main() { int a=12 ; int *ptr = &a; //int **pi = 30; //不能初始化,类型错误,因为30是int型。 //int **pi = ptr; //不能初始化,类型错误,因为ptr是指向int型的内存地址,而不是指针的地址。 int **pi = &ptr; // 成功,获得ptr的地址,而ptr是个指针 cout << "ptr at:"<< &ptr << endl ;//ptr本身的内存地址 cout << "ptr is:"<< ptr << endl ;//ptr本身的内存地址所指向的内存地址 cout << "ptr ="<< *ptr << endl ;//ptr本身的内存地址所指向的内存地址 所代表的值 cout << "pi at: "<< &pi << endl ;//pi本身的内存地址 cout << "pi is: "<< pi << endl ;/pi本身的内存地址所指向的内存地址 cout << "pi =: "<< *pi << endl ;//pi本身的内存地址所指向的内存地址 所代表的值(ptr指针本身的内存地址) cout << "pi =: "<< **pi << endl ;//实质是 ptr本身的内存地址所指向的内存地址 所代表的值 return 0; }
`
得到结果:
解释如下:
ptr = (0014FB78 , 0014F84) 而 (0014FB84 , 12).
0014FB78 代表ptr本身的内存地址,ptr本身是个指针。即指针本身的内存地址。根据ptr的定义,是指向int值的指针。
0014F84是ptr这个指针所指向的内存地址,通过*ptr = &a赋值过来的,也就是a的值 = (0014FB84 , 12)
pi = (0014FB6C, 0014FB78)
0014FB6C代表pi本身的内存地址,pi本身是个指向指针的指针[/b]。即指针本身的内存地址。
根据pi的定义 ,0014FB78必须是另外一个指针本身的内存地址,即 *pi后,得到 0014FB78。 而0014FB78是 ptr本身的内存地址。
故而 * pi = (0014FB78)= *ptr = a值 =12.
列4
#include
using namespace std;
int main()
{
int a=12 ;
int *ptr = &a;
cout << "ptr at:"<< &ptr << endl ; cout << "ptr is:"<< ptr << endl ; cout << "ptr ="<< *ptr << endl ; cout << "*&ptr ="<< *&ptr << endl ; cout << "&*ptr ="<< &*ptr << endl ; return 0;
}
输出结果:
解释如下:
ptr =(0025F7E8,0025F7F4),a = (0025F7F4,12)
则:
&ptr = (0025F7E8) = ptr的本身内存地址所指向的值 = 0025F7F4
&*ptr = &(12) = 12这个值所存储的地址 = &a = 0025F7F4
列5
继续用上面的结果,分析 &&ptr
&&ptr = & (0025F7E8) ,而值 0025F7E8 所存储的地址 =(X,0025F7E8), X在哪里?也就是天知道…..
数组
大爷的,写累了,后面再说吧。。。。相关文章推荐
- 【C语言】 递归求非负数的每一位之和
- 【C语言】 实现strstr
- 第一章 初识C语言
- 【C语言】 字符串逆序
- 深入理解C++浮点数(float、double)类型数据比较、相等判断
- C语言注释框框
- [C/C++]2014年7月华为校招机试真题(一)
- leetcode笔记:Minimum Path Sum
- 记录C语言入门学习·四
- 今日学习札记——C++Primer补充2(11.8)
- C++程序进入main函数之前,退出main函数之后会做些什么?
- 设计模式C++实现——工厂模式
- C++ MFC多文档嵌入python
- C++继承、虚继承、虚函数类的大小问题
- c++类成员函数后边加const
- c++和c混合编程
- C++ code Summary --- 2015.11.8
- C/C++语法高阶:const的应用,const在类中的体现
- C++: 拷贝管理
- [并发并行]_[C/C++]_[使用线程本地存储Thread Local Storage(TLS)调用复制文件接口的案例]