首页 > 试题广场 >

下面程序的运行结果是()。 #include i

[单选题]
在gcc编译器中,下面程序的运行结果是()
#include<stdio.h>
int main(void)
{
    int x[5] = {2,4,6,8,10},*p;
    int (*pp)[5];
    p=x;
    pp=&x;
    printf ("%d\n",*(p++));
    printf ("%d\n",*pp);
}

  • 4  4
  • 2  4
  • 2  随机值
  • 4  6
第一个输出是数组中x[0]的值2    因为后置++,返回当前常量值,十进制打印x[0]的值,指针再自增。

第二个输出是随机值
第4行代码   int(*pp)[5] ;  变量pp的类型是数组指针 —> int(*)[]
数组指针:本质是指针,指针存储的是 整个数组的地址,整个数组的地址表示为(&数组名)—>(&x)。
数组名(x)  单独使用表示的数组首元素的地址即(&数组名[0])—>(&x[0])。
&数组名(&x)表示的是整个数组的首地址。
&x是整个数组的首地址,x 是数组首元素的首地址,其值相同但意义不同

第6行代码:pp=&x;    
这句代码“=”号两边的数据类型一致。左边的类型是指向整个数组的指针,右边的数据类型是整个数组的地址。
但是解引用就会得到一个随机值
第8行代码: printf ("%d\n",*pp);  这句代码相当与 printf("%d\n", *(&x)); 我用的是vs2013,在vs2013编译器上输出的是以10进制打印的整个数组地址。
但由于每次运行代码时,数组在栈上创建的起始地址不同,所以以10进制打印出来的值也是不同的,所以题目上面答案就是随机值
其实这个光看输出结果是看不出来pp数组指针中存储到底的是什么,可以把程序一步一调试,在监视窗口输入*pp时就能看到pp数组指针里面存储的内容,vs2013编译环境下,看到的pp数组指针存储的是整个数组。
想要单独用printf打印整个数组是不行的。
可以下来尝试调试一下。在这里我推荐一本书《c语言深度解剖》里面指针、数组章节有对这部分知识的解读,在我的博客上面也有我对这本书指针、数组章节的小结,欢迎大家访问。https://my.csdn.net/?c=9bf09bc5d3e6e61da8ffb9cd411e8232
以后上面也会更新我在学习阶段的遇到问题,读一些书的小结,还有牛客网刷到题的总结,还有日常学习生活中遇到的一些好玩的代码。
以上是我以现有知识所做出的回答,写的也比较仓促,如有错误请指出。
发表于 2018-06-12 00:53:01 回复(4)
第一个打印的是指针指向x数组的值,也就是x[0],然后指针变量自加1;
第二个打印的是x数组的首地址(pp=&x),但每次分配都不相同,所以随机。
发表于 2018-08-08 11:34:48 回复(4)
第一个输出考察的是后缀++的运算细节,先返回当前值(该返回值是个常量),再自加,不多赘述。
额外提醒一点,由于C++的后缀运算符优先级高于单目运算符*,所以在C++环境下,不加圆括号也不会改变其运算顺序。

第二个输出为x的存放地址,在题目没有指定起始地址的条件下,x的存放地址自然是一个随机值。
楼上有小伙伴说编译报错,看错误信息应该是题目有问题(估计之前题目定义的是int** pp),现在这个版本二者的类型都是int (*)[5],不会引起编译错误。
编辑于 2018-06-05 23:02:46 回复(0)
int x[5] = {2,4,6,8,10}:
申请五个空间存数组的数据2,4,6,8,10
5个数据对应的地址假设是ad(2),ad(4),ad(6)...
为指针变量x申请空间ad(x)
把指针x指向ad(2),即变量x存了2的地址,或者说地址为ad(x)的空间中存了ad(2)。

*p
为指针变量p申请地址ad(p),由于未赋值,现在ad(p)中是系统残留数据,是未知的随机值

int (*pp)[5]
为数组申请5个空间以便后续存数据,地址假设为ad[?0],ad[?1], ad[?2],ad[?3], ad[?4], 这五个空间以后要存的数据类型为指针型,由于还没有赋值,里面存的还是系统以前使用过程中遗留的数字,对于这个程序来说就是随机的值。
为指针变量pp申请空间
指针pp指向ad[?0]

p=x:
把变量p的值改为x的值,p原来是系统残留数据,现在把内容替换为ad(2)。即在ad(p)这个空间里面放了一个地址ad(2)

pp=&x;
把变量pp的值改为x变量的地址,即ad[?0]变为ad(x)

printf("%d\n",*(p++)):
先打印p所指地址中存放的数据,即ad(2)中存放的数据2
把p的值+1,由于数据在存数据时,数据的存放是连续的地址,所以p存的变成了ad(2)后面一个值的地址,即ad(4)

printf("%d\n",*pp);
打印pp变量所存地址中存放的数据,即x中存的东西,即ad(2)

最后的打印结果应该是:2,一个地址。
如2, 0x7FFF74883640
此时p的值为0x7FFF74883644,int占4个字节
注 0x7FFF74883640指的是2这个数据所占空间的起始字节,所对应的是0x7FFF74883640-0x7FFF74883643这四个字节。

做指针的题,个人觉得技巧是把申请地址和存放变量作为两个动作来思考,经常容易忽略的是一个题中看似就几个变量,其实内存中开辟了很多地址。由于指针本身是存地址的,所以理清楚地址信息是必要的。

编辑于 2019-10-22 14:10:31 回复(1)
pp = &x 其实可以理解为x是数组首元素的地址,&x的意思就是取数组首元素地址的地址。
那么*(pp)就是指取首元素的地址,那么这个地址是不确定的,故为随机值。可以看到编译器也在提示我们此时的*pp的类型为int*

(本人所用编译器为Clang,若有与gcc编译器不同之处,请批评指正)
若*(*pp)就可以理解为取首元素,此时就确定为2了。此时我们可以看到编译器就没有⚠️了

发表于 2023-03-25 14:11:03 回复(1)

超容易理解:我总结一下这一题出现的问题:
1、第一种理解方式。首先x是数组名,也就是我们熟知的数组的首元素地址 ,即&x[0];
其次得知道&x;代表的是整个数组的地址
pp操作时,相当于 *(&x),该表达式的结果自然就是x。而我说过,x是什么,数组名,首元素的地址。所以,对一个地址以整型格式打印,就是将地址转为整数。而每次分配一个数组,它的首元素地址就是不一样的。所以是随机值。
2、第二种理解方式。首先得知道什么是行地址和列地址。对于一个数组而言,第一个元素的地址既是整个数组的一行的地址标识,也是每个元素第一个列的地址标识。所以正确理解
pp的含义是,pp是行地址,而*pp得到列地址,也就是第一列的地址(数组首元素的地址)。
注意:这里得知道行地址如何转为列地址,也就是*行地址 == 列地址。

发表于 2022-11-26 21:18:18 回复(0)
#include<stdio.h>
int main(void)
{
    int x[5] = {2,4,6,8,10},*p;  int (*pp)[5];
    p=x;
    pp=x;
    printf ("%p\n",p);
    printf ("%p\n",pp);
    printf ("%d\n",*(p++));
    printf ("%d\n",*pp);
}
结果如下:
0x7fff5150e210
0x7fff5150e210
2
1364255248
实际上地址相同,但是出于如何解释地址上的数据,*pp的结果为大小为5的int数组。

发表于 2018-06-11 08:56:25 回复(5)
pp=&x;
则*pp=x;
print("%d",*pp)即print("%d",x);是数组首地址,为随机数
发表于 2020-08-29 12:09:31 回复(0)
数组作为参数传入 退化成指针
发表于 2026-03-12 14:38:53 回复(0)
/*
    p=x:指针p指向x的首元素地址
    pp=&x:pp是指向一个包含5个int 元素的数组的指针,&x表示一个int x[5]的数组的地址
*/
int func_4()
{
    int x[5] = {2,4,6,8,10},*p;
    int (*pp)[5];
    p=x;  
    pp=&x;
    printf ("%d\n",*(p++));  //先取值再相加
    printf ("%d\n",*pp);     //*pp表示解引用pp,pp是一个指向数组x的地址,所以是一个随机值 (*pp)[0]才能取出数组值
}
发表于 2025-02-08 09:24:21 回复(0)
首先第一个是后置++,先使用在加加,所以打印的是数组首元素2,第二个是类型不匹配
编辑于 2024-03-19 18:10:03 回复(0)
这里的*p++ 和*(p++)居然是一样的,我还以为括号里面的会完成自增,见识了。。。。。。。。。

发表于 2023-12-15 15:49:59 回复(0)
打印*pp是地址,打印*(*pp)才是首元素值
发表于 2023-11-10 23:29:17 回复(0)
数组名作为地址代表的是数组首元素的地址
对数组取地址代表的是数组的首地址

*(p++),虽然是先算小括号里的  但是++在后置影响不大  先取值->为2,在++
    
int (*pp)[5],表示为一个数组指针,pp=&x,此时++就会影响pp的值,使其跳过一行 但是数组x
只有一行  所以*pp的值是未知的

发表于 2023-10-07 22:02:01 回复(0)
两眼发懵😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮
发表于 2023-09-20 11:45:35 回复(0)
看了上面的大佬们,我还要好好学习
发表于 2023-09-04 11:03:34 回复(0)
*(p++)因为是后置++,先使用,也就是说先*p在p++;
pp是地址,*pp也是地址,所以会出来一个随机值。
发表于 2023-01-20 13:58:21 回复(0)
pp是指向数组的指针,*pp指向数组,此时*pp相当于数组名,可以当首地址用
发表于 2022-02-26 23:33:20 回复(0)
数组指针:

&x是整个数组的首地址,x 是数组首元素的首地址,其值相同但意义不同
第一个打印的是指针指向x数组的值,也就是x[0],然后指针变量自加1;
第二个打印的是x数组的首地址(pp=&x),但每次分配都不相同,所以随机。
对于非数组变量X=3,&X指向X的地址;而对于数组X={1 2 3},X指向数组X={1 2 3}的地址
发表于 2020-02-21 15:26:38 回复(0)
2
发表于 2019-02-28 08:00:40 回复(0)