哪种更好的方法使用字符串文字初始化字符数组? [英] Which is better way to initialize array of characters using string literal?

查看:110
本文介绍了哪种更好的方法使用字符串文字初始化字符数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是C语言的新手.我试图理解C语言中的数组概念.我对数组初始化感到困惑.

I'm newbie in C language. I'm trying to understanding concept of array in C. I have a confusion about array initialize.

哪种更好的方法使用字符串文字初始化字符数组?

char arr[3] = "xyz";

char arr[] = "xyz";

先谢谢了.

推荐答案

除非在特殊情况下,否则始终首选第二种方法,即不显式键入数组的大小.这样可以避免您在示例中似乎没有引起注意的错误.

Unless under special circumstances, always prefer the second way, that is, by not typing the array's size explicitly. This avoids the bug you seemingly unnoticedly created in your example.

要理解这一点,您首先应该了解什么是字符串.空字符由'\0'表示.字符串是一系列零个或多个非空char以单个空字符终止.最后一点非常重要.看下面的代码:

To understand this, you should first understand what exactly is a string. The null character is denoted by '\0'. A string is a series of zero or more non-null chars, terminated by a single null character. This last bit is very important. Look at the following code:

const char* my_string = "xyz";
size_t string_len = strlen( my_string ); // string_Len == 3

指针只是一个内存地址.它本身不包含任何类型的大小或长度信息.那么,strlen()如何测量my_string的长度?当然,这是通过测量从字符串开始到终止的空字符之前的非空字符的数量.您现在可能已经注意到,终止的空字符在字符串文字中是隐式.上面的字符串文字在内存中创建了一个数组,如下所示:

A pointer is just a memory address. It doesn't hold any type of size or length information in itself. Then, how can strlen() measure my_string's length? This is, of course, by measuring the amount of non-null characters from the string's beginning to just before the terminating null character. You might have now noticed that the terminating null character is implicit in a string literal. The above string literal creates an array in memory that looks like this:

 _______ _______ _______ _______
|       |       |       |       |
|  'x'  |  'y'  |  'z'  | '\0'  |
|_______|_______|_______|_______|
    ^
    |
`my_string` is a pointer to this cell

该数组本身未命名,但是编译器设法将其第一个元素的地址作为my_string的值给出.那么,第一个示例会发生什么?

The array itself goes unnamed, but the compiler manages to give its first element's address as my_string's value. So, what happens with your first example?

char my_string[ 3 ] = "abc";

根据标准的定义,字符串文字的类型为char[ N ],其中N是字符串的长度加上一个用于计算空字符的数字(请注意,出于历史原因,并未将字符串文字声明为const,但是仍未定义的行为来对其进行修改).因此,上述表达式"abc"具有类型char[ 4 ].另一方面,my_string(现在是数组,而不是指针BTW)的类型为char[ 3 ].也就是说,从4 > 3开始,您正在将较小的数组设置为较大的数组.该标准要求,在这种精确的情况下,字符串文字的空字符不适合数组时,应将其切除.因此,my_string在内存中看起来像这样:

By the standard's definition a string literal has type char[ N ], where N is the string's length plus one to count for the null character (note that string literals are not declared const for historical reasons, but it is still undefined behavior to modify them). Thus, the above expression "abc" has the type char[ 4 ]. my_string, on the other hand, (which is now an array, not a pointer, BTW) has type char[ 3 ]. That is, you're setting a smaller array to a larger array, since 4 > 3. The standard mandates that, in this precise situation, where the null character of a string literal doesn't fit into the array, shall it be cut off. Thus, my_string looks like this in memory:

 _______ _______ _______
|       |       |       |
|  'a'  |  'b'  |  'c'  |
|_______|_______|_______|

看起来不错,但是...等等.终止的空字符在哪里?您通过显式声明数组的大小来砍掉它!现在,strlen()应该如何确定字符串的长度?它将继续读取字符串后面的字符,直到巧合地找到空字符为止.这是未定义的行为.另一方面,通过执行以下操作:

Looks ok, but... wait. Where's the terminating null character? You chopped it off by explicitly declaring the array's size! Now, how is strlen() supposed to determine the string's length? It will just continue reading characters past the string until a null character is found by matter of coincidence. This is undefined behavior. On the other hand, by doing this:

const char[] my_string = "abc";

您不会冒险这样做. my_string的类型将自动推断为const char[ 4 ],并且将保留空字符.

You won't be risking doing so. my_string's type will automatically be deduced to const char[ 4 ], and the null character will be preserved.

tl; dr 不要忘记终止的空字符!

tl;dr Don't forget the terminating null character!

这篇关于哪种更好的方法使用字符串文字初始化字符数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆