我不能理解这些用C写的程序

我不能理解这些用C写的程序,c,pointers,C,Pointers,考虑以下代码: 1: #include <stdio.h> 2: int poin(int p[4]){ 3: printf("%u\n", p[0]); 4: printf("%u\n", p[1]); 5: printf("%u\n", p[2]); 6: printf("%u\n", p[3]); 7: 8: } 9: int main(){ 10: int *p[4],a=1,b=2,c=3,d=4; 11: 12: p[1]=&

考虑以下代码:

1: #include <stdio.h>
2: int poin(int p[4]){
3:    printf("%u\n", p[0]);
4:    printf("%u\n", p[1]);
5:    printf("%u\n", p[2]);
6:    printf("%u\n", p[3]);
7:
8: }
9: int main(){
10:     int *p[4],a=1,b=2,c=3,d=4;
11:
12:    p[1]=&b;
13:    p[2]=&c;
14:    p[3]=&d;
15:    p[0]=&a;
16:    poin(*p);
17:    return 0;
18:}
让我们修改第14行和第15行中的程序,看看修改后的代码:

1: #include <stdio.h>
2: int poin(int p[4]){
3: printf("%u\n", p[0]);
4: printf("%u\n", p[1]);
5: printf("%u\n", p[2]);
6: printf("%u\n", p[3]);
7:
8:}
9: int main(){
10: int *p[4],a=1,b=2,c=3,d=4;
11:
12:     p[1]=&b;
13:     p[2]=&c;
14:     p[3]=&a;
15:     p[0]=&d;
16:     poin(*p);
17:     return 0;
18:     }

请向我解释这些输出发生的原因和方式。我非常困惑,无法理解这些程序。这两个程序都有未定义的行为,因为编译器在内存中以何种顺序放置具有自动存储持续时间的变量尚不明确

但是,例如在第二个程序中获得的结果可以用以下方式解释

编译器似乎将变量a、b、c、d按顺序放置

d, c, b, a
没有内存缺口

因此,当int*类型的函数参数p指向变量d时,d之后的所有变量都被输出

考虑到这些陈述

12:     p[1]=&b;
13:     p[2]=&c;
14:     p[3]=&a;
甚至是冗余的,因为函数不访问p[1]、p[2]和p[3]

足够写了

15:     p[0]=&d;
该函数不处理数组。它处理指向变量d的指针

为了更清楚地说明这一点,只需按以下方式运行第二个程序

 poin(&d);
没有数组元素的初始化

一个正确的程序可能看起来像

1: #include <stdio.h>
2: int poin(int **p ){
3: printf("%u\n", *p[0]);
4: printf("%u\n", *p[1]);
5: printf("%u\n", *p[2]);
6: printf("%u\n", *p[3]);
7:
8:}
9: int main( void ){
10: int *p[4],a=1,b=2,c=3,d=4;
11:
12:     p[1]=&b;
13:     p[2]=&c;
14:     p[3]=&a;
15:     p[0]=&d;
16:     poin(p);
17:     return 0;
18:     }

请阅读printf及其格式说明符mini language的文档为什么编译器会放置d,c,b,a@Hash我已经根据程序输出做出了结论。然而,正如我所指出的,编译器如何放置具有自动存储持续时间的变量还没有明确说明。因此它是实现定义的。由于转换说明符和参数类型不匹配,使用%u打印一个整数也是未定义的行为。@DavidBowling如果有符号整数值可以适合无符号整数,则没有未定义的行为。@VladFromMosco-有符号整数值不会自动转换为无符号整数值,%u显式表示无符号int,int是另一种类型。
 poin(&d);
1: #include <stdio.h>
2: int poin(int **p ){
3: printf("%u\n", *p[0]);
4: printf("%u\n", *p[1]);
5: printf("%u\n", *p[2]);
6: printf("%u\n", *p[3]);
7:
8:}
9: int main( void ){
10: int *p[4],a=1,b=2,c=3,d=4;
11:
12:     p[1]=&b;
13:     p[2]=&c;
14:     p[3]=&a;
15:     p[0]=&d;
16:     poin(p);
17:     return 0;
18:     }