为什么将字符指针索引为整型是有意义的?

4
char *a = "apple";
printf("%s\n", a);  // fine
printf("%s\n", a[1]);  // compiler complains an int is being passed

为什么索引字符串指针会给我一个整数?我原以为它只是打印从位置一开始的字符串(实际上,当我使用&a[1]时确实发生了这种情况)。为什么我需要获取地址?
5个回答

13
那就是如何定义 [] 操作符 - 当 a 是一个 char * 时,a[1] 获取指向 a 指针指向字符的下一个字符(a[0] 是第一个字符)。
谜题的第二个部分是当作为函数可变长度参数列表的一部分传递时,char 值总是被提升为 int(或者很少是 unsigned int)。 a 相当于 &a[0],并从第一个字符开始打印 - 因此使用 &a[1] 从第二个字符开始打印是有意义的。您还可以只是使用 a + 1 - 这是完全等效的。
如果使用打印单个字符的 %c 转换说明符,则可以使用 a[1] 仅打印第二个字符:
printf("%c\n", a[1]);

6
表达式a[1]返回一个单个的字符,并且在表达式中被扩展为一个int
你可以使用%c来打印一个字符:
char *a = "apple";
printf("%c\n", a[1]);   // prints 'p'

您可以使用a+1来实现您想要的功能,例如:
printf("%s\n", a+1);    // prints 'pple'

另一种解释方式如下:
char *a2 = a+1;   // a2 points to 'pple'   
a[1] ≡ *(a+1)  ≡ *a2 

2

%s期望一个char*指针。仅使用Char会被解释为整数。 此外,a[1]会给你第二个元素,而不是第一个!


1
一个“char *指针”将会是一个“char **”(我敢打赌你是那些说ATM机器之类的人!) - Grant Peters
我们的自动取款机大多数情况下会显示“请稍等……” - Danvil

2

字符(即a [1]评估的类型)是整数,但printf()的“%s”格式化程序需要指针。请注意,检测到此错误的事实是某些编译器提供的扩展功能 - 它不是标准C的一部分。其他编译器可能会在运行时失败,可能会导致核心转储。


0
char *a = "bla"

a:是一个char*,在printf(...)中应该使用%s

a[1]等同于*(a+1),那么a[1]是一个char,在printf(...)中应该使用%c

&a[1]等同于&(*(a+1)),那么&a[1]是一个char*,在printf(...)中应该使用%s

这更像是一个指针问题。为了更好地理解指针的工作原理,请这样思考:

char *j;

j是一个char*
*j是一个char,等同于j[0]
*(j+1)是一个char,等同于j[1]
&(*j)是一个char*,等同于&j[0],等同于j
&j是一个char**

另一个例子:

char j**

j 是一个 char**
*j 是一个 char*
**j 是一个 char,等同于 *(*(j+0)+0),也等同于 j[0][0]
&j 是一个 char***

以此类推...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接