我正在学习C语言。我想知道函数内部数组的大小。此函数接收指向数组的第一个元素的指针。我不想像函数参数一样发送大小值。
我的代码是:
#include <stdio.h>
void ShowArray(short* a);
int main (int argc, char* argv[])
{
short vec[] = { 0, 1, 2, 3, 4 };
short* p = &vec[0];
ShowArray(p);
return 0;
}
void ShowArray(short* a)
{
short i = 0;
while( *(a + i) != NULL )
{
printf("%hd ", *(a + i) );
++i;
}
printf("\n");
}
我的代码没有显示任何数字。我该如何解决?
感谢。
答案 0 :(得分:0)
C
中的数组只是分配连续内存位置的方法,而不是&#34;对象&#34;正如您可能在其他语言中找到的那样因此,当您分配数组(例如int numbers[5];
)时,您需要指定要为阵列保留多少物理内存。
但是,这并不能告诉您在任何特定时间点使用物理阵列的(概念)列表中有多少有效条目。
因此,您需要保留&#34;列表&#34;的实际长度。作为单独的变量(例如size_t numbers_cnt = 0;
)。
我不想像函数参数那样发送大小值。
由于您不想这样做,另一种方法是使用struct
并自行构建array
类型。例如:
struct int_array_t {
int *data;
size_t length;
};
这样,您可以使用类似于:
的方式使用它struct int_array_t array;
array.data = // malloc for array data here...
array.length = 0;
// ...
some_function_call(array); // send the "object", not multiple arguments
现在你不必写:some_other_function(data, length);
,这是你原本想要避免的。
要使用它,您可以简单地执行以下操作:
void display_array(struct int_array_t array)
{
size_t i;
printf("[");
for(i = 0; i < array.length; ++i)
printf("%d, ", array.data[i]);
printf("]\n");
}
我认为这是一个更好,更可靠的替代方案,而不是尝试用哨兵值填充数组的另一个建议(例如-1
),这在非平凡的程序中更难处理(例如,理解,维护,调试等)和AFAIK也不被视为良好做法。
例如,您当前的数组是short
s的数组,这意味着建议的-1
的标记值不能再被视为有效条目这个数组。你还需要将内存块中的所有内容清零,以防万一这些哨兵已经存在于已分配的内存中。
最后,当你使用它时,它仍然不会告诉你数组的实际长度是多少。如果你不在一个单独的变量中跟踪它,那么你必须通过循环遍历数组中的所有数据来计算运行时的长度,直到遇到一个标记值(例如-1
),这会影响表现。
换句话说,要找到长度,您必须执行以下操作:
size_t len = 0;
while(arr[len++] != -1); // this is O(N)
printf("Length is %u\n", len);
strlen
函数已经遇到此性能问题,时间复杂度为O(N)
,因为它必须处理整个字符串,直到找到NULL char来返回长度。
依赖于哨兵值也不安全并在C和C ++程序中产生了无数的错误和安全漏洞,甚至微软建议使用banning their use来帮助阻止更多安全漏洞。
我认为没有必要制造这类问题。比较以上内容,只需写下:
// this is O(1), does not rely on sentinels, and makes a program safer
printf("Length is %u\n", array.length);
在array.data
添加/删除元素时,您只需编写array.length++
或array.length--
即可跟踪有效条目的实际数量。所有这些都是固定时间操作。
你还应该保持数组的最大大小(你在malloc中使用的大小),这样你就可以确保array.length
永远不会超出上述限制。否则你会遇到段错误。
答案 1 :(得分:-1)
一种方法是使用与数组中任何值唯一的终结符。例如,您想传递int
的数组。您知道您从不使用值-1
。所以你可以用它作为终结者:
#define TERM (-1)
void print(int *arr)
{
for (; *arr != TERM; ++arr)
printf("%d\n", *arr);
}
但通常不使用这种方法,因为哨兵可能是有效数字。通常情况下,你必须通过这个长度。
你不能在函数内部使用sizeof
,因为只要你传递数组,它就会衰减成指向第一个元素的指针。因此,sizeof arr
将是您计算机上指针的大小。
答案 2 :(得分:-2)
#include <stdio.h>
void ShowArray(short* a);
int main (int argc, char* argv[])
{
short vec[] = { 0, 1, 2, 3, 4 };
short* p = &vec[0];
ShowArray(p);
return 0;
}
void ShowArray(short* a)
{
short i = 0;
short j;
j = sizeof(*a) / sizeof(short);
while( i < j )
{
printf("%hd ", *(a + i) );
++i;
}
printf("\n");
}
不确定这是否会起作用尝试(我目前没有电脑)