您的位置:首页 > 其它

C指针与数组详解 -- 一道数组与指针的问题

2013-04-11 20:11 302 查看
下面一段代码的运行结果是什么?

#include <iostream>
using namespace std;

int main(int argc, char** argv)
{
int a[5] = {1,2,3,4,5};
int* ptr = (int*)(&a + 1);
cout<<*(a+1)<<","<<*(ptr-1)<<endl;
return 0;
}

答对了吗?运行结果为: 2,5。  为什么呢?

因为题目涉及到指针的加减运算,这就涉及到了指&a的类型和&a指向对象的类型等问题。

注意到了吗对整形指针ptr赋值的时候,我们用了类型强制转换,可见&a的类型不是int*,那究竟是什么类型呢?

最简单的方法就是去掉强制类型转换(int*),然后编译,编译器就会提示如下信息:

error: cannot convert 'int (*)[5]' to 'int*' in initialization|

另一种方法就是C++关键字typeid,代码如下:

#include <typeinfo>
#include <iostream>
using namespace std;

int main(int argc, char** argv)
{
int a[5] = {1,2,3,4,5};
const type_info &t_info = typeid(&a);
cout<<t_info.name()<<endl;
return 0;
}

运行结果为:PA5_i

原来&a的类型是是int (*)[5](PA5_i)!那么这下答案就很明了了,则根据C语言规定:如果指针变量p指向数组中的一个元素,则p+1指向同一数组中的下一个元素,即p+sizeof(a)。&a为指向数组的指针,其中每个元素为由5个整形组成的数组,因而&a+1=(&a+sizeof(int[5]))= &a[6],是指向下一个数组的指针,即数组对象为一个整体。可以发现其实&a+1其实刚刚超出了a的范围,但将p强制类型转换为int*后,此时p又为指向整形的指针,因而 p-1 = p - sizeof(int)= &a[5],因而打印结果为2,5

其实,用typedef为数组定义别名,结果就很容易理解了,因为人们习惯将数组看成是一个连续的对象列表,而不会将其看为是一个数据类型。

应牢记这一点,数组也是一个数据类型。

#include <typeinfo>
#include <iostream>
using namespace std;
typedef int arr[5];
int main(int argc, char** argv)
{
arr a = {1,2,3,4,5};
cout<<typeid(a).name()<<endl;
cout<<typeid(&a).name()<<endl;
int* ptr = (int*)(&a + 1);
cout<<*(a+1)<<","<<*(ptr-1)<<endl;
return 0;
}

ps:各种数组的数据类型:

int a[1]:int[1]

int a[1][1]: int(*)[1]

int a[1][1][1]:int(*)[1][1]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: