繁体   English   中英

指向char指针与char指针的指针数组的指针(或char ** argv vs. char *(* argv)[])

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM