【问题标题】:What happens if i don't use zero-based array in C如果我不在 C 中使用从零开始的数组会发生什么
【发布时间】:2015-06-23 21:52:37
【问题描述】:

有人可以解释会发生什么吗?真的有必要从索引0 而不是1 开始(这对我来说更容易)吗?

【问题讨论】:

  • 你最终会遇到使用数组(例如字符串库)和动态分配数组(大小)的任何库函数。
  • @GrzegorzSzpetkowski:不正确!上次我有 UB 我的电脑问我披萨。
  • 提醒我 - 我没有多余的意大利辣香肠了:(
  • 你可能会发现很难找到一份编程工作。
  • 采用从零开始计数比让任何代码处理从一开始计数要容易得多。优雅的代码是不可能的。相信我,我是一名医生。

标签: c arrays


【解决方案1】:

你可以为所欲为,只要你的数组下标严格小于数组的大小。

例子:

int a[100];

a[1] = 2;   // fine, 1 < 100

【讨论】:

  • 问题是如果不关心(未使用的)零索引,他可能会遇到分配问题。
  • @Olaf:不,为什么?没有迹象表明这应该会发生。
  • int *a = malloc(sizeof(int) * 10); // 10 elements: index 1..10 ?对于多个维度,这变得更加讨厌。但是,就问题本身而言,OP 可能会在关心malloc&friends 之前更早遇到麻烦。
  • @Olaf:嗯,正如我在帖子中所说(但可能不够清楚),下标必须严格小于大小。
【解决方案2】:

如果我不在 C 中使用从零开始的数组会发生什么

嗯,你不能C 数组是从零开始的,按照定义,按照标准。

真的有必要从0开始吗?

好吧,这不是防止你离开索引0未使用的规则,但是,你几乎肯定不会得到想要的结果。 p>

【讨论】:

  • 是的,我得到了我的回答的真正崇拜者!!!尊敬的先生/女士,请说明拒绝投票的原因,我很感兴趣。 :-)
【解决方案3】:

C 中使用基于非零的数组是可能的,但不推荐。以下是分配 100 个整数的基于 1 的数组的方法:

int * a = ((int*)malloc(100*sizeof(int)))-1;

-1 将指针的开头从数组的开头移回一个,使第一个有效索引为 1。因此该数组将具有从 1 到 100 的有效索引。

a[1]   = 10; /* Fine */
a[100] = 7;  /* Also fine */
a[0]   = 5;  /* Error */

不推荐这样做的原因是C 中的所有其他内容都假定指向内存块的指针指向第一个感兴趣的元素,而不是之前的元素。例如,上面的数组不适用于memcpy,除非每次传入时都给指针加1。

【讨论】:

  • 该代码是非法的,因为它创建的指针既不指向分配的存储空间,也不指向“刚刚超出”的位置。此类指针的创建是未定义行为,无论它们是否被引用;编译器可以(从 C 标准的角度)完全合法地将 int *a = ... 语句替换为查找并销毁所有 Justin Bieber 记录的代码,因为没有定义该语句的行为的情况。跨度>
  • 那是避免它的另一个原因。尽管如此,找到一个不起作用的编译器将是一项壮举。尽管根据标准,所有未定义的行为都是相同的,但实际上有些行为比其他行为更温和。这种情况是最安全的未定义行为之一。
  • 如果标准要描述更多形式的规范行为超出所需的规范行为,并且需要实现来定义类似于 FLT_EVAL_METHOD 的功能宏,代码可以验证以确保它只会被使用,这将是有帮助的在支持预期行为的平台上,但目前还不支持。一些编译器作者认为,为了优化不会导致未定义行为发生的输入的性能,编译器应假定永远不会收到任何会导致未定义行为发生的输入组合。
  • 由于拥护该哲学的编译器编写者尚未被流放出上流社会,因此对于可能使用此类人编写的编译器处理的任何代码,都不存在“安全”未定义行为。静态分析可以非常快速地确定到达malloc 语句的任何代码都会调用未定义行为,无论malloc 是否返回null;如果编译器可以确定调用方法foo 将始终调用未定义行为,则编译器可以将if (x &gt; 0) bar(); else foo(); 替换为对bar 的无条件调用。
  • 是的,这可能会发生。不过,我认为您不会找到真正做到这一点的人。标准非常重要,但编译器的实际工作不应被忽视。编纂现有实践是标准编写的重要组成部分。
猜你喜欢
  • 2022-11-17
  • 1970-01-01
  • 1970-01-01
  • 2015-02-09
  • 1970-01-01
  • 2011-12-31
  • 1970-01-01
  • 1970-01-01
  • 2012-04-01
相关资源
最近更新 更多