首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么char** argv与char* argv[]相同?

为什么char** argv与char* argv[]相同?
EN

Stack Overflow用户
提问于 2022-07-13 16:27:53
回答 4查看 158关注 0票数 3

因此,我在后台阅读了编译器在函数中传递数组时的情况。

代码语言:javascript
复制
int myArray(int arr[])

转到

代码语言:javascript
复制
int myArray(int *arr)

另外,数组大部分时间都会衰减到指针,例如

代码语言:javascript
复制
arr[0]

是相同的

代码语言:javascript
复制
(arr +  0)

(如果我错了,请纠正我)

但是当涉及到char *argv时,它会让人感到困惑,char *argv[]会转换成一个字符串数组。

例如:

代码语言:javascript
复制
argv[2] = "Hello"
argv[3] = "World"

但是**argv如何与*argv[]相同,因为**argv是指向指针的指针,**argv如何包含10个不同的值,因为它是指向指针的指针?我想我误解了什么。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2022-07-13 16:30:10

也是指向指针的数组,例如arr与(arr + 0)相同。

arr[0]的计算与*( arr + 0 )类似,与*arr相同。

具有数组类型的函数参数由编译器调整到指向数组元素类型的指针。

另一方面,用作参数表达式的数组被隐式转换为指向其第一个元素的指针。

因此,例如,这些函数声明

代码语言:javascript
复制
void f( char * s[100] );
void f( char * s[10] );
void f( char * s[] );

,并声明相同的一个函数。

代码语言:javascript
复制
void f( char **s );

为了澄清这一点,只需引入typedef名称即可。例如

代码语言:javascript
复制
typedef char *T;

然后你就有了

代码语言:javascript
复制
void f( T s[] );

因此,函数参数由编译器调整为

代码语言:javascript
复制
void f( T *s );

现在,将ty胡枝子别名更改为它的原始类型,您将得到

代码语言:javascript
复制
void f( char * *s );

请注意,指针s不知道数组用作函数参数的元素有多少。

因此,例如,函数main声明如下

代码语言:javascript
复制
int main( int argc, char *argv[] );

也就是说,它还有一个参数argc,它允许确定传递给函数的字符串数组中的元素数。尽管如果要告诉main,那么在一般情况下,参数argc是多余的,因为字符串数组总是包含哨位值NULL。也就是说,argv[argc]等于NULL

但通常,您还必须传递数组中用作函数参数的元素数。

票数 4
EN

Stack Overflow用户

发布于 2022-07-13 19:06:01

,但是**argv如何与*argv[]相同,因为**argv是指向指针的指针。

因为,引用n1570 6.7.6.3p7 (强调我的):

参数声明为“数组的类型”,应调整为“限定指针到类型”,其中类型限定符(如果有的话)是在和数组类型派生中指定的。如果关键字静态也出现在数组类型派生的和数组类型派生中,那么对于对函数的每次调用,对应的实际参数的值应该提供对数组的第一个元素的访问,至少具有大小表达式指定的元素。

char *argv[]的每个元素都有char *类型,它是指向char的指针。

因此,根据6.7.6.3p7,char *数组将调整为指向char *的指针;即char *argv[] (指向chars的指针数组)将调整为char **argv (指向指向char的指针)。

为什么**argv包含10个不同的值,因为它是指向指针的指针?

因为它没有。仅仅因为它是指向指针的指针,就不会使它不同于任何其他指针(除了它们的大小、表示形式和对齐要求可能不同)。

下面的图表可能会帮助您理解实际发生的事情:

代码语言:javascript
复制
argv (points to the beginning of the array of pointer to chars.)
------------------+---------+---------+
    \             |         |         |
     \ argv[0]    |argv[1]  |argv[2]  | argv[3]
      \           |         |         |
       \          |         |         |
        V  char * V  char * V char *  V char *
        +---------+---------+---------+---------+
        |  0xf00  |  0xf0C  |  0xf13  |   NULL  |   (0xf0C and 0xf13 are the addresses of the first element of the strings passed as parameters to your program.)
        +---------+---------+---------+---------+
             |           |        |
             |           |        |
             |           |        |
             V           V        V
            "my_        "hello"  "world"            ("hello" and "world" are the parameters passed to your program.)
            program"
票数 1
EN

Stack Overflow用户

发布于 2022-07-13 17:43:21

"**“只是指指向指针的指针。数组本身作为指针工作。因此,我们可以说int **argv == *argv[] = argv。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72969633

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档