有没有办法在不传递参数的情况下在函数中查找数组长度?
Is there a way to find array length in a function without passing an argument?
有没有办法在函数中获取数组的长度?我需要找到数组的大小,但是它是在主函数中定义的,我不能将数组大小作为参数传递,因为我不能更改主函数。那么有没有办法通过函数找到呢?
数组的最大大小设置为大约 100,但实际输入将在大小 1 - 20 之间的任何位置。所以我也不能真正采用最大大小方法。
您可以包含一个带有计数器的 for 循环,以查看在下一行之前有多少变量。
int counter(int array[100]) {
int counter = -1;
for (i = 0; array != '[=10=]'; i++) {
counter = counter + 1;
}
return counter;
}
然后在主要部分
int arraysize = counter();
如果函数被声明为例如
void f( T a[] );
其中 T 是某种类型说明符,然后函数处理指向类型 T 的指针。即上面的声明等同于以下声明
void f( T *a );
两者都声明了同一个函数。
因此,计算指针指向的数组中实际元素数量的唯一方法是引入一个不同于数组实际元素值的标记值。
例如,当字符数组包含一个字符串时,字符数组可以有像'\0'这样的标记值。
字符串数组可以将空字符串“”作为标记值,或者根据它的声明方式(例如作为元素类型为 char * 的数组),标记值可以为 NULL。
对于整数数组,您必须自己 select 一个适当的值作为标记值。例如,如果实际元素是非负的,那么标记值可以设置为 -1。
不,数组 总是 在传递给函数时衰减为指针,因此如果您想让函数知道大小,则必须传递长度。对于一些先决条件,您有多种方法可以在没有附加参数的情况下执行此操作:
在最后添加一个null/zero/whatever特殊参数,类似于以null结尾的char数组。这只有在您确实知道有一个从未出现在值列表中的唯一值要放在最终位置时才有可能。这个方法在Linux系统调用中其实很常见,比如exec
family
char *args[] = { "Hello", "C", "Programming", NULL /* ends the array */ };
execv("./hello", args);
开头加上长度前缀
void my_function(int array[])
{
int length = array[0];
int* data = &array[1];
// operate on data[];
}
int my_data[LENGTH + 1] = { LENGTH, /* values */ };
my_function(my_data);
Pascal 也使用 length-prefixed string,因此它的字符串被限制为只有 255 个字符,长度为 1 个字节。但这可以通过使用更大的长度来解决
它的一个变体是BSTR
in Windows,其中指针指向实际数据而不是结构的开始
typedef struct MY_ARRAY
{
int32_t length;
my_type* data; // array of the desired type
} my_array;
void my_function(my_type array[])
{
int length;
memcpy(&length, (char*)array - sizeof(int32_t), sizeof(int32_t));
// operate on array[];
}
my_type data_list[] = { /* some data */ };
my_array my_data = { LENGTH, data_list };
my_function(my_data.data);
有没有办法在函数中获取数组的长度?我需要找到数组的大小,但是它是在主函数中定义的,我不能将数组大小作为参数传递,因为我不能更改主函数。那么有没有办法通过函数找到呢?
数组的最大大小设置为大约 100,但实际输入将在大小 1 - 20 之间的任何位置。所以我也不能真正采用最大大小方法。
您可以包含一个带有计数器的 for 循环,以查看在下一行之前有多少变量。
int counter(int array[100]) {
int counter = -1;
for (i = 0; array != '[=10=]'; i++) {
counter = counter + 1;
}
return counter;
}
然后在主要部分
int arraysize = counter();
如果函数被声明为例如
void f( T a[] );
其中 T 是某种类型说明符,然后函数处理指向类型 T 的指针。即上面的声明等同于以下声明
void f( T *a );
两者都声明了同一个函数。
因此,计算指针指向的数组中实际元素数量的唯一方法是引入一个不同于数组实际元素值的标记值。
例如,当字符数组包含一个字符串时,字符数组可以有像'\0'这样的标记值。
字符串数组可以将空字符串“”作为标记值,或者根据它的声明方式(例如作为元素类型为 char * 的数组),标记值可以为 NULL。
对于整数数组,您必须自己 select 一个适当的值作为标记值。例如,如果实际元素是非负的,那么标记值可以设置为 -1。
不,数组 总是 在传递给函数时衰减为指针,因此如果您想让函数知道大小,则必须传递长度。对于一些先决条件,您有多种方法可以在没有附加参数的情况下执行此操作:
在最后添加一个null/zero/whatever特殊参数,类似于以null结尾的char数组。这只有在您确实知道有一个从未出现在值列表中的唯一值要放在最终位置时才有可能。这个方法在Linux系统调用中其实很常见,比如
exec
familychar *args[] = { "Hello", "C", "Programming", NULL /* ends the array */ }; execv("./hello", args);
开头加上长度前缀
void my_function(int array[]) { int length = array[0]; int* data = &array[1]; // operate on data[]; } int my_data[LENGTH + 1] = { LENGTH, /* values */ }; my_function(my_data);
Pascal 也使用 length-prefixed string,因此它的字符串被限制为只有 255 个字符,长度为 1 个字节。但这可以通过使用更大的长度来解决
它的一个变体是
BSTR
in Windows,其中指针指向实际数据而不是结构的开始typedef struct MY_ARRAY { int32_t length; my_type* data; // array of the desired type } my_array; void my_function(my_type array[]) { int length; memcpy(&length, (char*)array - sizeof(int32_t), sizeof(int32_t)); // operate on array[]; } my_type data_list[] = { /* some data */ }; my_array my_data = { LENGTH, data_list }; my_function(my_data.data);