* p和*&p有什么区别

时间:2019-08-06 16:53:38

标签: c pointers printf operators

此代码有问题

int main()
{
 char *p = "example";
 printf("%s\n", *&p);   This is giving desired output
 printf("%s\n", *p);    Here giving segmentation fault
 return 0;
} 

我的问题是*&p和* p在这里有什么区别,以及它们在此代码中如何工作?

3 个答案:

答案 0 :(得分:2)

*&p实际上与p相同,并且类型为char *。

这些电话

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

产生相同的结果。

*p的类型为char,并且不能与格式说明符%s一起使用。否则,将其与格式说明符%s一起使用会导致未定义的行为

您可以改写

printf("%c\n", *p);
        ^^

请注意,并非总是*&p等同于p

例如,您可能无法将运算符&应用于non-lvalue

请考虑以下演示程序。

#include <stdio.h>

char * f( void )
{
    char *p = "Hello";

    return p;
}

int main(void) 
{
    printf( "%s\n", f() );
    // The statement below will not compile if to uncomment it
    // printf( "%s\n", *&f() );

    return 0;
}

在此程序中,从函数f返回的临时对象不是左值。

答案 1 :(得分:1)

[('album_group', 'album'), ('album_type', 'album'), ('artists_0_external_urls_spotify', 'https://open.spotify.com/artist/3WrFJ7ztbogyGnTHbHJFl2'), ('artists_0_href', 'https://api.spotify.com/v1/artists/3WrFJ7ztbogyGnTHbHJFl2'), ('artists_0_id', '3WrFJ7ztbogyGnTHbHJFl2'), ('artists_0_name', 'The Beatles'), ('artists_0_type', 'artist'), ('artists_0_uri', 'spotify:artist:3WrFJ7ztbogyGnTHbHJFl2'), ('available_markets_0', 'AD'), ('available_markets_1', 'AE'), ('images_1_width', 300), ('images_2_height', 64), ('images_2_url', 'https://i.scdn.co/image/f6e12b2ef70abf43d110e5c79810655c7c3fae98'), ('images_2_width', 64), ('name', 'The Beatles'), ('release_date', '2018-11-09'), ('release_date_precision', 'day')] 是变量&p的地址,类型为p。然后,值char **将取消引用此地址,从而为变量*&p提供类型为char *的l值。 p等同于*&p

p正在取消引用变量*p。这将给p所指向的字符提供类型char的l值,在这种情况下,该p位于字符串的开头。 (请注意,尽管它的类型为'e',但该值是只读的,因为char是指向字符串文字的指针。)

由于进行了默认类型转换,您最终将值p的{​​{1}}传递到int'e'将此值视为地址,因为您使用格式说明符printfprintf取消引用此指针,这是无效的内存访问。.

答案 2 :(得分:0)

在这种情况下:

1)   p   is a char pointer storing the address where is stored first 'e' letter in "example"
2)   *p  is the value stored at that address stored in p, that means the value 'e' 
3)   *&p = *(&p) is the value pointed by the address of p then *&p == p 

然后给出1,2,3:

printf("%s\n", *&p);  // is equivalent to printf("%s\n",p)      which is OK
printf("%s\n", *p);   // is equivalent to printf("%s\n",'e')    which is wrong 
                      // because 'e' is interpreted as an address