【问题标题】:I made array of pointer. What is difference between names and names[0]?我做了一个指针数组。名称和名称[0]有什么区别?
【发布时间】:2021-11-13 06:47:42
【问题描述】:

https://i.stack.imgur.com/7Fgkp.jpg output)这是输出图片的链接

我的代码---->

#include <stdio.h>
 
const int MAX = 5;
 
int main () {

   char *names[] = {
      "Zara Ali",
      "Hina Ali",
      "Nuha Ali",
      "Sara Ali",
      "Zara Ali"
   };
   
   int i = 0;

   for ( i = 0; i < MAX; i++) {
      printf("Value of *names[%d] = %c char\n", i, *names[i] );
   }
  
   for ( i = 0; i < MAX; i++) {
      printf("Value of *(names+%d) = %d\n", i, *(names+i) );
   }
   for ( i = 0; i < MAX; i++) {
      printf("Value of names[%d] = %d\n", i, names[i] );
   }
   for ( i = 0; i < MAX; i++) {
      printf("Value of *(names+%d) = %s\n", i, *(names+i) );
   }
   for ( i = 0; i < MAX; i++) {
      printf("Value of names[%d] = %s\n", i, names[i] );
   }
   
 
   
   printf("Value of names = %d\n",names );
   printf("Value of names+1 = %d\n",names+1 );
   return 0;
}

namesnames[0] 的值不同时。 我在哪里可以正确学习这个主题。 问题是“我不知道..哪个变量存储了哪个地址或值”。

【问题讨论】:

  • 请在问题中包含任何代码,避免代码或链接的图像,真的很难复制。
  • 欢迎来到 stackoverflow.com。请花一些时间阅读the help pages,尤其是名为"What topics can I ask about here?""What types of questions should I avoid asking?" 的部分。也请使用tour 并阅读有关How to Ask 的好问题。最后请阅读this question checklist,并学习如何edit您的问题以改进它们。
  • 顺便说一下,对于任何数组(或指针)names 和索引i,表达式*(names + i)恰好等于names[i]。此外,当使用没有索引的数组时,例如names 然后它将衰减指向指向其第一个元素的指针。所以names&amp;names[0] 是一样的。
  • @Someprogrammerdude (names and names+1) 他们的地址之间的差异是 8... 为什么不是 9. names[0] 的值 = 4196188 names[1] 的值 = 4196197 是地址吗?或者是其他东西。这里的区别是 9
  • @Sahil 你有一个指针数组。每个元素的大小(以字节为单位)为char *的大小,即sizeof(char *)。一个指针的大小是8 告诉我你在一个 64 位系统上,每个指针是 64 位或 8 个字节。

标签: arrays c string memory


【解决方案1】:

图片会有所帮助:

      char *                char
+–––+                +–––+
|   | names[0] ––––> |'Z'| names[0][0]
+–––+                +–––+
|   | names[1] ––+   |'a'| names[0][1]
+–––+            |   +–––+
 ...             |    ...
                 |   +–––+
                 |   |'i'| names[0][7]
                 |   +–––+
                 |   | 0 | names[0][8]
                 |   +–––+
                 |
                 |   +–––+
                 +-> |'H'| names[1][0]
                     +–––+
                     |'i'| names[1][1]
                     +–––+
                      ...
                     +–––+
                     |'i'| names[1][7]
                     +–––+
                     | 0 | names[1][8]
                     +———+

每个字符串字面量("Zara Ali""Hina Ali" 等)都以零结尾数组的形式存储在内存中某处的char(字符串字面量的存储方式使其在程序)。

每个names[i] 存储每个字符串文字的第一个字符的地址。

表达式 names 的类型为“指向char 的指针”(char **)1 并计算为第一个元素的地址names 数组 - 相当于写 &amp;names[0]。表达式 names[0] 计算为 "Zara Ali" 字符串文字中第一个字符的地址 - 与编写 &amp;names[0][0] 相同。

使用%p 转换说明符来打印指针值而不是%d - %d 期望其对应的参数具有int 类型,并且指针不是整数:

printf( "Value of names[%d] = %p\n", i, (void *) names[i] );

printf( "Value of names = %p\n", (void *) names );
printf( "Value of names+1 = %p\n", (void *) (names + 1) );

这几乎是您唯一需要在 C 中显式转换指向 void * 的指针。


  1. 除非它是 sizeof 或一元 &amp; 运算符的操作数,或者除非它是用于在声明中初始化字符类型数组的字符串字面量,否则为 表达式 类型为“T 的 N 元素数组”将被转换或“衰减”为“指向 T 的指针”类型的表达式,表达式的值将是第一个地址数组的元素。

    变量 names 被声明为指向char (char *[]) 的指针数组。但是,当names 出现在表达式中并且它不是sizeof 或一元&amp; 的操作数时,它会转换为类型“指向char 的指针(char **)的指针。

    这就是为什么nameschar * 的数组的原因——每个字符串文字本身就是一个数组表达式(“char 的9 元素数组”),但在这种情况下“衰减”以键入char *

【讨论】:

  • 我正在做 3 到 4 个月的编码......我很感激能从你那里得到如此令人满意和概念清晰的答案。??
【解决方案2】:

首先,下面这行是错误的:

printf("Value of names = %d\n",names );

使用%d 格式说明符不是打印指针的正确方法。虽然它可以在大多数 32 位平台上工作(在这些平台上,指针的大小通常为 4),但它肯定不能在 64 位平台上正常工作(在这些平台上,指针的大小通常为 8)。

打印指针的正确方法是使用%p 格式说明符并将指针转换为void*

printf( "Value of names = %p\n", (void*)names );

在大多数平台上,void* 的强制转换不是必需的,因此您可以放心地省略它(即使 ISO C 正式要求强制转换)。

正如在 cmets 部分中已经指出的那样,编写 names[i] 根据定义等同于编写 *(names+i)

namesnames+1 之间的差异之所以为8,是因为在这两个表达式中,数组namesdecays 指向指向其第一个元素的指针,即指向&amp;names[0]。将指针增加1 不会将地址增加1,而是使其指向下一个元素。由于数组names 的每个元素都是一个指针,并且在您的平台上似乎具有8 的大小(您似乎在具有64 位指针的64 位平台上),地址增加@987654342 @ 当您将指针增加1 时。

在您的图片中,您似乎也在问为什么*(names+0)*(names+1) 之间的区别是9。表达式*(names+0) 等价于names[0],它是指向string literal "Zara Ali" 的指针。表达式*(names+1) 等价于names[1],它是指向字符串文字"Hina Ali" 的指针。因此,这两个表达式都表示字符串文字的地址,即编译器存储某个字符串文字的地址。编译器存储字符串文字的位置由编译器决定,编译器的行为可能会有所不同。但是,在这种情况下,编译器似乎决定将两个字符串文字彼此相邻地存储在内存中。字符串文字"Zara Ali" 的长度为9(包括空终止字符),这就解释了为什么地址的差异是9

【讨论】:

  • 非常感谢先生
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-11
  • 1970-01-01
  • 2015-05-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多