c语言中指针地址的证明

c语言中指针地址的证明,c,pointers,c-strings,string-literals,C,Pointers,C Strings,String Literals,试图理解指针 下面,我只想向自己证明下面的 str地址(&str)=str2指向的地址(str2) str2的实际地址内存有所不同(&str2) 然而,当我在下面编译时,我得到seg错误,它说“morePointers.c:6:56:warning:format指定类型'int',但参数的类型为'char*'[-Wformat]” 我如何在代码中证明这一点的同时纠正这一点 int main(int argc, char** argv) { char str = "goodbye";

试图理解指针

下面,我只想向自己证明下面的

str地址(&str)=str2指向的地址(str2) str2的实际地址内存有所不同(&str2)

然而,当我在下面编译时,我得到seg错误,它说“morePointers.c:6:56:warning:format指定类型'int',但参数的类型为'char*'[-Wformat]”

我如何在代码中证明这一点的同时纠正这一点

int main(int argc, char** argv) {
    char str = "goodbye";
    char *str2 = str;

    printf("%d %d %s %d %d\n", &str2, str2, str2, str, &str);
}

这将是正确的代码:

#include <stdio.h>

int main(int argc, char** argv) {
  char *str = "goodbye";  // a '*' was missing in your code
  char* str2 = str;

  // you need to use %p for pointer values
  // and for each argument for a %p you need to cast to (void*)

  printf("%p %p %s %p %p\n", (void*)&str2, (void*)str2, str2, (void*)str, (void*)&str);
}
此代码在64位系统上的典型可能输出

00FFF710 00996B30 goodbye 00996B30 00FFF71C
0x7ffc8f58ada0 0x555ba93f6004 goodbye 0x555ba93f6004 0x7ffc8f58ad98
在本声明中

char str = "goodbye";
char *str2 = str;
您正试图使用初始化表达式中类型为
char*
的字符串文本初始化类型为
char
的对象

你必须写作

char *str = "goodbye"; 
而不是这个声明

char str = "goodbye";
char *str2 = str;
看来你是说

char **str2 = &str;
也就是说,您正在创建指向指针
str
的指针

因此,解除对指针str2的引用,您将获得存储在指针str中的值,该值是字符串literal的第一个字符的地址

这是一个演示程序

#include <stdio.h>

int main(void) 
{
    char *str = "goodbye";
    char **str2 = &str;

    printf( "str = %p is the same as *str2 = %p\n", ( void * )str, ( void * )*str2 );
    printf( "str2 = %p contains the address of str (&str) = %p\n", ( void *)str2, ( void *)&str );

    printf( "The string literal pointed to by str = %s\n"
            "is the same as pointed to by *str2 = %s\n",
            str, *str2 );

    return 0;
}

请注意,将转换说明符
%d
与指针一起使用会导致未定义的行为。

使用
%p
打印指针。如果你真的想要一些证据考虑使用,这是你的实际代码吗?你没有
#include
s吗?是的,它们很重要。
char str=“再见”
这是打字错误吗?必须是
char*str
char-str[]
节省时间。“当我编译时”当然没有启用所有警告。将它们全部打开,可以更快地反馈堆栈溢出。“对于
%p
的每个参数,您需要强制转换为
(void*)
”-为什么<代码>printf(“%p%p%s%p%p\n”、&str2、str2、str2、str和str)也适用于启用了
-Wall
-Werror
标志的情况。@roberts支持smonicacellio,因为
%p
需要一个
void*
参数,其他任何行为都是未定义的(C11 7.1.4):“如果函数的参数具有[…]类型(升级后)参数个数可变的函数不希望出现这种情况,行为是未定义的。“和(C11 7.21.6.1
fprintf
函数):“
p
参数应是指向
void
的指针。指针的值以实现定义的方式转换为打印字符序列。”@Roberts SupportsMonicacellio通常在没有
(void*)
强制转换的情况下工作,但标准要求它必须是
void*
,请参见以下内容:。但说实话,我真的不明白为什么在没有演员阵容的情况下传递一个指针会导致UB.@S.S.Anne,这是一个错误OK@RobertSsupportsMonicaCellio是 啊我希望C委员会能在C20中改变这一点。我正在复习这一点。。顺便说一句,什么是%p?我在哪里可以找到有关此的文档?@user3502374它是指定给输出指针的转换说明符。