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

时间:2017-08-18 20:50:47

标签: c pointers printf

这是代码

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

int main(int x, char *argv[]) {
    test(argv[0])
    return 0;
}

argv[]是一个指针数组,argv[0]获取数组中的第一个指针。

test(char *whatever)中使用时,因为它是一个指针,我认为它会打印内存地址,而不是值。 (为了获得价值,你会printf("%s,*whatever)

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

4 个答案:

答案 0 :(得分:4)

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

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

printf("%p", (void *)bar);

请注意,此处需要转换为void *指针,这是需要进行此类转换的少数几次之一。

答案 1 :(得分:3)

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

引用C11章节§7.21.6.1

  

s

     

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

的确,如果你想打印一个地址,你必须

  • 使用%p转换说明符
  • 将参数投射到void *

参考,同章,

  

p

     

参数应是指向void的指针。指针的值是   转换为一系列打印字符,在实现定义中   方式。

在这个特定的情况下,参数是一个指向char的指针,如章节§6.2.5中所述,指向void的指针和指向具有相同表示和对齐要求的字符类型的指针,它在这里是可以互换的并且强制转换不是必须的,但是如果指向其他类型的指针(不兼容)必须有强制转换

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

指针 包含内存地址的变量。因此,如果要打印内存地址,则需要打印此变量包含的值。您可以在printf中使用任何数字格式来执行此操作,但是有一个特殊的指针:%p。虽然在大多数系统中都不需要它,但它是一种将其转换为(void*)的可移植方式。

当你使用*pointer这样的东西时,你要求编译器获取该指针所指向的内存中的第一个值。结果的类型取决于指向的指针。因此,在char *pointer中,操作将返回一个char。它绝对等同于pointer[0]。因此,在您的示例中,printf("%s", *whatever)可能会崩溃,因为printf将尝试将第一个字符的值解释为字符串的地址。但是,您可以按以下方式打印此字符:printf("%c", *whatever)