繁体   English   中英

C'中结构的不同行为

[英]Different behaviour of struct in C'

我开始学习C,挺好玩的。 但是当我尝试使用struct时,我已经到了关键点。 下面是我创建的程序,我注意到struct的行为因创建方式而异。

当我运行下面的程序时,我的 output 令人惊讶。 Output:

1. 1 0.000000 (some strange chars)
2. 0 0.000000 (null)

首先就像你可以看到 1 的 output 一样,2 是不同的,即使它与相同的struct相关。 第二个数字 3 根本没有打印。

我想知道这是为什么? 我在 stackoverflow 上找到了一些关于c struct的解释,但这篇文章没有涉及这个问题。 我想知道这是否是因为编译器? 或者这是我必须了解的 C 的正常功能? 还是我什至考虑过?

#include <stdio.h>

struct s1 {
  int int1;
  double double1;
  char *string;
} strc;

typedef struct {
  int int1;
  double double1;
  char *string;
} DStruct;

int main() {
  struct s1 defqu;
  DStruct defqu2;

  printf("1. %d %f %s\n", defqu.int1, defqu.double1, defqu.string);
  printf("2. %d %f %s\n", strc.int1, strc.double1, strc.string);
  printf("3. %d %f %s\n", defqu2.int1, defqu2.double1, defqu2.string);
  
  return 0;
}

您从未初始化您创建的实例,因此它包含“垃圾”。 因此,您可以期待“意外行为”:)

将其更改为:


struct s1 {
  int int1;
  double double1;
  char *string;
} strc = {0};

typedef struct {
  int int1;
  double double1;
  char *string;
} DStruct;

int main() {
  struct s1 defqu = {0};
  DStruct defqu2 = {0};

  ...

语法= { 0 }将结构中的所有值初始化为 0。来自 C99 标准:

如果大括号括起来的列表中的初始值设定项少于聚合的元素或成员,或者用于初始化已知大小数组的字符串文字中的字符少于数组中的元素,则聚合的其余部分应与具有 static 存储持续时间的对象一样被隐式初始化。

这样会更好,但仍不完美。 数字将全部初始化为 0,字符串指针(更准确地说是char * )将初始化为 NULL。

现代 libc 实现将优雅地处理您传递给%s的 NULL 指针,但这实际上也是未定义的行为。

strc是一个全局变量。 它保证(按 C 标准)初始化为零。 所以strc的所有成员也将被初始化为零(包括字符串指针)。 当您尝试在第二个 printf ( %s ) 中打印string时,您会调用未定义的行为(取消引用 null 指针)。 当取消引用 NULL 指针时,程序很可能会崩溃/终止,但这不是标准所保证的。 因为,你知道,这是未定义的行为!

defqudefqu2main function 中的局部变量。在 C 中,局部变量永远不会自动初始化。所以它们有一些垃圾值,不能像strc那样保证为零。 因此, string指针指向某个随机地址 memory,而第一个 printf 最有可能在该随机 memory 位置打印字符。 您没有从第三个printf中看到任何 output,因为如上所述,由于 null 取消引用,程序在第二个printf崩溃/退出。 将这个printf移到最后,你也会看到 defqu2 的defqu2 ,但你永远无法确定(因为,未定义的行为!)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM