为什么这个指针做作会引发错误?

问题描述

最近开始研究指针,想知道为什么char *n = “hii”; char *p = &n;显示错误

#指向地址#

#include<stdio.h>
#include<string.h>
#include<cs50.h>


int main(void)
   {
        char *n = "hii";
        /*why the below line is showing the error as it has no impact on the result,below the pointer p is pointing to address of n*/
        char *p = &n;
        printf("%i\n",&n);              

   }
  

解决方法

这段代码是怎么回事:

int main(void)
{
  // initializes n to point to the string literal "hii". So far so good
  char *n = "hii";  
  // This is problem. It assigned the address of n (type char**) to p (type char*).
  // Your compiler should warn you about this.
  char *p = &n;
  // This is a problem. Trying to print the address of n (type char**) using the
  // %i format specifier,which is used for int types. To printf an address,// use the %p format specifier and cast the argument to void*.
  printf("%i\n",&n);
}

您可以看到所有警告 here。如果您的编译器没有产生这些警告,请打开它们或使用更好的警告。以下是此代码的“修复”:

int main(void)
{
  // This is fine
  char *n = "hii";  
  // This assignment is valid since p and n are the same type (char*),and both
  // point to the string literal "hii"
  char *p = n;
  // This prints the _address_ of n
  printf("%p\n",(void*)&n);
  // This prints the address of where the string literal "hii" is stored
  printf("%p\n",(void*)p);
  // these print the actual string
  printf("%s\n",n);
  printf("%s\n",p);

  return 0;
}
,

"char * p = & n;"是一个错误,因为“&n”的类型是“char **”而不是“char *”,这是您从编译器收到的错误应该告诉您的。

,

如果您有一个 T 类型的对象,其中 T 是某种类型,例如

T n;

然后一个指向对象的指针看起来像

T *p = &n;

或者是一样的

T ( *p ) = &n;

现在想象一下,类型 T 被定义为类型 char * 的别名。

typedef char * T;

因此将别名替换为您将获得的定义类型

char *n;
char * ( *p ) = &n;

最后一个声明可以像这样重写

char **p = &n;

因此编译器为此声明发出错误

char *p = &n;

因为声明的对象具有 char * 类型,而初始化表达式具有 char ** 类型,并且没有从 char ** 类型到 char * 类型的隐式转换。

至于本声明

char *n = "hii";

那么字符串文字 "hii" 的类型为 char[4],内部表示为 { 'h','i','\0' }。表达式中使用的数组指示符在极少数例外情况下被转换为指向它们的第一个元素的指针。所以上面的声明等价于下面的

char *n = &"hii"[0];

至于这个printf

printf("%i\n",&n);

那么它没有意义并且具有未定义的行为,因为使用了不正确的带指针的转换说明符。

看来你的意思是以下

printf( "%s\n",n );

或/和

printf( "%s\n",*p );

也许

printf( "%p\n",( void * )&n );

printf( "%ti\n",( ptrdiff_t )&n );

这是一个演示程序。

#include <stdio.h>

int main(void) 
{
    char *n = "hii";
    char * ( *p ) = &n;
    
    printf( "%s\n",n );
    printf( "%s\n",*p );
    printf( "%p\n",( void * )&n );
    
    return 0;
}

程序输出可能看起来像

hii
hii
0x7ffdf28b86d8