[英]Pointer to array of pointer to char vs. pointer to pointer to char (or char** argv vs. char* (*argv)[])
今天,我与一位同事讨论了他(对我而言)不寻常的“主要”功能签名。 他喜欢这样声明:
int main(int argc, char* (*argv)[]) {
printf("at index 0: %s\n", (*argv)[0]);
}
而我通常编写以下代码:
int main(int argc, char** argv)
{
printf("at index 0: %s\n", argv[0]);
}
有时我写“ char * argv []”,以便更清楚地表明argv是指向chars的指针数组。
第一个示例中的代码确实带有警告编译
warning: second argument of ‘main’ should be ‘char **’
但它有效。 我的问题是代码为什么能正常工作,因为我曾预计会由于取消引用argv而导致崩溃。 编译器是否知道函数签名不同,并且在这里允许(* argv)作为一种“无操作”?
为了理解正在发生的事情,我编写了以下示例,令我惊讶的是,该示例也没有崩溃也不会输出“ first”(但编译器会发出警告):
#include <stdio.h>
int my_function(int argc, char* (*argv)[])
{
printf("at index 0: %s\n", (*argv)[0]);
}
int main(void)
{
char* stringArr[] = { "frist",
NULL };
size_t stringArrSz = sizeof(stringArr)/sizeof(*stringArr);
return my_function(stringArrSz, stringArr);
}
我曾期望我需要传递“&stringArr”(使用地址运算符)来使代码运行。 当然,它也可以工作,并且可以修复编译器警告。
如果我的问题不清楚,请告诉我,我们将不胜感激!
我的问题是代码为什么能正常工作,因为我曾预计会由于取消引用argv而导致崩溃。 编译器是否知道函数签名不同,并且在这里允许(* argv)作为一种“无操作”?
“看起来像预期的那样工作”是不确定行为的可能结果之一。
有效的指针值仍在从运行时环境传递给argv
,因此我不希望代码仅由于访问argv[0]
而崩溃,无论它如何声明。
当您尝试访问argv[1]
, argv[2]
等时,会变得有趣的地方。尽管C语言本身并不保证指向不同对象类型的指针具有相同的大小,但实际上,它们在大多数现代语言中都可以做到。像x86
这样的x86
; IOW, sizeof (T *)
== sizeof (T **)
== sizeof ( T *** )
。 因此,对于该平台上的每种类型, p + 1
应产生相同的字节偏移。
但是,您的同事却在调情灾难。 类型确实很重要,如果您在不同指针类型具有不同大小的系统上工作,则将argv
声明为char *(*)[]
而不是char *[]
或char **
可能会产生一些意外的后果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.