这可能是一个非常基本的问题,但我对如何实现这样的事情感到困惑。
对于我正在使用C的类,我需要采用两个长度不同的数组,并在一个单独的函数中比较它们的元素。 (此函数仅将数组作为参数,而不是它们的大小)两个数组中的任何元素我需要放入另一个数组并返回该数组(注意:每个数组都像一个集合,因为没有元素在同一个数组中重复)。我已经研究了如何实现这一点,以下是我遇到的一些问题。
我如何知道数组末尾的位置?
我想我看到我可以将{0}作为null元素的数组中的元素。如果这是真的,我不知道我将比较这个元素以检查是否为空。
我想我应该将指针传递给数组的第一个元素,因为我不认为C会让数组的值传递,但有点不确定。
如果我将数组作为指针传递,我如何访问数组元素以获取数据?
将数组返回到main函数时,如何在不清除内存的情况下返回结果函数?
我应该将结果数组设为全局数据,还是有更好的处理方式?
提前致谢。
答案 0 :(得分:2)
你的问题有点模糊。看起来你想要实现set intersection,你有两个集合,由数组表示,输出是另一个实现为数组的数组。
<强> 1。我怎么知道数组的末尾在哪里?
在C中,没有办法说出来。如果您无法将长度作为函数传递,那么您将无法执行强大的解决方案。它需要与#2类似。
<强> 2。我想我看到我可以将{0}作为一个元素 null元素的数组。如果这是真的,我不知道我会做什么 比较此元素以检查是否为空。
你可以添加一个空字符,它只是值0.要检查,你需要比较0.我不知道你的每个数组元素是由什么组成的,但有一点需要注意的是这些值都不允许为零,因为它被保留为数组标记的结尾。
第3。我想我应该将指针传递给第一个元素 数组因为我不认为C会让数组的值为 通过,但有点不确定。
是。您将传递指向第一个元素,在C中是数组符号。
int A[10]; // pass A
<强> 4。如果我确实将数组作为指针传递,我该如何访问数组 获取数据的元素?
假设您传递了指针A,您可以通过简单索引作为A [i]来访问元素,以获取元素i。
<强> 5。将数组返回到main函数时,如何在不清除内存的情况下返回结果函数?
在您正在编写的函数中,您可以malloc
一个数组并将指针传递给malloc创建的数组。当函数退出时,不会删除Malloce'd内存。
答案 1 :(得分:1)
我怎么知道数组的结尾在哪里?
如果你没有将数组的大小作为单独的参数传递(你应该是这样),那么你将使用来使用某种类型的sentinel值(C字符串的方式)在字符串中的最后一个字符后使用0)。
我想我应该将指针传递给数组的第一个元素,因为我不认为C会让数组的值传递,但有点不确定。
C的数组语义有点棘手。除非它是sizeof
,_Alignof
或一元&
运算符的操作数,或者是用于在声明中初始化数组的字符串文字,否则表达式为“N” -element数组T
“将转换为”指向T
的指针“的表达式,表达式的值将是数组中第一个元素的地址。所以,给定代码
int arr1[10];
foo(arr1); // equivalent to foo(&arr1[0]);
arr1
调用中的表达式foo
将从“{10}元素数组int
”转换为“指向int
”,并且收到的值by foo
是数组第一个元素的地址:
void foo(int *a)
{
// do stuff with a[i]
}
表达式a[i]
被解释为*(a + i)
;我们在i
之后找到a
'元素的地址,并取消引用结果。
这是一种冗长的方式,说你会在函数的参数上使用[]
运算符,就像它们是常规数组一样。
将数组返回到main函数时,如何在不清除内存的情况下返回结果函数?
不完全清楚你的意思。请注意,以下代码不会工作:
int *foo(int *a1, int *a2)
{
int a3[SOME_SIZE];
// copy elements from a1 and a2 to a3;
return a3;
}
一旦foo
退出,数组a3
就不复存在了;该内存由系统回收,因此返回的指针值不再有效。您有三种选择:
首先,您可以将目标数组作为第三个参数传递:
int main(void)
{
int arr1[N];
int arr2[M];
int arr3[K];
...
foo(arr1, arr2, arr3);
...
}
void foo(int *a1, int *a2, int *result) { ... }
前提是result
指向一个足够大的数组来容纳你找到的所有元素(它应该与两个源数组中较大的一个一样大)。如果你不想搞乱动态内存管理,这就是你要走的路。
其次,您可以在函数中动态分配目标数组:
int main(void)
{
int a1[M];
int a2[N];
int *a3;
...
a3 = foo(a1, a2);
...
free(a3);
}
int *foo(int *a1, int *a2)
{
int *result = malloc(sizeof *result * SOME_SIZE);
...
if (element_in_both_arrays())
result[n++] = element_from_both_arrays();
...
return result;
}
一旦完成记忆,你必须记住释放内存。
最后,您可以将目标数组声明为全局变量(即,在文件范围内)。我不会举一个例子,因为你不想那样做。
无论何时将数组传递给函数或返回动态分配的缓冲区,您都需要将数组大小作为单独的参数传递。通常,不可能仅根据指针值确定数组中有多少个元素。您可以使用sentinel值,但它们只会告诉您数组的逻辑大小,而不是 physical 大小。例如:
char buffer[1024] = "foo";
buffer
的逻辑大小为3(字符串的长度),但其物理大小为1千字节。
答案 2 :(得分:0)
要知道数组的长度,您需要将长度作为参数传递,或者您需要在数组中使用一个特殊值来表示它是最后一项。
如果传递数组,则传递指向数组的指针。如果不清楚,也许你应该包括一些代码。
如果将数组传递给函数,则对调用方法可以看到对数组所做的任何更改。没有必要退货。
答案 3 :(得分:0)
For 1:函数的调用者应该知道每个数组的长度。允许将此信息传递给函数。您可以选择使用sentinel值来指示有效元素的结尾,但您必须确保该函数的所有用户都知道此约定并遵循它。
For 2:数组名称将降级为指针类型,其值为数组的第一个元素的地址(在大多数情况下)。没有什么特别需要做的事情。
For 3:您可以让调用者提供指向要复制输出的内存的指针。或者,可以通过函数动态分配数组,但调用者需要知道释放此内存。
/* Finds elements common to both a and b, and copies them to c. The c out
parameter is assumed to be at least as large as the smaller of the a_sz
and b_sz. Returns the number of elements copied into c. */
int find_in_common (const int *a, size_t a_sz, const int *b, size_t b_sz,
int *c)
{
/* ... */
}