您的位置:首页 > 编程语言 > C语言/C++

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++-指针