C语言字符串与字符数组辨析以及字符串操作详解

直接先来一组代码辨析: 

//字符数组:char 的数组,例如char arr[10];
* 字符串:用""包括的字符序列,如果字符数组有'\0'也是字符串
*  '\0':字符串的结尾标记
*/
int main()
{
	char arr[5] = { 'a','b','c','d','e' };//是字符数组,不是字符串
	char brr[] = { 'a','b','c','d','e' };//是字符数组,不是字符串
	char crr[10] = { 'a','b','c','d','e' };//是字符数组,是字符串
	char drr[] = "abcde";//是字符数组,是字符串
	char err[10] = "abcde";//是字符数组,是字符串
	char frr[] = {'a','b','\0','c'};//是字符数组,是字符串
	printf("%s\n",frr);//%s输出字符串

	return 0;
}

 简单粗暴的讲解(有'\0'或者有" "就是字符串):

char arr[5] = { 'a','b','c','d','e' };//是字符数组,不是字符串

 没有'\0'不是字符串

char brr[] = { 'a','b','c','d','e' };//是字符数组,不是字符串

数组长度未定义,后面有值,长度为根据后面值的数量而设定,后面值的数量为5,则长度为5,没有'\0' ,不是字符串.

char crr[10] = { 'a','b','c','d','e' };//是字符数组,是字符串

数组长度为10,后面值的数量为5,多出来的五个长度会置为0,即'\0',是字符串.

char drr[] = "abcde";//是字符数组,是字符串

 有" "是字符串

char err[10] = "abcde";//是字符数组,是字符串

 有" "是字符串

char frr[] = {'a','b','\0','c'};//是字符数组,是字符串
//输出ab

 有'\0'就是字符串,但是'\0'出现在c前面,程序就终止不继续读下去了,输出ab

再来看一组,你能辨析吗?

int main()
{

	char str1[10];//字符数组,不是字符串
	char str2[10] = "abcde";//字符数组,是字符串
	char str3[] = "abcde";//字符数组,是字符串   长度是6,因为是字符串,有个隐藏的\0
	char str4[] = { 'a','b','c','d','e' };//字符数组,不是字符串,无"",无\0(长度为5)
	char str5[10]= { 'a','b','c','d','e' };//字符数组,是字符串,有\0
	const char* str6 = "abcde";//字符串常量,不是字符数组,没有中括号,是字符串,因为有""

	printf("%s\n", str1);//错,str1不是字符串


	return 0;

详细讲解: 

char str1[10];

    •    这是字符数组,但未初始化,数组中的内容是随机的垃圾值。
    •    不是字符串,因为不保证有 \0 终止符。
    •    printf("%s", str1); 会访问到未知数据,导致运行错误或不确定的输出。

char str2[10] = "abcde";


    •    这是字符数组,长度 10,字符串 "abcde" 只占 6 个字节(包括 \0)。
    •    是字符串,因为 "abcde" 自动添加 \0。
    •    剩下的 4 个字节未初始化,可能是随机值。

存储结构:

'a'  'b'  'c'  'd'  'e'  '\0'  ?  ?  ?  ?

(3)char str3[] = "abcde";


    •    这是字符数组,长度为 6(abcde + \0)。
    •    是字符串,因为 \0 结尾。
    •    自动计算数组长度,等价于 char str3[6] = "abcde";。

存储结构:

'a'  'b'  'c'  'd'  'e'  '\0'

char str4[] = {'a','b','c','d','e'};


    •    这是字符数组,长度为 5。
    •    不是字符串,因为没有 \0 终止符。
    •    printf("%s", str4); 可能导致内存越界,读取未知数据。

存储结构:

'a'  'b'  'c'  'd'  'e'  (无 `\0`)

char str5[10] = {'a','b','c','d','e'};


    •    这是字符数组,长度 10,初始化了 5 个字符,剩余部分自动填充 \0。
    •    是字符串,因为自动填充 \0。

存储结构:

'a'  'b'  'c'  'd'  'e'  '\0'  '\0'  '\0'  '\0'  '\0'

const char* str6 = "abcde";


    •    str6 是指向字符串常量的指针,而不是字符数组。
    •    存储在常量区,不可修改(const)。
    •    访问方式:指针 str6 指向 "abcde" 的首地址。

存储结构:

字符串 "abcde" 存储在常量区:
'a'  'b'  'c'  'd'  'e'  '\0'

为什么 printf("%s", str1); 会出错?

printf("%s\n", str1);

错误原因:
    •    str1 未初始化,内容是随机值。
    •    printf("%s", str1); 会一直读取内存,直到找到 \0,但 str1 可能没有 \0,导致读取非法内存或崩溃。

总结:

有'\0'的就是字符串,用" "双引号就是字符串,数组长度有多余的,其余值为0,即'\0',也是字符串.数组没有初始化,如char str1[10];其值为随机值,不保证有 \0 终止符,也不是字符串

以下为知识点:

在C语言中,字符串(String) 本质上是 以' \0 '结尾的字符数组,C语言没有专门的 string 类型,而是使用 字符数组 或 字符指针 来表示字符串。 在C语言中,字符串必须以 \0 结尾,否则程序无法正确识别字符串的结束位置。

字符数组是由一组字符组成的数组,用于存储一串字符。字符数组的每个元素都是一个字符类型(char)。

1. 字符数组

字符数组是由一组字符组成的数组,用于存储一串字符。字符数组的每个元素都是一个字符类型(char)。
 

定义字符数组

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

上面这个字符数组存储的是单个字符,并没有字符串终止符 \0(空字符)。如果要让它作为字符串使用,必须手动添加 \0:

char arr[6] = {'H', 'e', 'l', 'l', 'o', '\0'};

字符串终止符 \0
    •    在C语言中,字符串必须以 \0 结尾,否则程序无法正确识别字符串的结束位置。
    •    \0 不是可见字符,但它的ASCII值为0,标志着字符串结束。

2. 字符串

字符串本质上就是以 \0 结尾的字符数组,C语言没有专门的字符串类型,而是用字符数组来表示字符串。

定义字符串

char str1[] = "Hello";   // 自动在末尾添加 '\0'
char str2[6] = "Hello";  // 需要足够的空间存放 '\0'

等价于:

char str[] = {'H', 'e', 'l', 'l', 'o', '\0'};

字符串的存储

假设我们定义:

char str[] = "Hello";

内存布局如下:

H   e   l   l   o  \0

实际上,字符串在内存中就是一个字符数组,唯一的区别是字符串必须以 \0 结尾。

3. 字符数组与字符串的区别

C语言字符串与字符数组辨析以及字符串操作详解_第1张图片

3,字符串的操作

C语言中的字符串操作

C 语言标准库 提供了一些常用的字符串操作函数:

(1)计算字符串长度:strlen()

#include 
#include 

int main() {
    char str[] = "Hello";
    printf("字符串长度: %lu\n", strlen(str)); // 5,不包括 '\0'

    return 0;
}

(2)复制字符串:strcpy()

#include 
#include 

int main() {
    char src[] = "Hello";
    char dest[20];

    strcpy(dest, src);  // 复制字符串
    printf("复制后的字符串: %s\n", dest);

    return 0;
}

注意:
    •    strcpy() 不能检查目标数组的大小,可能会导致 缓冲区溢出(Buffer Overflow)。
    •    建议使用 strncpy() 来限制复制的字符数:

strncpy(dest, src, sizeof(dest) - 1);
dest[sizeof(dest) - 1] = '\0';  // 确保字符串以 `\0` 结尾

(3)连接字符串:strcat()

#include 
#include 

int main() {
    char str1[20] = "Hello";
    char str2[] = " World";

    strcat(str1, str2);  // 连接字符串
    printf("连接后的字符串: %s\n", str1);

    return 0;
}

注意:
    •    strcat() 可能会导致 缓冲区溢出,建议使用 strncat() 限制拼接的字符数:

strncat(str1, str2, sizeof(str1) - strlen(str1) - 1);

(4)比较字符串:strcmp()

#include 
#include 

int main() {
    char str1[] = "apple";
    char str2[] = "banana";

    if (strcmp(str1, str2) == 0) {
        printf("两个字符串相等\n");
    } else {
        printf("两个字符串不相等\n");
    }

    return 0;
}

返回值说明:
    •    strcmp(str1, str2) == 0:字符串相等
    •    strcmp(str1, str2) < 0:str1 小于 str2
    •    strcmp(str1, str2) > 0:str1 大于 str2

 总结
    1.    字符串是以 \0 结尾的字符数组
    2.    常用字符串函数:
    •    strlen(str): 计算字符串长度
    •    strcpy(dest, src): 复制字符串
    •    strcat(dest, src): 连接字符串
    •    strcmp(str1, str2): 比较字符串

如果有疑问欢迎在评论区交流!

你可能感兴趣的:(c语言,服务器,linux)