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,希望这能澄清任何混淆。:)