在许多编程语言中(包括JavaScript,Java和Ruby),可以在其中放置一个数组。在这里,我试图在其第三个索引处放置一个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数组放入其中,或者根本不可能?
答案 0 :(得分:5)
不,int
数组不可能包含自己。
你可以玩一些(很可能是非便携式)技巧,比如让数组中的一个元素成为指向数组的转换指针:
int arr[10];
arr[5] = (int)arr;
但这并不会使数组包含自身。表达式arr
,因为它是数组类型,在大多数情况下(包括这个)隐式转换(“衰减”)指向其第一个元素的指针。因此,假设转换不会丢失任何信息,您可以通过将arr
转换回类型arr[5]
来检索指向int*
的第一个元素的指针。请注意,这只会指向arr
的第一个元素;它丢失了有关arr
长度的任何信息。并且int*
指针值在不丢失信息的情况下不适合int
是非常常见的(在64位系统上,int*
常见的是64位且{{1}是32位)。
整数,指针和数组是三个截然不同的东西。它们不仅仅是可以互换的。
推荐阅读:comp.lang.c FAQ的第6部分;它很好地解释了C中数组和指针之间常常令人困惑的关系。
即使在像Java和Ruby这样的语言中,数组实际上也不能包含本身。它可以包含一个引用 - 虽然该语言可能提供语法糖,隐藏它是一个引用的事实。在C中,这些引用通常是明确的。
您可以做的是定义一个数据结构,其中包含指向其自身类型的对象的指针。这通常用结构来完成。例如:
int
这是C,您必须显式管理树节点的内存,使用struct tree_node {
int data;
struct tree_node *left;
struct tree_node *right;
};
分配和malloc()
解除分配 - 或者您可以使用现有的库为您执行此操作。< / p>
答案 1 :(得分:0)
实际上,如果你的系统上的int的长度等于或大于指针的长度,那么你可以将指针强制转换为int来存储它 - 如果你记得要转换它在您尝试将其作为指针取消引用之前。忽视做后者是导致错误信息的原因。
请注意,在这样一个简单的方案中,您必须分别跟踪哪些元素是值,哪些元素是指针。只有当你可以保证指针的长度小于一个元素的长度(或者用户空间指针的有效范围被进一步约束)时,你可以保留一些位来指示一个元素是一个文字值还是一个指针。
以下是一个示例,说明如何根据先前的知识明确地将其强制转换回来:
printf("%i", ((int *)arr[2])[0]);
为了更干净地完成这个,你可能想要创建一个不是int的数组,而不是unions,这样每个元素都是一个int的union
和一个指针 - 这意味着有两个正式认可的可能相同记忆的意见。但是你仍然需要一个方案来跟踪每个元素的适用类型。