C 在参数中使用指针时的类型转换

C 在参数中使用指针时的类型转换,c,pointers,printf,C,Pointers,Printf,这是密码 void test(char *bar) { printf("%s", bar); } int main(int x, char *argv[]) { test(argv[0]) return 0; } argv[]是指针数组,argv[0]获取数组中的第一个指针 在测试(char*whatever)中使用时,因为它是指针,所以我认为它会打印内存地址,而不是值。(要获取该值,您需要printf(“%s,*无论什么) 是否正在进行类型转换?我是否误解了指针的工

这是密码

void test(char *bar) {
    printf("%s", bar);
}

int main(int x, char *argv[]) {
    test(argv[0])
    return 0;
}
argv[]
是指针数组,
argv[0]
获取数组中的第一个指针

测试(char*whatever)
中使用时,因为它是指针,所以我认为它会打印内存地址,而不是值。(要获取该值,您需要
printf(“%s,*无论什么)


是否正在进行类型转换?我是否误解了指针的工作原理?

指向
printf
%s
格式说明符需要指向字符串的指针(即以空字节结尾的字符数组的第一个元素的地址)并打印该字符串

如果要打印指针值,请使用
%p
格式说明符

printf("%p", (void *)bar);
请注意,此处需要对
void*
指针进行强制转换,这是需要进行强制转换的少数几次之一。

“%s”
需要一个指针作为参数。它将开始读取指针的值,直到找到一个
'\0'
,并且每次转换一个字符


因此,它需要一个地址,但不打印地址,而是打印指针指向的字符串。

不,您弄错了,
%s
转换说明符需要以空结尾的字符数组的第一个元素的地址,并打印数组的内容,直到找到空终止符为止

引用
C11
章节§7.21.6.1

s

如果不存在
l
长度修饰符,则参数应为指向初始值的指针 字符类型数组的元素。数组中的280)个字符 写入(但不包括)终止空字符。[….]

事实上,如果你想打印一个地址,你必须

  • 使用
    %p
    转换说明符
  • 将参数强制转换为
    void*
参考,同一章

p

参数应为指向
void
的指针。指针的值为 在定义的实现中转换为打印字符序列 态度



在这种特定情况下,参数是指向字符的指针,如第§6.2.5章所述,是指向void的指针,是指向字符类型的指针,具有相同的表示和对齐要求,在这里可以互换,转换不是必须的,但如果是指向其他类型的指针(不兼容)必须在那里进行强制转换指针是一个包含内存地址的变量。因此,如果要打印内存地址,需要打印这样一个变量包含的值。可以使用printf中的任何数字格式来执行此操作,但指针有一个特殊的格式:
%p
。它是一种可移植的方式,可以将其强制转换为
(void*)
,尽管大多数系统不需要它


当您使用类似于
*指针
的东西时,您要求编译器获取该指针指向的内存中的第一个值。结果的类型取决于指针指向的对象。因此,在
char*pointer
中,该操作将返回一个字符。它完全等同于
指针[0]
。因此,在您的示例中,
printf(“%s”,*随便什么)
可能会崩溃,因为printf将尝试将第一个字符的值解释为字符串的地址。但是,您可以将此字符打印为以下内容:
printf(“%c”,*随便什么)

%s
需要一个
char*
类型的参数来打印它指向的空终止字符串。
bar
类型为
char*
,因此
*bar
将是
char
。它甚至押韵。康纳案例:OP关于打印地址的想法适用于对象指针,如
char*bar
printf(“%p\n”,(void*)some_object_pointer);
是一种很好的方法。如果指针指向函数,
printf(“%p\n”,(void*)some_function_pointer);
未指定为“工作”“。什么是以非空结尾的字符串?:)@SouravGhosh是一个等待发生的故障;)@不可知不可表达是的,或者。。。也许不是。@unknownable无法形容的嗯。。。我对此表示怀疑,因为不存在任何称为非空终止字符串的代码,所以不存在的代码不会生成任何可以进行segfault的二进制代码P@SouravGhosh我明白了。关于“…要打印地址,您必须…将参数转换为
void*
,”指向
void
的指针应具有与指向字符类型的指针相同的表示和对齐要求。“C11§6.2.5 28及其脚注”意味着互换性“。这显然意味着在这种情况下,
void*
cast(一个好主意)不是必须的,因为它们具有相同的表示形式,因此无法区分。@chux是的,对于字符指针,您是非常正确的。但总的来说,它并不适用于所有其他类型,不是吗?因此,在这种情况下,虽然不是必须的,但在其他情况下,它是必需的,并且是多余的,但也没有任何伤害,在这种情况下,我将更新。@chux Edited,希望这能澄清任何混淆。:)