理解 char array[] 和 string
Understanding char array[] and string
我是编程新手。我正在学习 C 作为我的第一门编程语言。我发现了一些奇怪的东西。
我了解到在 C 中我们可以将字符串表示为这样的字符序列(使用字符数组):
char status[10] = "Married";
我了解到这种方法的问题是我们必须在编译期间告诉 status
数组的大小。
但现在我知道我们可以使用 char
指针来表示 string
,例如 -
char status[10] = "Married";
char *strPtr;
strPtr = status;
我不是很理解。我的问题是 -
如何使用 [=15 获取索引 4 处的字符(即 Married 中的 i) =]?
在status
中char
数组表示的string
末尾有一个空字符([=17=]
)-M
-a
-r
-r
-i
-e
-d
-[=17=]
。所以通过使用空字符([=17=]
)我们可以理解字符串的结尾。当我们使用strPtr
时,如何理解string
的结尾?
char *strPtr;
strPtr = status;
现在你的指针 strPtr
指向数组中的第一个字符,你可以这样做
int i =0;
while( strPtr[i] != '[=11=]')
{
printf("%c ",strPtr[i]);
i++;
}
*strPtr
调用取消引用指针以获取存储在指针指向的位置的值。
记下
strPtr[4] = *(strPtr +4);
两者都会为您提供存储在数组索引 4 处的值。
注意指针和数组名的区别:
----------------------------------
| s | t | r | i | n | g | [=13=] |
----------------------------------
|
strPtr
status
strPtr ++
将使您的指针指向数组中的下一个元素。
| s | t | r | i | n | g | [=14=] |
----------------------------------
|
strPtr
而您不能对数组名称执行此操作
不允许 status++
因为 an array is not a modifiable lvalue.
字符串末尾的 '\0' 是为方便或安全而设计的无用附加组件。您可以像这样使用 'sizeof' 来告诉字符串最后一个字符:
char status[] = "Married";
size_t szLastCharstatus = sizeof(status) / sizeof(status[0]) - 2;
char chLastChar = status[szLastCharstatus];
详细解释:
sizeof(status)
Returns数组占用字节数
sizeof(status[0])
Returns 第一个元素占用的字节数(其余元素也是如此)。
这 2 个值之间的除法就是数组中元素的数量。现在要访问最后一个元素,我们需要减一 2 次,因为数组中的元素从零开始计数,而且字符串中的最后一个字符是 '\0'。
另请注意,数组不是指针,反之亦然。数组可以隐式转换为第一个元素的指针、常量大小和它们自己的类型。它们可以通过指针或值传递(第二个需要使用结构 hack)。
请注意,我使用的是“size_t”,它是存储一定大小数据的变量的类型定义。
表达式 status[10]
只是 *(status+10)
的语法糖。
[=12=]
终止在幕后用于检查结束,如果您自己实现了一些字符串处理程序,您也可以这样做,或者您可以忽略它并使用其他一些参数 size
与字符串一起给出,或者您可以(不要!)选择任何其他内容作为终止符号。
这不仅适用于 char
数组,或 'strings',C 数组只是一个指针,指向类似类型的连续块,并在编译时检查您的'array' 下标不超过声明时指定的 'end'。使用 *(array+offset)
表示法,您需要自己检查一下。
很高兴知道:
char status[10] = "Married";
只是 语法糖 相当于:
char status[10]; // allocate 10 Bytes on stack
status[0] = 'M';
status[1] = 'a';
...
status[6]= 'd';
status[7] = '[=11=]'; // same as 0
仅此而已。
另外:
char c = status[3];
与
完全相同
char c = *(status+3);
要获取索引 4 strPtr
处的字符,您只需使用 strPtr[4]
(这也适用于 status
)。
要在使用 strPtr
时获取字符串的结尾,您需要遍历字符并查找终止符 [=15=]
。这就是 printf("%s", strPtr)
在打印字符串时所做的(以及在解析 "%s"
表达式时所做的,这只是另一个字符串)。要在 C 语言的字符串中查找多个有效字符,您可以使用 strlen()
函数。哦,确保你不做这样的事情:
char a[3];
strcpy(a, "Hello!");
因为这会将 7 个字节写入一个三字节内存 space,因此会覆盖您不想覆盖的内容。
我要发表一个挑衅性的声明:可以这样想,C
没有字符串。 C
只有 char
个数组。尽管名称如此,char
实际上是一个 numeric 类型(例如,'A'
只是一种有趣的数字书写方式,通常是 65)。
char
的数组与 int
的数组或任何其他数字类型的数组并没有真正的区别;只是该语言提供了一些额外的方法来编写 char
类型的对象及其数组,并且对于如何解释存储在 char
数组作为字符串的表示。
char status[10]; // declares an array of `char` of length 10.
char *strPtr; // declare a pointer to `char`
strPtr = status; // make `strPtr` point to the first element of `status`
// Declare an array of 6 `char`, and initialize it.
char hello[6] = {'H', 'e', 'l', 'l', 'o', '[=10=]'};
// Shorthand notation for initializing an array of 6 `char` as above
char world[6] = "World";
// I want to store numeric data in this one!
char other[6] = {0, 1, 2, 3, 4, 5};
// "World" is shorthand for a constant array of 6 `char`. This is
// shorthand for telling the compiler to actually put that array in
// memory someplace, and initialize worldPtr to point to that memory.
const char *worldPtr = "World";
// This does the same thing as above. But it's still a *constant* array.
// You should *never* do this; it should be syntactically illegal to
// make a nonconstant `char*` to point to it. This is only allowed for
// historical reasons.
char *helloPtr = "Hello";
我是编程新手。我正在学习 C 作为我的第一门编程语言。我发现了一些奇怪的东西。
我了解到在 C 中我们可以将字符串表示为这样的字符序列(使用字符数组):
char status[10] = "Married";
我了解到这种方法的问题是我们必须在编译期间告诉 status
数组的大小。
但现在我知道我们可以使用 char
指针来表示 string
,例如 -
char status[10] = "Married";
char *strPtr;
strPtr = status;
我不是很理解。我的问题是 -
如何使用 [=15 获取索引 4 处的字符(即 Married 中的 i) =]?
在
status
中char
数组表示的string
末尾有一个空字符([=17=]
)-M
-a
-r
-r
-i
-e
-d
-[=17=]
。所以通过使用空字符([=17=]
)我们可以理解字符串的结尾。当我们使用strPtr
时,如何理解string
的结尾?
char *strPtr;
strPtr = status;
现在你的指针 strPtr
指向数组中的第一个字符,你可以这样做
int i =0;
while( strPtr[i] != '[=11=]')
{
printf("%c ",strPtr[i]);
i++;
}
*strPtr
调用取消引用指针以获取存储在指针指向的位置的值。
记下
strPtr[4] = *(strPtr +4);
两者都会为您提供存储在数组索引 4 处的值。
注意指针和数组名的区别:
----------------------------------
| s | t | r | i | n | g | [=13=] |
----------------------------------
|
strPtr
status
strPtr ++
将使您的指针指向数组中的下一个元素。
| s | t | r | i | n | g | [=14=] |
----------------------------------
|
strPtr
而您不能对数组名称执行此操作
不允许status++
因为 an array is not a modifiable lvalue.
字符串末尾的 '\0' 是为方便或安全而设计的无用附加组件。您可以像这样使用 'sizeof' 来告诉字符串最后一个字符:
char status[] = "Married";
size_t szLastCharstatus = sizeof(status) / sizeof(status[0]) - 2;
char chLastChar = status[szLastCharstatus];
详细解释:
sizeof(status)
Returns数组占用字节数
sizeof(status[0])
Returns 第一个元素占用的字节数(其余元素也是如此)。
这 2 个值之间的除法就是数组中元素的数量。现在要访问最后一个元素,我们需要减一 2 次,因为数组中的元素从零开始计数,而且字符串中的最后一个字符是 '\0'。
另请注意,数组不是指针,反之亦然。数组可以隐式转换为第一个元素的指针、常量大小和它们自己的类型。它们可以通过指针或值传递(第二个需要使用结构 hack)。
请注意,我使用的是“size_t”,它是存储一定大小数据的变量的类型定义。
表达式 status[10]
只是 *(status+10)
的语法糖。
[=12=]
终止在幕后用于检查结束,如果您自己实现了一些字符串处理程序,您也可以这样做,或者您可以忽略它并使用其他一些参数 size
与字符串一起给出,或者您可以(不要!)选择任何其他内容作为终止符号。
这不仅适用于 char
数组,或 'strings',C 数组只是一个指针,指向类似类型的连续块,并在编译时检查您的'array' 下标不超过声明时指定的 'end'。使用 *(array+offset)
表示法,您需要自己检查一下。
很高兴知道:
char status[10] = "Married";
只是 语法糖 相当于:
char status[10]; // allocate 10 Bytes on stack
status[0] = 'M';
status[1] = 'a';
...
status[6]= 'd';
status[7] = '[=11=]'; // same as 0
仅此而已。
另外:
char c = status[3];
与
完全相同char c = *(status+3);
要获取索引 4 strPtr
处的字符,您只需使用 strPtr[4]
(这也适用于 status
)。
要在使用 strPtr
时获取字符串的结尾,您需要遍历字符并查找终止符 [=15=]
。这就是 printf("%s", strPtr)
在打印字符串时所做的(以及在解析 "%s"
表达式时所做的,这只是另一个字符串)。要在 C 语言的字符串中查找多个有效字符,您可以使用 strlen()
函数。哦,确保你不做这样的事情:
char a[3];
strcpy(a, "Hello!");
因为这会将 7 个字节写入一个三字节内存 space,因此会覆盖您不想覆盖的内容。
我要发表一个挑衅性的声明:可以这样想,C
没有字符串。 C
只有 char
个数组。尽管名称如此,char
实际上是一个 numeric 类型(例如,'A'
只是一种有趣的数字书写方式,通常是 65)。
char
的数组与 int
的数组或任何其他数字类型的数组并没有真正的区别;只是该语言提供了一些额外的方法来编写 char
类型的对象及其数组,并且对于如何解释存储在 char
数组作为字符串的表示。
char status[10]; // declares an array of `char` of length 10.
char *strPtr; // declare a pointer to `char`
strPtr = status; // make `strPtr` point to the first element of `status`
// Declare an array of 6 `char`, and initialize it.
char hello[6] = {'H', 'e', 'l', 'l', 'o', '[=10=]'};
// Shorthand notation for initializing an array of 6 `char` as above
char world[6] = "World";
// I want to store numeric data in this one!
char other[6] = {0, 1, 2, 3, 4, 5};
// "World" is shorthand for a constant array of 6 `char`. This is
// shorthand for telling the compiler to actually put that array in
// memory someplace, and initialize worldPtr to point to that memory.
const char *worldPtr = "World";
// This does the same thing as above. But it's still a *constant* array.
// You should *never* do this; it should be syntactically illegal to
// make a nonconstant `char*` to point to it. This is only allowed for
// historical reasons.
char *helloPtr = "Hello";