简体   繁体   English

理解char数组[]和字符串

[英]Understanding char array[] and string

I am new to programming. 我是编程新手。 I am learning C as my first programming language. 我正在学习C作为我的第一门编程语言。 I found something strange to understand. 我发现一些奇怪的东西要理解。

I have learnt that in C we can represent a String as a sequence of characters like this (using a char array): 我已经了解到在C中我们可以将String表示为像这样的字符序列(使用char数组):

char status[10] = "Married";   

I have learnt that the problem of this approach is that we have to tell the size of the status array during compilation. 我了解到这种方法的问题是我们必须在编译期间告诉status数组的大小。

But now I have learned we can use a char pointer to denote an string like - 但现在我已经学会了,我们可以用一个char指针来表示一个string喜欢-

char status[10] = "Married";
char *strPtr;
strPtr = status;

I don't understand it properly. 我不理解它。 My questions are - 我的问题是 -

  1. How can I get char at index 4 (that is i in Married ) using the strPtr ? 如何使用strPtr在索引4(即Married )获取char?

  2. In status there is a null character ( \\0 ) at the end of the string represented by the char array - M - a - r - r - i - e - d - \\0 . status ,在char数组表示的string末尾有一个空字符( \\0 ) - M - a - r - r - i - e - d - \\0 So by using the null character ( \\0 ) we can understand the end of the string. 因此,通过使用空字符( \\0 ),我们可以理解字符串的结尾。 When we use strPtr , how can we understand the end of the string ? 当我们使用strPtr ,我们如何理解string

char *strPtr;
strPtr = status;

Now your pointer strPtr is pointing to the first character in the array and you can do 现在你的指针strPtr指向数组中的第一个字符,你可以这样做

int i =0;
while( strPtr[i] != '\0')
{
  printf("%c ",strPtr[i]);
  i++;
}

*strPtr is called dereferencing the pointer to get the value stored in the location the pointer is pointing to. *strPtr被称为取消引用指针以获取存储在指针指向的位置的值。

Make a note that 记下来

strPtr[4] = *(strPtr +4); 

Both will get you the value stored at the index 4 of the array. 两者都将获得存储在数组索引4处的值。

Note the difference between a pointer and a array name: 注意指针和数组名称之间的区别:

----------------------------------
| s  | t  | r  | i  | n | g | \0 |
----------------------------------
  |
strPtr
status

strPtr ++ will make your pointer point to the next element in the array. strPtr ++将使您的指针指向数组中的下一个元素。

| s  | t  | r  | i  | n | g | \0 |
----------------------------------
       |
      strPtr

Whereas you can't do this for the array name 而您不能为阵列名称执行此操作

status++ is not allowed because an array is not a modifiable lvalue . 不允许使用status++因为数组不是可修改的左值

Good to know: 很高兴知道:

char status[10] = "Married";

is just syntax sugar for the equivalent: 只是等价的语法糖

char status[10]; // allocate 10 Bytes on stack
status[0] = 'M';
status[1] = 'a';
...
status[6]= 'd';
status[7] = '\0'; // same as 0

Nothing more, nothing less. 没有更多,没有更少。

Also: 也:

char c = status[3];

is exactly the same as 与... 完全相同

char c = *(status+3);

The expression status[10] is mere syntactic sugar for *(status+10) . 表达status[10]仅仅是*(status+10)语法糖。

The \\0 termination is used under the hood to check for the end, if you were implementing some string-handler yourself you could do this too, or you could ignore it and use some other parameter size given with the string, or you could (don't!) choose anything else as the termination symbol. 在引擎盖下使用\\0终止来检查结束,如果你自己实现了一些字符串处理程序,你也可以这样做,或者你可以忽略它并使用字符串给出的其他参数size ,或者你可以(不要!)选择其他任何东西作为终止符号。

This isn't just true of char arrays, or 'strings', a C array is just a pointer to a contiguous block of like-typed stuff with a compile-time check that your 'array' subscripts don't go beyond the 'end' specified at time of declaration. 这不仅仅是char数组或'字符串',C数组只是指向类似类型的连续块的指针,编译时检查你的'数组'下标不会超出'在声明时指定的“结束”。 With the *(array+offset) notation, you need to check this for yourself. 使用*(array+offset)表示法,您需要自己检查。

To get character at index 4 strPtr , you just use strPtr[4] (this also work for status ). 要在索引4 strPtr处获取字符,只需使用strPtr[4] (这也适用于status )。

To get the end of the string when using strPtr , you need to go through the characters and look for the terminating \\0 . 要在使用strPtr时获取字符串的strPtr ,您需要遍历字符并查找终止\\0 This is what printf("%s", strPtr) does when it prints the string (and also when it parses the "%s" expression, which is just another string). 这就是printf("%s", strPtr)在打印字符串时所做的事情(当它解析"%s"表达式时,它也只是另一个字符串)。 To find a number of valid characters in the string in C, you use strlen() function. 要在C中查找字符串中的许多有效字符,请使用strlen()函数。 Oh, and make sure you dont do something like this: 哦,并确保你不做这样的事情:

char a[3];
strcpy(a, "Hello!");

As this will write 7 bytes into a three-byte memory space, and hence overwrite something you don't want overwritten. 因为这会将7个字节写入3字节的内存空间,因此会覆盖您不想覆盖的内容。

The '\\0' at the end of the string is a useless add-on designed for easy or safety. 字符串末尾的'\\ 0'是一个无用的附加组件,旨在简化或安全。 You can tell string last character by using 'sizeof' like this: 您可以使用'sizeof'来判断字符串的最后一个字符,如下所示:

char status[] = "Married"; 

size_t szLastCharstatus = sizeof(status) / sizeof(status[0]) - 2;

char chLastChar = status[szLastCharstatus];

Detailed explanation: 详细说明:

sizeof(status)

Returns the number of bytes array occpuies. 返回数组occpuies的字节数。

sizeof(status[0])

Returns the number of bytes first element occupies (and so the rest). 返回第一个元素占用的字节数(以及其余的)。

The division between those 2 values gives us the number of elements in the array. 这两个值之间的区分给出了数组中元素的数量。 To access the last element now we need to subtract one 2 times because elements in array count from zero and because the last character in the string is '\\0'. 要访问最后一个元素,我们需要减去一次,因为数组中的元素从零开始计数,因为字符串中的最后一个字符是'\\ 0'。

Also note that arrays are not pointers and vice-versa. 另请注意,数组不是指针,反之亦然。 Arrays have an implicit conversion to pointer of their first element, constant size and their own type. 数组有一个隐式转换为第一个元素的指针,常量大小和它们自己的类型。 They can be passed around by pointers or by value (using structure hack is required for the second). 它们可以通过指针或值传递(使用结构hack是第二个)。

Note that I'm using ' size_t ' which is a type-def of a variable storing some size of data. 请注意,我使用' size_t ',它是存储一些大小数据的变量的类型def。

I'm going to make a provocative statement: the way to think of this is that C doesn't have strings . 我要做一个挑衅性的陈述:想到这个的方法是C没有字符串 C only has arrays of char . C只有char数组。 And despite its name, char is actually a numeric type ( 'A' , for example, is just a funny way to write a number, usually 65). 尽管它的名字, char实际上是一个数字类型( 'A' ,例如,只是一个有趣的方式来写一个数字,通常是65)。

An array of char is not really different from an array of int or any other array of numeric type; char数组与int数组或任何其他数值类型数组没有什么不同; it's just that the language offers some extra ways to write objects of type char and arrays of them, and there is a general convention (systematized with functions like strlen ) for how to interpret data stored in char arrays as being representations of strings. 只是语言提供了一些额外的方法来编写char类型的对象和它们的数组,并且有一个通用的约定(用strlen这样的函数系统化),用于解释如何将存储在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', '\0'};

// 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";

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM