指向整形数组的指针和指向字符串数组的指针

2017-02-20

版权声明:本文为作者原创文章,可以随意转载,但必须在明确位置表明出处!!!

今天总结一下指针的操作,对于刚接触到编程的同学来说,指针应该是比较难掌握,不易操作的,而且出错了往往不知道问题出在哪里,今天主要讲一下指针在内存中是如何存储的。我们将从指向整形的指针,指向字符串的指针,指针整形数组的指针,指向字符串数组的指针4个例子并结合输出结果谈一谈它们分别在内存的存储方式。最最重要的一点是我们只需要把指针看作一个变量就是了,它和普通变量位移的区别便是指针变量存储的是地址。

指向整形的指针

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
using namespace std;
int main()
{
int a = 100;
int *p = &a;
cout<<"&a = "<<&a<<endl;
cout<<"p = "<< p<<endl;
cout<<"&p = "<<&p<<endl;
}

运行结果:

从运行结果我们可以看到a的地址是0x28feac,指针p指向的地址同样是0x28feac,所以再对p做操作时就得到的是地址0x28feac存放的值100,也就是说当我们做p=200的时候a的值同样也变成了200,指针p的地址是0x28fea8,从这里我们也可以看出在一个指针所暂用内存大小是4个字节,0x28feac-0x28fea8 = 0x04

指向字符串的指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
using namespace std;
int main()
{
char ch[] = "hello world";
char *p = ch;
cout<<"&p = "<<&p<<endl;
cout<<"p = " << p<<endl;
cout<<"p = " <<(void*)p<<endl;
for(int nLoop = 0; nLoop < sizeof(ch); nLoop ++)
{
cout<<"&ch["<<nLoop<<"] = "<<(void*)&ch[nLoop]<<endl;
}
return 0;
}

运行结果:

我们可以看到这里的指针p指向的是字符串ch的首地址,当cout的时候若指针指向的是字符串则只会遇到\0才会结束,所以这里的cout<<p 会输出整个字符串

指向整形数组的指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
using namespace std;
int main()
{
int a[] = {1,2,3,4,5};
int *p = a;
int **q = &p;
cout << "a = "<<a << endl;//a的首地址
cout << "p = "<<p << endl;//指针p指向的地址
cout << "&p = "<<&p<< endl;//指针p在内存的地址
cout << "q = " << q <<endl;
cout<< "&q = " <<&q<<endl;//指针q在内存的地址
for(int nLoop = 0; nLoop < 5; nLoop ++)
{
cout<<"&a["<<nLoop<<"] = "<<&a[nLoop]<<endl;
}
return 0;
}

运行结果:

我们用一个图来表示,会更直观一些。

从运行结果我们可以看到指针p指向的是a[0]的地址,也就是说指针p存放的是a[0]的地址0x28fe98,指针p在内存中的地址是0x28fe94,指针q指向的地址正好是指针p在内存中的地址,也就是说指针q存放的是p的地址0x28fe94,而q在内存中的地址是0x28fe90通过上图就跟直观的明白,q等价于p,q取的的是0x28fe94地址存放的值,正好是0x28fe98,而q等价于a[0] 因为q相当于p,通过这个图就能应对q++等操作,比如我们做一个q++操作然后cout<<q<<endl; 这个时候输出的肯定是1,因为做*q++之后q所指向的地址是0x28fe98对应的正好是a[0]的地址,再解索引就得到1了。

指向字符串数组的指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
using namespace std;
int main()
{
char *ch[] = {"gray","red","blue"};
char **p = ch;
for(int index = 0; index < 3; index ++)
{
for(int nLoop = 0; nLoop < strlen(ch[index]) + 1; nLoop ++)
{
cout<< ch[index][nLoop] << "\t" << (void*)&ch[index][nLoop]<<endl;
}
cout << endl;
}
for(int nLoop = 0; nLoop < 3; nLoop ++)
{
cout << "a[" << nLoop << "] =" << (void*)ch[nLoop]<<endl;
cout << "&a["<< nLoop << "] = "<< &ch[nLoop]<<endl;
}
cout << "p = " << p << endl;//指针P所指向的地址
cout << "&p = " << &p << endl;//指针p在内存中所在地址
return 0;
}

运行结果:

内存结构图:

p等价于ch[0],当cout<<p会大于出gray字符串,这和上面的指向字符串的指针是一个道理,**p等价于ch[0][0];当我们执行p++;p指向的地址加1,p指向的地址是0x28fe98,p加1过后的地址为0x28fe9c,所以这个时候p就指向了ch[1]了。


推荐我的微信公众号:爱做饭的老谢


上一篇:CentOS6.5下Oracle 11g安装
下一篇:TCP协议总结