【问题标题】:Assign pointer type to string type将指针类型分配给字符串类型
【发布时间】:2015-05-30 12:22:15
【问题描述】:

考虑到必须在 %p 中分配指针,我预计会出现编译错误,但是当我故意将指针分配给 %s 时,下面的代码不会给我错误。通过添加 & 符号,它应该生成数组的地址并将内存地址分配给 %p,而不是给出字符串的值。除非我取消引用指针,但我根本不取消引用指针,否则我从不在 printf 中的 my_pointer 前面放一个星号 *。

#include <stdio.h>
int main()
{
   char words[] = "Daddy\0Mommy\0Me\0";
   char *my_pointer;
   my_pointer = &words[0];

   printf("%s \n", my_pointer);
   return 0;

}

请看这个:

printf("%s \n", my_pointer);

我的理解是,*my_pointer(带星号*)应该给我字符串的值。 但是 my_pointer (不带星号)不应该给我字符串的值,而应该只给我内存地址,但是当我运行这段代码时,我得到了字符串的值,即使我没有不要把星号 * 放在前面。我希望我这次能说清楚。

【问题讨论】:

  • 您不能“分配”指向printf 格式说明符的指针; %s 想要一个 char*,这就是你给它的。
  • 我看不出问题出在哪里。 %s 考虑 const char* 参数

标签: c arrays pointers


【解决方案1】:

这里:

printf("%s \n", my_pointer);

%s,需要一个char*,因为my_pointer 是一个char*,它指向一个包含NUL 终止字符串的数组,printf 没有问题并且完全有效。 C11 标准的相关引用(强调我的):

7.21.6.1 fprintf 函数

[...]

  1. 转换说明符及其含义是:
    [...]
    s - 如果不存在 l 长度修饰符,参数应该是指向初始值的指针 字符类型数组的元素280) 数组中的字符是 写到(但不包括)终止空字符。如果 指定精度,写入的字节数不超过。如果 精度未指定或大于数组的大小,数组应 包含一个空字符。
    [...]

IMO,您在这里感到困惑:

考虑到必须在 %p 中分配指针,但是当我故意将指针分配给 %s 时,下面的代码不会给我错误

首先,%s%p 等是转换说明符。它们用于某些功能,例如printfscanf 等。
接下来,您是指定指针类型的人。所以在这里:

my_pointer = &words[0];

&amp;words[0]my_pointer 的类型为 char*。因此,分配这两个是完全有效的,因为它们属于同一类型。

【讨论】:

  • OT 但粗体文本似乎说 printf("%s\n", my_pointer+1); 将是 UB,因为该指针不指向初始元素!
  • 它并没有说它是UB,但你是对的。你觉得我应该怎么做或大胆?
  • 这是另一个实验,仍然与我的问题有关:int a; int *pointer_to_a; pointer_to_a = &a printf(“我的地址是 %d\n”, pointer_to_a );返回0;错误:%d 需要一个数学“int”参数(但为什么 %s 不会产生错误)
  • @CoolGuy 保持原样,语言律师讨论与该问题的主题无关
  • @user4951761 ,因为%d 期望int,但您传递了int*%s 需要 char*
【解决方案2】:

编译器会完全按照需要处理您的代码。

%s 格式说明符告诉printf() 期望const char * 作为相应的参数。然后它认为该指针是char 数组的第一个元素的地址,并打印它找到的每个char,直到遇到一个值为0 的'\0'

严格来说,编译器甚至不需要检查my_pointer 是否是或可以隐式转换为const char *。但是,大多数现代编译器(假设在编译时提供格式字符串)都会这样做。

【讨论】:

    【解决方案3】:

    在 c 中,数组名称也是指向第一个元素的指针,这意味着在您的情况下 words&amp;words[0] 当作为指针时,它们具有相同的值。

    而且,你将它分配给另一个相同类型的指针,所以这是合法的。

    关于c中的字符串,它只是一个以'\0'结尾的字符数组,其名称指针指向第一个字符。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-22
      • 2020-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多