所以我知道字符串只是一个连续存储在计算机内存中的字符array.

我还知道,为了找出字符串的位置,您只需转到第一个字符的位置作为它的连续字符,当程序或函数遇到\0字符时,字符串结束.

但我不明白的是:

  1. _

它是否创建4个字符的数组?或者它只是一个指向起始字符位置的指针?还是两者兼而有之?

2.

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

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

推荐答案

在本声明中

char* s = "HI!";

创建了两个实体.

第一个是字符串文本"HI!",它具有静态存储持续时间和数组类型char[4].(在C++中,与C相反,它具有常量字符数组const char[4]的类型.)

您可以通过这个print tf调用来进行判断

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

该字符数组用作指针s的初始化器.在这种情况下,它被隐式地转换为指向其第一个元素的指针,并且第一个元素的地址被分配给指针s.

至于这段代码片段

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

则由于指针算法,类型为char *的表达式name + 1指向字符串文字"BEN"的第二个字符(即指向'E').取消引用类似于*(name + 1)的指针表达式,您将获得该表达式所指向的字符串的符号.实际上,表达式*(name + 1)name[1]相同,即与1[name]相同.:)

对于这个表达式*name,然后解除对指针name的引用,得到字符串文字的第一个符号'B'.并且将1( *name + 1 )添加到该符号的内部代码.结果,该表达式产生'B'之后的下一个符号,即'C'.公式( *name + 1 )等同于公式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);

C++相关问答推荐

是否可以在C中进行D3 D12申请?

为什么GCC可以调用未定义的函数?

当execvp在C函数中失败时杀死子进程

C lang:当我try 将3个或更多元素写入数组时,出现总线错误

VS代码';S C/C++扩展称C23真关键字和假关键字未定义

GCC创建应用于移动项的单独位掩码的目的是什么?

如何在下面的C代码中正确管理内存?

用gcc-msse 2编译的C程序包含AVX 1指令

如何使用C++在控制台中以彩色打印被阻止的客户端

编译器如何处理具有更复杂值的枚举?

在vfork()之后,链接器如何在不 destruct 父内存的情况下解析execve()?

在运行时判断C/C++指针是否指向只读内存(在Linux操作系统中)

GETS()在C++中重复它前面的行

在C中打印指针本身

与指针的原始C数组或C++向量<;向量<;双>>;

在列表中查找素数

使用 _Atomic float 时,MSVC 编译的代码会命中调试断言

如何正确探测平台设备?

C 中 struct 体自赋值是否安全?特别是如果一侧是指向 struct 的指针?

int 与 size_t 与 long