【问题标题】:Assigning array to pointer confusion将数组分配给指针混淆
【发布时间】:2013-07-01 11:07:20
【问题描述】:

我在 C 教程中找到的一行代码让我感到困惑。代码如下:

int main(int argc, char *argv[]){
   ...
   char **inputs = argv+1; // This is the confusing line
   ...
   return 0;
}

我无法理解如何将数组分配给这样的指针。如果有人能为我澄清这一点,我会很高兴。先谢谢了!

【问题讨论】:

  • 本例中没有数组。 inputs = &argv[1] 不那么混乱了吗?
  • Confusing pointers in C的可能重复
  • argv 是一个指针数组,argv 代表*argv[0] 的地址,所以我认为你完全可以这样分配它。
  • 但它不是只分配 argv[1] 而不是以 argv[1] 开头的整个 argv[] 吗?
  • 不,argv[1] 将等同于 *(argv+1),而不等同于 argv+1。换句话说,argv+1 是指向argv[1] 的指针。

标签: c arrays pointers variable-assignment


【解决方案1】:

argv 是一个指向字符串的数组指针,最后一个指针为空。 假设您的可执行文件名称是exe,并且您像这样运行它:

$ exe fist second 

那么argv就是:

                     +----------+ 
             argv---►| "exe"    | 
                     +----------+ 
         argv + 1---►| "first"  | 
                     +----------+ 
         argv + 2---►| "second" | 
                     +----------+      
         argv + 3---►|  null    |      
                     +----------+      

    * Notice last is null. 

所以char** input = argv + 1 指向作为第一个输入参数的“第一个”字符串。

如果您的打印argv[0]%s 输出将是"exe",这是您的可执行文件名称,如果您打印input[0]%s 输出将是"fisrt" 字符串。

注意:即使您不传递任何参数 intput 也会指向 NULL(有效地址)。
(这样做的目的是指向输入参数字符串,或者说跳过程序名称"exe"

我的以下代码示例及其输出集将帮助您理解。
code.c:

#include<stdio.h>
int main(int argc, char* argv[]){
    char** input = argv + 1;
    while(*input) /* run untill input-->null */
        printf("%s \n", *input++);
    return 1;
}

输出:

~$ gcc code.c  -Wall  -pedantic  -o exe 
~$ ./exe 
~$ ./exe first
first 
~$ ./exe first second
first 
second 

【讨论】:

    【解决方案2】:

    假设你执行这样的程序

    C:\Temp>myprog.exe hello world

    操作系统获取这些字符串并将它们放在一起,在一个空终止字符串数组中:

    { "myprog.exe", "hello", "world", NULL } 
    

    然后它调用main() 并将字符串的数量(3) 作为argc 传递给它,并将一个指向该数组中第一个字符串的指针传递给它。这个指针被称为argv,并且是char** 类型(char* argv[] 只是一种语法便利,在函数签名内部语义等价)

    但您希望 inputs 仅包含字符串“hello”和“world”,因此您使用此指针 argc,并指向下一个元素 - 向其添加一个:

    char **inputs = argv+1;
    

    现在inputs 指向{ "hello", "world", NULL }

    【讨论】:

      【解决方案3】:

      argv 在此上下文中不是数组;它是一个指针值。在函数参数声明的上下文中,T a[N]T a[] 等价于T *a;在所有三个中都将a 声明为指向T 的指针。

      但是,即使argv 是一个数组,仍然可以进行赋值。除非它是 sizeof 或一元 &amp; 运算符的操作数,否则“T 的 N 元素数组”类型的表达式将转换(“衰减”)为“指向 T 的指针”类型的表达式,表达式的值就是数组第一个元素的地址。

      【讨论】:

        【解决方案4】:

        注意

        char *argv[]
        

        是一个指针数组。数组声明,本身就是一个指针,argv 是一个指针。由于这里我们有一个指针数组,所以argv是一个指向指针的指针,就像char **inputs一样,因此

        char **inputs = argv+1;
        

        只是说输入等于指针 argv 加一,因为 argv+1 也是一个指针,所以你有一个指向指针的指针。

        【讨论】:

        • 如果有人给我的答案打分,请解释原因。谢谢。
        • 不是我,但你的解释有些不妥。数组声明不是指针,但在函数参数中使用时会隐式转换为指针。
        【解决方案5】:

        函数参数中使用的数组总是被转换为指针。

        所以char *argv[]char **argv 相同。

        argv[0] 包含程序名称(或用于调用程序的名称,在多重链接文件的情况下),因此argv+1 只是程序的参数。

        【讨论】:

          【解决方案6】:

          数组名是指向数组第一个元素的常量指针

          更多:- http://forum.allaboutcircuits.com/showthread.php?t=56256

          【讨论】:

          • 不是真的,在这里也无关紧要:这段代码中是 no 数组。
          • 问题是“如何将数组分配给指针”,这就是可能的解释,即如果数组名称是一个常量指针,那么它可以分配给一个指针,ELAZAR跨度>
          • 这是一个解释,但是一个准确的解释。而且这里没有数组,所以也无关紧要。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-11-18
          • 1970-01-01
          • 1970-01-01
          • 2018-10-06
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多