所以我知道字符串只是一个字符数组,连续地存储在计算机的内存中。
我还知道,为了找出字符串的位置,你只需要去第一个字符的位置作为它的连续字符,当程序或函数遇到\0字符时,字符串结束。
但我不明白的是
1.
char* s = "HI!";
字符串
它是否创建了一个4个字符的数组?或者它只是一个指向起始字符位置的指针?还是两者都有?
2.
char* name = "BEN";
printf("%c %c\n", *(name + 1), *name + 1);
型
为什么它们都给予两个不同的输出(E和C),而不是都给出E?
3条答案
按热度按时间qpgpyjmq1#
在这份宣言中
字符串
将创建两个实体。
第一个是字符串文字
"HI!"
,它具有静态存储时间和数组类型char[4]
。(在C++中,它有常量字符数组类型const char[4]
,与C相反。你可以使用printf来检查
型
这里字符数组被用作指针
s
的初始化器。在这种情况下,它被隐式转换为指针的第一个元素,指针s
指向数组的第一个元素的地址。至于这段代码
型
表达式
name + 1
的类型为char *
,并指向字符串文字"BEN"
的第二个字符(因此为'E'
),这是由于指针算术。解引用指针表达式(如*(name + 1)
)可以得到表达式所指向的字符串文字的符号。实际上,表达式*(name + 1)
与name[1]
相同,name[1]
与1[name]
相同。对于这个表达式
*name
,解引用指针name
可以得到字符串字面量的第一个符号'B'
。然后,将1加到符号( *name + 1 ), so the expression takes the value of the next symbol after
’B’, which is
’C’. The expression
(*name + 1)is equivalent to the expression
name[0]+1’的内部代码。使用下标运算符(如
name[1]
和name[0] + 1
)使表达式更加清晰。我想你会很有兴趣知道
printf
的调用可以只使用原始字符串字面量重写。一些例子:型
或者是
型
甚至
型
thigvfpy2#
但我不明白的是
第一个月
它是否创建了一个4个字符的数组?或者它只是一个指向起始字符位置的指针?还是两者都有?
在赋值的右侧,
= "HI!";
提供了一个常量字符数组(4个字符,包括空字符)。在哪里/如何为这4个字符分配内存并不重要。编译器可以自由选择"HI!"
的位置和生存时间。分配的左侧:
char *s =
在堆栈上声明一个局部指针,指向数组的第一个字符('H'
)char* name = "BEN";
个printf("%c %c\n", *(name + 1), *name + 1);
个为什么它们都给予两个不同的输出(E和C),而不是都给出E?
name
是指针。它指向该字符串中字母B
的地址。name+1
是指向该字符串中B
之后一个字符的指针,在本例中为E
。*name
是在name
所指向的地址处保存的值。换句话说,字符'B'
。*name + 1
与(*name) + 1
或'B' + 1
或'C'
相同。在这个表达式中,你是在给值加1,而不是地址。*(name + 1)
,计算为name
引用的字符串中的第二个字符。或者'E'
,正如您所期望的eiee3dmh3#
1.在
char* s = "HI!";
中,"HI!"
是一个 string literal。s
指向H
。字符串文字长度为4char
(包括终止字符\0
)。另一种(非惯用的)方式来看待它:...这里
s
是指向char[4]
的指针。型
(name + 1)
将1
添加到char*
name
,因此您将获得指向E
的指针。之后,您使用*
* 解引用 * 指针并获得E
。*name
取消引用指针,该指针指向B
,然后您将+ 1
指向它,使其成为C
。这和做这个是一样的:
型