①:串行执行
#include <stdio.h>
int main()
{
struct ks{
int a;
int *b;
}s[4], *p;
int n=1, i;
for(i = 0; i<4; i++){
s[i].a = n;
s[i].b = &s[i].a;
n = n+2;
}
/*
0 1 2 3
1 3 5 7
*/
p = &s[0];
p++;
printf("%d\n",(++p)->a);
printf("%d\n",(p++)->a);
//printf("%d,%d\n", (++p)->a, (p++)->a); /* 输出数据之间没有空格分隔 */
return 0;
}
?这个程序的执行结果是:
5,5
②:并行执行:
#include <stdio.h>
int main()
{
struct ks{
int a;
int *b;
}s[4], *p;
int n=1, i;
for(i = 0; i<4; i++){
s[i].a = n;
s[i].b = &s[i].a;
n = n+2;
}
/*
0 1 2 3
1 3 5 7
*/
p = &s[0];
p++;
printf("%d,%d\n", (++p)->a, (p++)->a); /* 输出数据之间没有空格分隔 */
return 0;
}
这个程序的输出结果是:
7,3
与变编译器有关,我使用的是Codeblocks和Dev Cpp,这两个编译器会从右往左计算参数,也就是先计算p++再计算++p,所以输出是7,3
此外需要注意的是:
在 C 语言中,函数参数的计算顺序是没有定义的(undefined order of evaluation)。也就是说,函数参数的计算顺序取决于编译器的实现,可能会有不同的结果。
在这段代码中,printf
?函数的两个参数?(++p)->a
?和?(p++)->a
?都涉及到指针?p
?的自增操作。然而,由于参数计算顺序不确定,编译器可以自由地计算这两个参数的先后顺序,因此结果也是不确定的。
在一些编译器实现中,可能先计算这个表达式的第一个参数,然后计算第二个参数。而在另一些编译器实现中,可能先计算第二个参数,然后再计算第一个参数。这就解释了为什么两个代码的输出结果不同。
所以,对于这样依赖于参数计算顺序的代码,应尽量避免在同一个表达式中同时使用多个自增或自减操作,在不同的语句中分开计算会更可靠。
#include<stdio.h>
struct ps{
double i;
char arr[24];
};
int main()
{
struct ps s[3], *p1, *p2;
p1=s;
p2=s+2;
printf("%d,%d\n", p2-p1, sizeof(struct ps)); /* 输出数据之间没有空格分隔 */
return 0;
}
输出结果:
2,32
注意结构体占用的空间是每个元素的空间之和(与共用体区分),double占8个字节。