【问题标题】:What is the logic behind the below example of array and pointer?下面的数组和指针示例背后的逻辑是什么?
【发布时间】:2014-09-28 08:49:12
【问题描述】:

我无法弄清楚数组和指针的工作方式之间的区别以及它们如何相互关联。

代码:

char str[]="banti is a nice girl";
    char *ptr=str+6;
    printf("%s",ptr)

输出:is a nice girl

  1. 我没有在 printf 语句中使用解引用运算符,
    为什么它给我的是数组的内容,而不是地址?

  2. 当我写 char*ptr=str[6] 时,我得到 Error: cannot convert char to char* -
    这个错误是什么意思?

  3. 是不是要引用一个数组地址,我们需要放&str[6],但我们不需要放str+6?如果是这样,其背后的逻辑是什么?

【问题讨论】:

  • 这段代码无法编译,第一行缺少*
  • str[6]char,而不是 char *str 表示str 的第一个元素的地址已被评估为指针。
  • 我建议你在尝试学习 C 之前先学习 C++。

标签: c++ c arrays pointers printf


【解决方案1】:

当您使用如下代码时

char str[]="banti is a nice girl";
printf("%s",str);

然后将数组 str 转换为指向其第一个 char * 类型元素的指针

所以上面的代码等价于

char str[]="banti is a nice girl";
char *ptr=str;
printf("%s",ptr);

当函数 printf 处理格式说明符 %s 时,它将相应的参数视为 char * 类型的指针,并输出指针指向的所有字符,直到遇到终止零。

所以这段代码被剪掉了

char str[]="banti is a nice girl";
char *ptr=str + 6;
printf("%s",ptr);

您只需将指针右移到 6 个字符,函数 printf 就会开始从 str + 6 输出字符

【讨论】:

    【解决方案2】:

    在您的代码中,str 的类型为 char[21]。也就是说,一个包含banti is a nice girl 中的所有字符加上nul 终止符\0 的数组。现在,在 C 和 C++ 中,数组可以很容易地衰减为指向其第一个元素的指针。这发生在这个表达式中:

    str + 6
    

    在这里,str 可以理解为 &str[0]。将其递增 6 会得到指向 str 中第 7 位的指针(str[6] 的地址),即 is 中的 iptr 被初始化为保存该指针的值。当您将 ptr 传递给 printf 时,它会从该位置开始打印字符串,直到 nul 终止符。

    现在,我没有在我的 printf 语句中使用解引用运算符,为什么它给我的是数组的上下文,而不是地址?

    因为您告诉printf,您正在向它传递一个指向以 nul 结尾的字符串的指针,以便它可以打印出该字符串。这就是"%s" 的意思。 printf 知道如何打印以 nul 结尾的字符串。它打印字符,直到找到 nul 终止符 \0

    如果我写 char*ptr=str[6]; 为什么会出错错误:无法将 char 转换为 char*;

    因为str[6]char,并且您不能从char 初始化char*。这就是编译器错误告诉你的。

    【讨论】:

    • 或许可以参考一些更多的解释:cs.umd.edu/class/sum2003/cmsc311/Notes/BitOp/pointer.html
    • 让我们说 int str[2,3,4,5,6,7,8]; int *ptr=str+4;现在要打印值“6”,我会写 printf("%d",*ptr) 而不是 printf("%d",ptr) 我们在字符串的情况下所做的以上问题。为什么这里的语法有所不同,为什么我的输出不是我上面的问题中发生的 6 7 8 ?
    • @Rishab 不同之处在于printf 假设您在使用%s 并传递char* 时传递一个以空结尾的字符串。它打印字符,直到找到一个 nul 终止符。
    • 所以,我们在获取数组字符串的上下文时使用不使用解引用运算符 (*)(因为我们使用 printf("%s",ptr) ),但我们必须在获取时使用 *数组 int 的上下文(因为我们使用 printf("%d",*ptr) 来获取特定值)?背后的原因?
    • @Rishab "%d" 如果是有符号整数,而不是指针。所以当printf 期望int 时传递指针是没有意义的。尝试阅读some documentation
    【解决方案3】:

    它将str 基地址推进6,现在将指向is a nice girl

    试试这个:

    main()
    {
    
           char str[]="banti is a nice girl";
           char *ptr=&str[6];
           printf("%s",ptr);
    }
    

    尝试打印:

     printf("%d",str[6]);  // return first character ascii value
       printf("\n%d",(str+6)); // return the address 
       printf("\n%d",&str[6]); // return the address
    

    &str[6](str+6)都是地址,str[6]是字符串的第一个字符。

    【讨论】:

    • 但是为什么会这样。请再次阅读上面的问题。
    • 您应该指定该位置的地址。
    • ASCII 可能不是目标字符集/编码。数组str 是一个字节大小的代码单元序列。未指定哪个字符集的哪个编码。就像是 Windows-1252 或等效或 Unicode/UTF-8。
    【解决方案4】:

    您收到的错误

    Why it gives error if I write char*ptr=str[6]; Error: cannot convert char to char*;
    

    那是因为你正在做这样的事情

    char* str = *(str + 6);
    

    如您所知,str[6] 将被计算为 *(str + 6),它等于 ii 您正试图将其存储在 char 指针 str.. 中。

    【讨论】:

      【解决方案5】:

      我几乎可以肯定你根本不懂 C 和 C++ 中的数组和指针。

      数组如何在 C 和 C++ 中工作?

      char str[]="banti is a nice girl";
      

      这一行创建了一个字符数组。

      ['b','a','n','t','i',' ','i','s',' ','a',' ','n','i','c','e',' ','g','i','r','l','\0']
        ^
       str
      

      数组是您在[] 之间拥有的,它存储在内存中的某处;
      可以通过指针str访问。

      str+6 表示 指针 str6 元素移到它所指向的元素之后。

        0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19   20
      {'b','a','n','t','i',' ','i','s',' ','a',' ','n','i','c','e',' ','g','i','r','l','\0'}
        ^                       ^
       str                    str+6
      

      str[6] 表示*(str+6),表示获取str+6 的值

      strchar*str+6也是char*,但*(str+6)char,等于'i'
      char不能隐式转换为char* .

      printf, 当你在格式字符串中给它%s 时,它是什么意思?

      它希望你给它char*指向char的指针);
      它会复制您提供的char*(让我们将副本命名为copy),然后执行以下操作:

      while( (*copy)!='\0'){
          //print out *copy;
          ++copy;
      }
      

      因此,它在数组中的char 之后打印char,直到遇到'\0'

      【讨论】:

        猜你喜欢
        • 2018-06-18
        • 1970-01-01
        • 1970-01-01
        • 2022-08-14
        • 2014-05-06
        • 2020-04-04
        • 2017-10-17
        • 1970-01-01
        • 2020-09-08
        相关资源
        最近更新 更多