无法理解CS50中的char* 和string

hrysbysz  于 2023-08-03  发布在  其他
关注(0)|答案(3)|浏览(124)

所以我知道字符串只是一个字符数组,连续地存储在计算机的内存中。
我还知道,为了找出字符串的位置,你只需要去第一个字符的位置作为它的连续字符,当程序或函数遇到\0字符时,字符串结束。
但我不明白的是
1.

char* s = "HI!";

字符串
它是否创建了一个4个字符的数组?或者它只是一个指向起始字符位置的指针?还是两者都有?
2.

char* name = "BEN";
    printf("%c %c\n", *(name + 1), *name + 1);


为什么它们都给予两个不同的输出(E和C),而不是都给出E?

qpgpyjmq

qpgpyjmq1#

在这份宣言中

char* s = "HI!";

字符串
将创建两个实体。
第一个是字符串文字"HI!",它具有静态存储时间和数组类型char[4]。(在C++中,它有常量字符数组类型const char[4],与C相反。
你可以使用printf来检查

printf( "sizeof( \"HI!\" ) = %zu\n", sizeof( "HI!" ) );


这里字符数组被用作指针s的初始化器。在这种情况下,它被隐式转换为指针的第一个元素,指针s指向数组的第一个元素的地址。
至于这段代码

char* name = "BEN";
printf("%c %c\n", *(name + 1), *name + 1);


表达式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的调用可以只使用原始字符串字面量重写。一些例子:

printf("%c %c\n", *( "BEN" + 1), *"BEN" + 1);


或者是

printf("%c %c\n", "BEN"[1], "BEN"[0] + 1);


甚至

printf("%c %c\n", 1["BEN"], 0["BEN"] + 1);

thigvfpy

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',正如您所期望的
eiee3dmh

eiee3dmh3#

1.在char* s = "HI!";中,"HI!"是一个 string literals指向H。字符串文字长度为4 char(包括终止字符\0)。另一种(非惯用的)方式来看待它:

char(*s)[4] = &"HI!";

...这里s是指向char[4]的指针。

  • 在第二个例子中,它是关于你做事情的顺序,运算符优先级。
char* name = "BEN";
printf("%c %c\n", *(name + 1), *name + 1);

  • (name + 1)1添加到char*name,因此您将获得指向E的指针。之后,您使用* * 解引用 * 指针并获得E
  • *name取消引用指针,该指针指向B,然后您将+ 1指向它,使其成为C

这和做这个是一样的:

printf("%c %c\n", name[1], name[0] + 1);

相关问题