现在的位置: 首页 > 综合 > 正文

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

2013年01月19日 ⁄ 综合 ⁄ 共 1262字 ⁄ 字号 评论关闭

下面一段代码的运行结果是什么?

#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;
}

答对了吗?运行结果为: 25。  为什么呢?

因为题目涉及到指针的加减运算,这就涉及到了指&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+sizeofa)。&a为指向数组的指针,其中每个元素为由5个整形组成的数组,因而&a+1=&a+sizeofint[5]))= &a[6],是指向下一个数组的指针,即数组对象为一个整体。可以发现其实&a+1其实刚刚超出了a的范围,但将p强制类型转换为int*后,此时p又为指向整形的指针,因而 p-1 = p - sizeofint= &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]

抱歉!评论已关闭.