在C语言中,定义一个这样的结构:
typedef struct str
{
char *s;
int len;
}str;
int main()
{
str a;
a.s = "abc"
printf("%s", a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是:"abc",我想知道为什么可以得到这个?
我猜编者认为printf("%s", a)是printf("%s", *&a) 因为与一个等于&A.S,因此*a等于*A.S,对不对?
但如果是这样,如果我把int len结构体中的第一个放在这样:
typedef struct str
{
int len;
char *s;
}str;
int main()
{
str a;
a.len = 10;
printf("%d", a);
}
Run Code Online (Sandbox Code Playgroud)
这次输出是:10,为什么?
也许编译器读取%d所以它知道应该打印一个整数值,只打印4个字节?我想得到一些解释.
您必须指定要打印的值,printf和C通常无法猜测:)
typedef struct str
{
int len;
char *s;
}str;
int main()
{
str a;
a.len = 10; // As you did there, you specify which value from your struct !
printf("%d", a.len);
}
Run Code Online (Sandbox Code Playgroud)
否则,这是不确定的行为,Segfault就要来了!
你正在做的是未定义的行为......
至于它为什么起作用,这取决于现在可变长度参数在 C 中工作的本质。像这样的函数printf依赖于格式字符串来告诉它们传递了什么类型的参数。在第一个示例中,您已经表明您正在传递一个字符串 ( %s),但实际上您传递了一个结构。该函数将在堆栈上printf查找指针,并且因为您的结构以字符串开头,所以它会找到一个!如果你交换和 的char*顺序,然后用 a调用,你将得到垃圾输出或访问冲突。slenprintf%s
同样的规则适用于您交换了顺序的第二个示例,但这次您尝试输出一个整数。您已将整个结构传递给调用,然后调用在堆栈上printf查找 a 。int因为该结构以 an 开头,int你很幸运!如果您没有交换场序,您会看到 10 以外的数字。