C - 这段代码如何/为什么"起作用"?

Gaz*_*zob 3 c arrays pointers

我写了这段代码并且"它有效" - 但是怎么样?

我没有在我的main函数中声明一个数组; 我只是在带有指针的过程中添加了一个标准整数.例如,它将通过更改循环运行的次数来扫描2或20个整数的数组.

#include <stdio.h>

void test(int *v, int n) {
    int i;
    for (i = 0; i < n; i++) {
        printf("[%d]: ", i);
        scanf("%d", &v[i]); 
    }
    printf("\n\n#############\n\n");
    for (i = 0; i < n; i++) {
        printf("[%d]: %d\n", i, v[i]);
    }
}

int main(void) {
    int array;
    int t = 10; 
    test(&array, t);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我真的不知道我写的是什么,直到我意识到它在起作用.我试图搜索"指针数组"或一般指针,但找不到上面这个例子的任何具体答案.我希望我知道更多要找的东西.

pax*_*blo 11

此代码适用于"work"一词的某些值:-)

您的test函数需要整数的地址和整数计数.主要功能完全给出了那些东西,&array并且t.所以它编译得很好.

不过,即时你尝试去引用v[1],甚至计算出的地址v[N]在那里N既不是零也不是一个,全盘皆输.你已经给出了一个恰好是一个元素的数组,并且它是未定义的行为来执行上述任何一个

所以,当你的代码可能似乎工作(一),那将是对另一种实现方式,在另一台机器完全由事故,并且不保证,或在月亮的不同阶段,甚至.

当然,您可以通过确保不要尝试在数组末尾之外执行任何操作来解决此问题.有类似的东西:

int array;
test(&array, 1);
Run Code Online (Sandbox Code Playgroud)

要么:

int array[42];
test(array, sizeof(array) / sizeof(*array));
Run Code Online (Sandbox Code Playgroud)

这将确保传递给函数的计数值与所述数组的大小相匹配.


对于我们中间的语言律师,C11 Appendix J.2将这些项目列为未定义的行为(第一个包括计算v[N]哪里N既不是零也不是一个,第二个包括取消引用v[1]):

将指针加到或减去数组对象和整数类型会产生一个不指向或超出同一数组对象的结果(6.5.6).

将指针加到或减去数组对象和整数类型会产生一个指向数组对象之外的结果,并用作被计算的一元*运算符的操作数(6.5.6).

引用6.5.6 /8状态:

如果指针操作数和结果都指向同一个数组对象的元素,或者指向数组对象的最后一个元素,则评估不应产生溢出; 否则,行为未定义.


(a)未定义的行为有时"有效"的可能性实际上是其最阴险的​​特征.如果它从未奏效,那就更好了.

这就是为什么我有一个专利申请中的专利(b)在连接电极到你的私人部分的设备上,只要编译器检测到所述行为的使用就会激活.

它大大提高了我们商店提供的代码质量.现在,如果我们能够留住我们的员工,那将是非常好的:-)


(b)不是真的,我似乎记得有一个实际的法律问题,声称申请专利的情况不真实,所以我需要澄清这只是幽默价值.

  • 喜欢"一些"这个词的价值"工作"`如果有鼓掌就这样我会给你许多鼓掌! (2认同)