0

在许多编程语言(包括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 数组,或者根本不可能?

4

2 回答 2

5

No, it's not possible for an array of int to contain itself.

There are some (likely non-portable) tricks you can play, like making one of the elements of the array be a converted pointer to the array:

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

but this doesn't make the array contain itself. The expression arr, since it's of array type, is implicitly converted ("decays") to a pointer to its first element in most contexts, including this one. So, assuming the conversion doesn't lose any information, you can retrieve a pointer to the first element of arr by converting arr[5] back to type int*. Note that this only gives you a pointer to arr's first element; it loses any information about the length of arr. And it's very common for an int* pointer value not to fit into an int without loss of information (on 64-bit systems, it's common for int* to be 64 bits and int to be 32 bits).

Integers, pointers, and arrays are three very different things. They are not simply interchangeable.

Recommend reading: section 6 of the comp.lang.c FAQ; it does a very good job of explaining the often confusing relationship between arrays and pointers in C.

Even in languages like Java and Ruby, an array can't actually contain itself. It can contain a reference to itself -- though the language might provide syntactic sugar that hides the fact that it's a reference. In C, such references are generally explicit.

What you can do is define a data structure that contains a pointer to an object of its own type. This is generally done with structures. For example:

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

This being C, you have to manage memory for your tree nodes explicitly, using malloc() to allocate and free() to deallocation -- or you can use an existing library that does that for you.

于 2013-05-22T03:09:31.077 回答
0

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

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

这是一个示例,说明如何根据先验知识将其显式回退,即这适用于该元素:

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

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

于 2013-05-22T02:50:43.737 回答