我正在尝试打印字符串数组。这是我到目前为止的代码:
#include <stdio.h>
void print_array (char * strings[]) {
size_t array_length = sizeof(strings) / sizeof(strings[0]);
for (int i=0; i < array_length; i++)
printf("%s, ", strings[i]);
}
int main(void) {
char * strings[] = {
"Hello",
"Zerotom",
"new"
};
// it does work here...
printf("Array size: %lu\n", sizeof(strings) / sizeof(strings[0]));
// but not here
print_array(strings);
return 0;
}
由此,我得到一条警告:
strings.c:4:30:警告:数组函数参数上的sizeof将返回size 'char **'而不是'char * []'[-Wsizeof-array-argument] size_t array_length = sizeof(strings)/ sizeof(strings [0]);
但是,如果我将函数arg从char * strings[]
更改为char **
,它将返回错误的长度(1而不是3)。我在这里做什么错了?
答案 0 :(得分:1)
可以在strings
中打印main()
但不能在print_array
中打印sizeof
的原因是数组如何在访问时转换为指针的结果。这意味着当您访问数组时(下面有4个例外),该数组将转换为指向数组中第一个元素的指针。转换完成后,就像将数组作为参数传递给函数时一样,您只有一个指针,而没有数组。
C11标准(以及C17标准)的内容如下:
数组指针转换
(p3)除非它是_Alignof
运算符,'&'
运算符或一元sizeof
运算符的操作数,或者是字符串常量用于初始化数组,将类型为“类型为数组” 的表达式转换为类型为“类型为指针” 的表达式,该表达式指向的初始元素数组对象,不是左值。
C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3)
如果您在上面指出,与main()
运算符一起使用时,并且数组未转换为指针,因此在sizeof(strings) / sizeof(strings[0])
中,strings
提供了以下元素的数组数目:串。但是,在将print_array
传递给print_array
之后,已经发生了向指针的转换,因此在sizeof
中尝试使用size_t array_length = sizeof(a_pointer) / sizeof(a_char);
会导致:
8
(在x86_64上为4
,在x86上为print_array
)
您有两种选择(1)将数组中的元素数量作为第二个参数传递给strings
,或者(2) NULL
print_array
中的指针(用作标记值)。然后在strings[i]
中,您可以遍历NULL
直到它为#include <stdio.h>
void print_array (char **strings, size_t nptrs)
{
for (size_t i = 0; i < nptrs; i++)
printf("%s, ", strings[i]);
putchar ('\n');
}
int main(void) {
char *strings[] = { "Hello",
"Zerotom",
"new" };
print_array (strings, sizeof strings/sizeof *strings);
return 0;
}
。
几个简单的例子:
传递元素数量
$ ./bin/prnarray
Hello, Zerotom, new,
使用/输出示例
NULL
向strings
添加一个前哨#include <stdio.h>
void print_array (char **strings)
{
for (size_t i = 0; strings[i]; i++)
printf("%s, ", strings[i]);
putchar ('\n');
}
int main(void) {
char *strings[] = { "Hello",
"Zerotom",
"new",
NULL }; /* sentinel NULL */
print_array (strings);
return 0;
}
for
(相同的输出)
至少有几种方法可以使用while
或strings
循环以及使用指向 Route::get('/', 'UserController@index')->name('user.index');
的指针和指针算术,或使用数组索引进行循环(区别在于做相同的事情的简单语义)。仔细研究一下,如果您还有其他问题,请告诉我。