【问题标题】:Is it possible to put a C array inside itself?是否可以在自身内部放置一个 C 数组?
【发布时间】:2013-05-22 11:14:37
【问题描述】:

在许多编程语言(包括JavaScriptJavaRuby)中,可以在自身内部放置一个数组。在这里,我试图将一个 C 整数数组放入其自身的第三个索引处,但我不确定 C 编程语言是否支持这一点:

#include <stdio.h>

int main(void) {
    int arr[] = {1, 1, 2};
    arr[2] = arr; //now I'm trying to put arr into itself.
    printf("%i", arr[2]); //this prints a negative number each time I run the program
    printf("%i", arr[2][0]); //prog.c:7:24: error: subscripted value is neither array nor pointer nor vector

    return 0;
}

是否可以在自身内部放置一个 C 数组,或者根本不可能?

【问题讨论】:

  • 如果需要不同长度的数组,请制作一个锯齿状数组。
  • @chris 不过,我不明白这会使将数组放入内部变得更容易。
  • 您可以创建一个 void 指针数组并使用大量类型转换来让自己发疯……也许您想要的是链表?
  • 您可能可以使用 void 指针数组,但是...为什么?
  • @AndersonGreen,如果你分配一个指针,这相当容易。如果您想要副本,则工作量不大。问题是 C 根本不像 Java,而且绝对不像 Ruby 或 JS。我发现较新的语言倾向于内置某些 C 没有的东西,而且其中很多倾向于修复 C 比现在大多数语言更难的东西,比如字符串操作。

标签: c arrays


【解决方案1】:

不,int 的数组不可能包含自身。

您可以玩一些(可能是不可移植的)技巧,例如将数组的元素之一转换为指向数组的指针:

int arr[10];
arr[5] = (int)arr;

但这不会使数组包含自身。表达式arr,因为它是数组类型,所以在大多数情况下都被隐式转换(“衰减”)为指向其第一个元素的指针,包括这个。因此,假设转换不会丢失任何信息,您可以通过将arr[5] 转换回类型int* 来检索指向arr 的第一个元素的指针。请注意,这只给您一个指向arr 的第一个元素的指针;它会丢失有关arr 长度的任何信息。 int* 指针值不适合 int 而不会丢失信息是很常见的(在 64 位系统上,int* 通常是 64 位,int 是 32 位)。

整数、指针和数组是三种截然不同的东西。它们不能简单地互换。

推荐阅读:comp.lang.c FAQ第6节;它很好地解释了 C 中数组和指针之间经常令人困惑的关系。

即使在 Java 和 Ruby 等语言中,数组实际上也不能包含自身。它可以包含对自身的引用——尽管该语言可能提供隐藏它是引用的事实的语法糖。在 C 中,此类引用通常是显式的。

您可以做的是定义一个数据结构,其中包含指向其自身类型对象的指针。这通常通过结构来完成。例如:

struct tree_node {
    int data;
    struct tree_node *left;
    struct tree_node *right;
};

这是 C,您必须明确管理树节点的内存,使用 malloc() 分配和 free() 释放 - 或者您可以使用为您执行此操作的现有库。

【讨论】:

    【解决方案2】:

    实际上,如果您系统上的 int 长度等于或大于指针的长度,那么您可以将指针转换为 int 来存储它 - 如果您记得转换它在您尝试将其取消引用为指针之前返回。忽略执行后者是您的错误消息的原因。

    请注意,在这样一个简单的方案中,您必须分别跟踪哪些元素是值,哪些是指针。只有当您可以保证指针的长度小于元素的长度(或者用户空间指针的有效范围受到进一步限制)时,您才能保留一些位来指示元素是文字值还是指针.

    这是一个示例,说明如何根据先验知识显式将其强制转换回该元素:

    printf("%i", ((int *)arr[2])[0]);
    

    为了更清楚地完成此操作,您可能希望创建一个不是整数数组,而是联合数组,这样每个元素都是一个整数和一个指针的union - 这意味着有两个正式认可的可能视图相同的记忆。但是您仍然需要一个方案来跟踪每个元素的适用类型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-14
      • 2011-07-09
      • 2012-08-01
      • 2010-10-17
      • 1970-01-01
      相关资源
      最近更新 更多