首页 > 解决方案 > 我做了一个指针数组。名称和名称[0]有什么区别?

问题描述

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

我的代码---->

#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;
}

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

标签: arrayscstringmemory

解决方案


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

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 正式要求强制转换)。

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

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

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


推荐阅读