关于argc argv和env的混淆

Confusion about argc argv and env

本文关键字:env argc argv 关于      更新时间:2023-10-16

我只是不知道如何准确地解释我的问题。所以我写了上面的标题。

这是我对一个非常简单的程序的困惑。没错,的结果是

#include <iostream>
using namespace std;
char * tmp[]={"aaa", "bbb", "ccc"};//there are 3 members
int main(int argc, char* argv[], char* env[])
{
    cout << sizeof(env)/sizeof(char*) << endl;
    cout << sizeof(tmp)/sizeof(char*) << endl;
}

结果:1 3

我需要的是env[]的长度。我怎么可能得到env[]的1,而'tmp'(3)的长度是绝对正确的呢?

env的长度不可能是1,因为我测试过了,它的数字是47。

为什么会这样?谢谢!

区别在于tmp是一个数组,而env是一个指针。数组和指针是不同的。这有点令人困惑,因为函数形式参数列表中的数组语法实际上是一个伪装的指针。

无法通过sizeof得到env所指向的元素个数。您必须遍历它们,直到找到终止列表的NULL元素。

重要的是要记住,argvenv指针,而不是数组。在函数参数声明的上下文中,T a[]T a[N]被解释为T *a,因此argvenv的类型都是char **,而不是char *[N]

确定每个元素指向多少个元素的唯一方法是遍历它们,直到找到一个NULL指针:

size_t i;
for ( i = 0; argv[i] != NULL; i++ )
  ; // empty loop body
printf( "There are %zu elements in argvn", i );
for ( i = 0; env[i] != NULL; i++ )
  ; // empty loop body
printf( "There are %zu elements in envn", i );

C语言有一些语法特性,对有经验的程序员来说很方便,但对初学者来说却很困惑。虽然语法T * X[]在这两种情况下看起来是一样的,但它们实际上意味着两个非常不同的东西:

  • int a[] = { 1, 2, 3};int a[3] = { 1, 2, 3 };相同。这里a是一个数组,数组的大小是从初始化器中推导出来的。

  • void f(int b[])void f(int * b)相同。这里b是一个指针,它的表示法仅仅暗示了这样一个事实,即应该使用指向数组元素的指针来调用f。例如,您可以调用f(a),或者等价的f(&a[0]),甚至f(a + 2)。但是声明器语法纯粹是为了美观方便,而且b不是数组,而是指针。

这与这些是main的参数没有什么关系,sizeof任何东西都是编译时表达式。显然,传递给程序的环境和参数不是。sizeof(array)/sizeof(element_type)仅在用静态大小声明数组时才表示该数组的长度。否则,sizeof(array)将等同于sizeof(element*)(并且因为sizeof(char**) == sizeof(char*)您在程序中得到1)。