Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 指针算法使用一个过去的数组元素,然后取消引用,结果会是什么?_C_Arrays_Clion_Pointer Arithmetic - Fatal编程技术网

C 指针算法使用一个过去的数组元素,然后取消引用,结果会是什么?

C 指针算法使用一个过去的数组元素,然后取消引用,结果会是什么?,c,arrays,clion,pointer-arithmetic,C,Arrays,Clion,Pointer Arithmetic,如果我取消引用一个数组并添加5个超出数组中可用元素的元素,那么打印的值是多少?我在IDE中返回32767,这没有多大意义 #include <stdio.h> int main(void) { int i; int meatBalls[5] = {1, 2, 3, 4, 5}; printf("%12s %18s %6s\n", "Element", "Address", "Value"); for(i=0; i < 5; i++) {

如果我取消引用一个数组并添加5个超出数组中可用元素的元素,那么打印的值是多少?我在IDE中返回32767,这没有多大意义

#include <stdio.h>

int main(void)
{

    int i;
    int meatBalls[5] = {1, 2, 3, 4, 5};

    printf("%12s %18s %6s\n", "Element", "Address", "Value");

    for(i=0; i < 5; i++) {
        printf("meatBalls[%d] \t %p \t %d \n", i, &meatBalls[i], meatBalls[i]);
    }

    printf("\nmeatBalls \t\t %p \n", meatBalls); /*already a pointer*/

    /*dereference meatBalls and it will update to the value e.g. 1*/

    printf("\n*meatBalls \t\t %d \n", *meatBalls); /*dereference with asterisk*/

    printf("\n*(meatBalls+2) \t\t %d \n", *(meatBalls+2)); /*dereference but also go through the array from 0 + 2*/

    printf("\n*(meatBalls+4) \t\t %d \n", *(meatBalls+4));

    printf("\n*(meatBalls+5) \t\t %d \n", *(meatBalls+5)); /*what is the number that this returns?*/

    return 0;
}
TL;博士:不知道,也不能说

详细说明,在您的代码中

  printf("\n*(meatBalls+5) \t\t %d \n", *(meatBalls+5));
当您尝试访问超出限制的内存时,会导致

请注意重点是访问。本例中的指针算法定义良好(超过最后一个元素),试图访问导致UB的内容

引用第§6.5.6章第11节(重点)

[…]如果表达式
p
指向最后一个 数组对象的元素,表达式
(P)+1
指向 数组对象,如果表达式
Q
指向数组对象的最后一个元素的后面, 表达式
(Q)-1
指向数组对象的最后一个元素如果指针和 操作数和结果指向同一数组对象的元素,或超过最后一个的元素 数组对象的元素,求值时不应产生溢出否则 行为是未定义的如果结果指向数组对象的最后一个元素后一个元素,则 不得用作已计算的一元
*
运算符的操作数。

也就是说,
%p
希望它的参数是一个
void*
,并且由于
printf()
是一个可变函数,因此不会发生默认参数提升。因此,您需要将所有参数强制转换为
%p
(void*)
TL;博士:不知道,也不能说

详细说明,在您的代码中

  printf("\n*(meatBalls+5) \t\t %d \n", *(meatBalls+5));
当您尝试访问超出限制的内存时,会导致

请注意重点是访问。本例中的指针算法定义良好(超过最后一个元素),试图访问导致UB的内容

引用第§6.5.6章第11节(重点)

[…]如果表达式
p
指向最后一个 数组对象的元素,表达式
(P)+1
指向 数组对象,如果表达式
Q
指向数组对象的最后一个元素的后面, 表达式
(Q)-1
指向数组对象的最后一个元素如果指针和 操作数和结果指向同一数组对象的元素,或超过最后一个的元素 数组对象的元素,求值时不应产生溢出否则 行为是未定义的如果结果指向数组对象的最后一个元素后一个元素,则 不得用作已计算的一元
*
运算符的操作数。


也就是说,
%p
希望它的参数是一个
void*
,并且由于
printf()
是一个可变函数,因此不会发生默认参数提升。因此,您需要将所有参数强制转换为
%p
(void*)
访问数组边界以外的元素是未定义的行为;因此,您可以获得任何值,但您的程序也可能崩溃。以下是如何定义未定义的行为:

3.4.3未定义的行为

使用不可移植或错误的程序结构或错误的数据时的行为 国际标准没有规定任何要求

注:可能未定义 行为范围从完全忽略情况到 不可预测的结果,翻译或编程过程中的行为 以环境特有的文件化方式执行 (无论是否发出诊断信息),终止 翻译或执行(通过发布诊断文件) 信息)

这就是标准定义您的访问是未定义的行为的地方:

J.2未定义的行为

1在以下情况下,该行为未定义:

  • 数组下标超出范围,即使对象明显不在范围内 可通过给定的下标访问(如左值表达式中的下标 a[7]鉴于声明[a[4][5])

访问数组边界以外的元素是未定义的行为;因此,您可以获得任何值,但您的程序也可能崩溃。以下是如何定义未定义的行为:

3.4.3未定义的行为

使用不可移植或错误的程序结构或错误的数据时的行为 国际标准没有规定任何要求

注:可能未定义 行为范围从完全忽略情况到 不可预测的结果,翻译或编程过程中的行为 以环境特有的文件化方式执行 (无论是否发出诊断信息),终止 翻译或执行(通过发布诊断文件) 信息)

这就是标准定义您的访问是未定义的行为的地方:

J.2未定义的行为

1在以下情况下,该行为未定义:

  • 数组下标超出范围,即使对象明显不在范围内 可通过给定的下标访问(如左值表达式中的下标 a[7]鉴于声明[a[4][5])

它正在打印当时内存中发生的任何事情。如果你在做一些奇怪的事情,为什么会对奇怪的结果感到惊讶?@GradyPlayer虽然我们大多数人都会明白这一点,但我们中的一些人可能不会(相信我,曾经在那里,看到过),最好不要发表这些评论。希望你得到这个角色。:)嗯……这肯定是未定义的行为。它可能的复制品是打印出在那里发生的任何东西