C语言中的字符串

1 C语言中的字符串

1.1 字符串的概念

C语言中字符串的概念如下:

  • 字符串是有序字符的集合。
  • 字符串是程序中的基本元素之一。
  • C语言中没有字符串的概念:
    • C语言中通过特殊的字符数组模拟字符串。
    • C语言中的字符串是以’\0’结尾的字符数组。

1.2 字符数组与字符串

在C语言中,双引号引用的单个或多个字符是一种特殊的字面量:

  • 存储于程序的全局只读存储区。
  • 本质为字符数组,编译器自动在结尾加上’\0’字符。
    在这里插入图片描述
    (除了第一个不是,其余都是。)

对于字符串,我们还需要知道:

  • 字符串字面量的本质是一个数组。
  • 字符串字面量可以看作指针常量。
  • 字符串字面量中的字符不可改变。
  • 字符串字面量至少包含一个字符。

"Hello World"是一个无名的字符数组。

在这里插入图片描述
(上面的结果分别为:‘a’,‘2’, ‘\0’。)

1.3 字符串的长度

关于字符串的长度:

  • 字符串的长度就是字符串所包含字符的个数。
  • 字符串长度指的是第一个’\0’字符前出现的字符个数。
  • 通过’\0’结束符来确定字符串的长度。
  • 函数strlen用于返回字符串的长度。
  • 字符串相关函数都依赖于结束符’\0’。

2 字符串典型问题分析

2.1 snprintf的问题

对于下面的程序会输出什么?
在这里插入图片描述
vs中输出结果如下:
在这里插入图片描述
分析:
snprintf函数本身是可变参数函数,原型如下:int snprintf(char* buffer, int buf_size, const char* format, ...)。当函数只有3个函数时,如果第三个参数没有包含格式化信息,函数调用没有问题(编译器会给出警告);相反,如果第三个参数包含了格式化信息,但缺少后续对应参数,则程序行为不确定。格式化信息必须与变参个数相匹配。

再看一段代码:

#include <stdio.h>
#include <string.h>

int main()
{
    #define STR "Hello, \0D.T.Software\0"
    
    char* src = STR;
    char buf[255] = {0};
    
    snprintf(buf, sizeof(buf), src);
    
    printf("strlen(STR) = %d\n", strlen(STR));
    printf("sizeof(STR) = %d\n", sizeof(STR));
    
    printf("strlen(src) = %d\n", strlen(src));
    printf("sizeof(src) = %d\n", sizeof(src));
    
    printf("strlen(buf) = %d\n", strlen(buf));
    printf("sizeof(buf) = %d\n", sizeof(buf));
    
    printf("src = %s\n", src);
    printf("buf = %s\n", buf);
    
    return 0;
}

/* 输出结果
strlen(STR) = 7
sizeof(STR) = 22
strlen(src) = 7
sizeof(src) = 4
strlen(buf) = 7
sizeof(buf) = 255
src = Hello,
buf = Hello,
*/

分析:

  • 字符串相关的函数均以第一个出现的’\0’作为结束符。
  • 编译器总是会在字符串字面量的末尾添加’\0’。
  • 字符串字面量的本质为数组。
  • 字符串、字符数组、字符指针三者不同。

2.2 字符串的比较问题

直接看如下代码:

#include <stdio.h>
#include <string.h>

int main()
{
    #define S1 "D.T.Software"
    #define S2 "D.T.Software"
    
    if( S1 == S2 )
    {
        printf("Equal\n");
    }
    else
    {
        printf("Non Equal\n");
    }
    
    if( strcmp(S1, S2) == 0 )
    {
        printf("Equal\n");
    }
    else
    {
        printf("Non Equal\n");
    }
    
    return 0;
}
/*
vs、gcc中输出:Equal、Equal。
bcc中输出:Non Equal、Equal。
*/

分析:

  • 字符串之间的相等比较需要用strcmp完成。
  • 不可直接使用==进行字符串直接的比较。
  • 完全相同的字符穿字面量的 == 比较结果为false,但是一些现代编译器能够将相同的字符串字面量映射到同一个无名字符数组,因此==比较结果为true。我们应该不编写依赖特殊编译器的代码!

参考资料:

  1. C语言进阶剖析教程
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值