C/C++数组的字符串与字符数组习题

了解知识

字符数组和字符串在 C 语言中是两个不同的概念,虽然它们都使用字符类型 char 来存储数据,但它们的用途和行为不同。

字符数组

字符数组是一个固定大小的内存块,包含一系列字符,它并不一定要以 \0 结尾。你可以将它看作一个普通的数组,它存储的是一系列的字符数据,不一定是一个完整的字符串。例如:

char arr[] = {
    
    'h', 'e', 'l', 'l', 'o'};

在这个例子中,arr 是一个字符数组,包含了五个字符 ‘h’, ‘e’, ‘l’, ‘l’, ‘o’。它 不一定 以 ‘\0’ 结尾,除非你显式地加上去。字符数组本身并没有“结束”这一概念,它的大小是固定的,程序会通过数组的大小来判断它的长度,而不是通过一个特殊字符来终止。

字符串(字符串常量或字符数组)

当你使用双引号 " "来定义一个字符数组时,编译器会自动在最后添加 ‘\0’ 作为结束符,这样就形成了一个字符串。例如:

char str[] = "hello";

在这个例子中,str 是一个字符数组,编译器会将其扩展为:

str[0] = 'h', str[1] = 'e', str[2] = 'l', str[3] = 'l', str[4] = 'o', str[5] = '\0'

在这里,‘\0’ 是自动添加的,表示字符串的结束。

总结:
字符数组:只是一组字符,存储数据,不需要 ‘\0’ 结尾。
字符串:字符数组的一种特殊形式,通常需要以 ‘\0’ 结尾,以标识字符串的结束。

sizeof和strlen

sizeof 和 strlen 都是在 C 语言中用来获取字符串或字符数组的大小,但它们的含义和用途有所不同,尤其是在处理字符串和字符数组时。

  1. sizeof 操作符:
    sizeof 用来获取数据类型或变量的总字节数,它在编译时就会确定大小。
    对于数组,sizeof 返回的是整个数组所占的总字节数(包括所有元素的字节数)。
    对于指针,sizeof 返回的是指针本身所占的字节数(通常是 4 或 8 字节,取决于平台)。
  2. strlen 函数:
    strlen 用来获取字符串的长度(即字符串中不包括 \0 结束符的字符个数)。
    strlen 适用于字符串,而不适用于普通的字符数组(注意:是不适合,不是不允许),因为它依赖于 \0 结束符来确定字符串的长度。
    对比:
    sizeof 计算的是数组的总字节数(包括 \0)。
    strlen 计算的是字符串的实际字符数(不包括 \0)。

举例说明:

  1. 对于字符数组:
#include <stdio.h>

int main() {
    
    
    char arr[] = "hello";
    
    // 使用 sizeof 获取字符数组的大小
    printf("sizeof(arr) = %zu\n", sizeof(arr));  // 输出:6,因为包含了 '\0'

    // 使用 strlen 获取字符串的长度
    printf("strlen(arr) = %zu\n", strlen(arr));  // 输出:5,不包括 '\0'

    return 0;
}

解释:

arr[] = “hello” 实际上是一个包含 6 个字符的数组(h, e, l, l, o, \0)。
sizeof(arr) 返回的是整个数组的字节数,包括结束符 \0,所以输出为 6。
strlen(arr) 计算的是字符串的长度,不包括 \0,所以输出为 5。
2. 对于字符指针:

#include <stdio.h>

int main() {
    
    
    char *str = "hello";
    
    // 使用 sizeof 获取指针的大小
    printf("sizeof(str) = %zu\n", sizeof(str));  // 输出:4 或 8,取决于平台(32位或64位)

    // 使用 strlen 获取字符串的长度
    printf("strlen(str) = %zu\n", strlen(str));  // 输出:5,不包括 '\0'

    return 0;
}

解释:

str 是一个指针,指向字符串常量 “hello”。指针 str 本身的大小与字符串内容的大小无关,通常在 32 位平台上是 4 字节,在 64 位平台上是 8 字节。
sizeof(str) 返回的是指针本身的大小,而不是字符串的长度。
strlen(str) 计算的是字符串 “hello” 的长度,即 5,因为 strlen 会遍历字符串直到遇到 \0。

3. 总结:
sizeof 在处理数组时返回数组的总字节数,包括字符串结束符 \0。
strlen 只适用于字符串,返回字符串中的字符数(不包括 \0)。

习题

1.

在这里插入图片描述
链接:https://www.nowcoder.com/questionTerminal/81cc723e49fc402ca7fa62a97a121251
来源:牛客网

sizeof返回数组所占的字节数,‘wang’ ‘miao’共占8字节,显式’\0’占1字节,字符串末尾隐式’\0’占1字节,共10字节。
strlen返回字符串的长度,以遇到’\0’结束符为准,因此为4。

2.

在这里插入图片描述
s 是一个字符数组,存储字符串 “china”,包括结尾的 \0。
p 是一个字符指针,指向数组 s 的首地址(即 s[0] 的地址)

A. s 和 p 完全相同
错误。

s 是一个数组,p 是一个指针。

数组名 s 表示数组的首地址,但它是一个常量指针,不能被修改。

指针 p 是一个变量,可以指向其他地址。

因此,s 和 p 不完全相同。

B. 数组 s 中的内容和指针变量 p 中的内容相等
错误。

数组 s 中的内容是字符串 “china”,包括字符 ‘c’, ‘h’, ‘i’, ‘n’, ‘a’ 和 \0。

指针变量 p 中的内容是数组 s 的首地址(即 s[0] 的地址),而不是字符串内容。

因此,s 中的内容和 p 中的内容不相等。

C. s 数组长度和 p 所指向的字符串长度相等
错误。

s 数组的长度是 6(包括 ‘c’, ‘h’, ‘i’, ‘n’, ‘a’ 和 \0)。

p 所指向的字符串是 “china”,其长度为 5(不包括 \0)。

因此,s 数组长度和 p 所指向的字符串长度不相等。

*D. p 和 s[0] 值相等
正确。

p 指向 s 的首地址,即 s[0] 的地址。

*p 表示取 p 所指向地址的值,即 s[0] 的值。

s[0] 的值是 ‘c’,因此 *p 也是 ‘c’。

所以,*p 和 s[0] 的值相等。

3.

在这里插入图片描述

char a[2][3];

定义了一个二维字符数组 a,大小为 23 列。

每行可以存储最多 2 个字符(因为需要留一个位置给字符串结束符 \0)。

strcpy(a[0], "ab");

将字符串 "ab" 复制到 a[0] 中。

a[0] 的内容为:{
    
    'a', 'b', '\0'}。

strcpy(a[1], "cd");

将字符串 "cd" 复制到 a[1] 中。

a[1] 的内容为:{
    
    'c', 'd', '\0'}。

a[0][2] = ' ';

将 a[0][2](即 a[0] 的第三个字符)修改为空格 ' '。

a[0] 的内容变为:{
    
    'a', 'b', ' '}。

注意:a[0] 现在不再是一个有效的 C 字符串,因为它的结尾没有 \0。

printf("%s", a);

printf 使用 %s 格式化字符串输出。

a 是一个二维数组,传递给 printf 时会被解释为指向 a[0] 的指针(即 char* 类型)。

a[0] 的内容是 {
    
    'a', 'b', ' '},由于没有 \0 结尾,printf 会继续读取内存中的内容,直到遇到 \0。

接下来会读取 a[1] 的内容 {
    
    'c', 'd', '\0'}。

因此,printf 会输出:ab cd。

选项分析:
A. ab
错误。a[0] 的内容是 {‘a’, ‘b’, ’ '},且没有 \0 结尾,printf 会继续读取 a[1] 的内容。

B. abcd
错误。a[0][2] 被修改为空格,因此输出中会包含空格。

C. ab cd
正确。printf 会输出 a[0] 的内容 ab ,然后继续输出 a[1] 的内容 cd。

D. 编译出错
错误。代码语法正确,可以正常编译。

总结:
正确答案是 C. ab cd。

4.

在这里插入图片描述

5.

在这里插入图片描述
char a1[] = “program”;

这是一个字符串初始化方式。

字符串 “program” 在内存中存储为:{‘p’, ‘r’, ‘o’, ‘g’, ‘r’, ‘a’, ‘m’, ‘\0’}。

因此,数组 a1 的长度为 8(包括结尾的 \0)。

char a2[] = {‘p’, ‘r’, ‘o’, ‘g’, ‘r’, ‘a’, ‘m’};

这是一个字符数组初始化方式。

数组 a2 的内容为:{‘p’, ‘r’, ‘o’, ‘g’, ‘r’, ‘a’, ‘m’}。

因此,数组 a2 的长度为 7(不包括 \0)。

选项分析:
A. a1 和 a2 完全相同

错误。

a1 的长度为 8,包含 \0。

a2 的长度为 7,不包含 \0。

因此,a1 和 a2 不完全相同。

B. a1 和 a2 不同,a1 是指针

错误。

a1 和 a2 都是数组,而不是指针。

a1 是一个字符数组,存储字符串 “program”。

a2 是一个字符数组,存储字符 {‘p’, ‘r’, ‘o’, ‘g’, ‘r’, ‘a’, ‘m’}。

因此,a1 不是指针。

C. a1 和 a2 存储单元的数目相同

错误。

a1 的存储单元数目为 8。

a2 的存储单元数目为 7。

因此,a1 和 a2 的存储单元数目不同。

D. a1 和 a2 不同,a1 的存储单元数目多

正确。

a1 的长度为 8,包含 \0。

a2 的长度为 7,不包含 \0。

因此,a1 的存储单元数目比 a2 多。

总结:
正确答案是 D. a1 和 a2 不同,a1 的存储单元数目多。

6.

在这里插入图片描述
char a[] = “ABCDEF”;

这是一个字符串初始化方式。

字符串 “ABCDEF” 在内存中存储为:{‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’, ‘\0’}。

因此,数组 a 的长度为 7(包括结尾的 \0)。

char b[] = {‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’};

这是一个字符数组初始化方式。

数组 b 的内容为:{‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’}。

因此,数组 b 的长度为 6(不包括 \0)。

选项分析:
A. a 与 b 数组完全相同
错误。
a 的长度为 7,包含 \0。
b 的长度为 6,不包含 \0。
因此,a 和 b 不完全相同。

B. a 与 b 长度相同
错误。
a 的长度为 7。
b 的长度为 6。
因此,a 和 b 长度不同。

C. a 和 b 中都存放了字符串
错误。
只有 a 是一个字符串,因为它以 \0 结尾。
b 是一个字符数组,没有 \0 结尾,因此不是字符串。

D. a 数组比 b 数组长
正确。
a 长度为 7。
b 的长度为 6。
因此,a 比 b 长。
总结:
正确答案是 D. a 数组比 b 数组长。

字符数组是否需要\0

字符数组是否需要 \0(空字符,即 null terminator)取决于它的用途。具体来说:

  1. 字符数组 vs 字符串
    字符数组:只是一个存储字符的数组,不一定要以 \0 结尾。

字符串:在 C/C++ 中,字符串是以 \0 结尾的字符数组。

  1. 字符数组不需要 \0 的情况
    如果字符数组仅用于存储一组字符,而不需要作为字符串使用(例如,不需要传递给字符串处理函数如 strlen、strcpy、printf 等),那么它不需要以 \0 结尾。

示例:

char b[] = {
    
    'A', 'B', 'C', 'D', 'E', 'F'};

这是一个字符数组,存储了 6 个字符。

它没有 \0 结尾,因此不能作为字符串使用。

如果尝试将其作为字符串使用(例如 printf(“%s”, b);),会导致未定义行为,因为 printf 会一直读取内存,直到遇到 \0。

  1. 字符数组需要 \0 的情况
    如果字符数组需要作为字符串使用(例如传递给字符串处理函数),则必须以 \0 结尾。

示例:

char a[] = "ABCDEF";

这是一个字符串,存储了 {‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’, ‘\0’}。

它以 \0 结尾,因此可以作为字符串使用。

例如,printf(“%s”, a); 会正确输出 ABCDEF。

  1. 为什么字符串需要 \0?
    在 C/C++ 中,字符串是以 \0 结尾的字符数组。\0 的作用是标记字符串的结束位置。如果没有 \0,字符串处理函数(如 strlen、strcpy、printf 等)无法确定字符串的结束位置,会导致未定义行为。

示例:

char a[] = "ABCDEF";  // 以 \0 结尾
char b[] = {
    
    'A', 'B', 'C', 'D', 'E', 'F'};  // 不以 \0 结尾

printf("%s\n", a);  // 正确输出 "ABCDEF"
printf("%s\n", b);  // 未定义行为,可能输出乱码或崩溃
  1. 总结
    如果字符数组仅用于存储一组字符,而不需要作为字符串使用,则不需要 \0。

如果字符数组需要作为字符串使用,则必须以 \0 结尾。

在题目中:

char a[] = “ABCDEF”; 是字符串,以 \0 结尾。

char b[] = {‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’}; 是字符数组,不以 \0 结尾。

因此,b 不需要 \0,但如果需要将其作为字符串使用,则必须手动添加 \0。例如:

char b[] = {
    
    'A', 'B', 'C', 'D', 'E', 'F', '\0'};

猜你喜欢

转载自blog.csdn.net/weixin_44628096/article/details/145811490
今日推荐