gpt4 book ai didi

c - C 中的垃圾值

转载 作者:行者123 更新时间:2023-11-30 20:08:17 25 4
gpt4 key购买 nike

我原以为第一个 printf() 语句会出现垃圾值,但我得到了地址。为什么?

#include<stdio.h>
int main()
{
int (*p)[10];
int a[10]={1,2,3,4,5,6,7,8,9,0};
p=a+10;
printf("%d\n",*(p));
printf("%u",(p));
}

最佳答案

首先,此声明

p=a+10;

无效。

赋值左侧的类型为 int( * )[10] 而赋值右侧的类型为 int * 并且没有隐式从一种类型到另一种类型的转换。

你必须写

p = ( int( * )[10] )( a + 10 );

其次是printf的这些调用

printf("%d\n",*(p));
printf("%u",(p));

具有未定义的行为,因为使用了无效的转换说明符 du 以及指针类型的参数,因为 *pp 都是指针。

因此,一个有效的程序可以如下所示

#include <stdio.h>

int main(void)
{
int (*p)[10];
int a[10]={1,2,3,4,5,6,7,8,9,0};

p = ( int( * )[10] )( a + 10 );

printf("%p\n",( void * )*p );
printf("%p\n", (void *)p );

return 0;
}

指针可以指向对象(或数组)最后一个元素后面的内存。

所以在这句话之后

p = ( int( * )[10] )( a+10 );

指针p指向一个想象的二维数组的第一个元素,其中的元素又是int[10]类型的一维数组,并且想象的二维数组的第一个元素对应于数组a

表达式*p也是一个指针。它的类型是 int * 因为表达式 *p 给出了 int[10] 类型的左值,并且在表达式中这个左值被隐式转换为指向其第一个元素的指针(在本例中的类型为 int)。

因此表达式 p*p 都指向相同的内存并具有相同的值。

程序输出证明了这一点

0x7ffcfd46ea48
0x7ffcfd46ea48

这两个指针 p*p 之间的区别在于它们可能指向的对象的类型。

考虑以下演示程序

#include <stdio.h>

int main(void)
{
int (*p)[10];
int a[10]={1,2,3,4,5,6,7,8,9,0};

p = ( int( * )[10] )( a+10 );

printf("%zu\n",sizeof( *p ) );
printf("%zu\n",sizeof( **p ) );

return 0;
}

它的输出是

40
4

如果你这样写,你可能会得到未定义的行为

printf( "%d\n", **p );

在本例中,表达式 **p 的类型为 int,并且可以访问数组 a 之外的内存。

关于c - C 中的垃圾值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57495601/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com