C语言中的字符串

来源:互联网 发布:淘宝模板制作 编辑:程序博客网 时间:2024/05/18 00:25

从概念上讲,C语言中没有字符串类型

在C语言中使用字符数组来模拟字符串

C语言中的字符串是以‘\0’结束的字符数组

C语言中的字符串可以分配于栈空间,堆空间或者只读存储区

char s1[] = {'H', 'e', 'l', 'l', 'o'};  //没有‘\0’,所以s1只不过是个单纯的字符数组

char s2[] = {'H', 'e', 'l', 'l', 'o', '\0'}; //也是一个字符数组,但是最后一个元素是‘\0’,因此s2就成了C语言中的字符串,并且这么写的话这个字符串是在栈空间分配的

char* s3 = "Hello";  //是C语言中最常规的写字符串的方法,这样的字符串存储于只读存储区,相当于一个字符串常量,不能改变里面的内容

char* s4 = (char*)malloc(6*sizeof(char));  

s4[0] = 'H';

s4[0] = 'e';

s4[0] = 'l';

s4[0] = 'l';

s4[0] = 'o';

s4[0] = '\0';           //malloc返回堆空间,因此s4指向的字符串是在堆上分配的空间

free(s4);

在栈和堆上分配的字符串都可以自由改动里面的内容,但是在只读存储区上字符串里的内容不可以改变


字符串的长度

字符串的长度就是字符串所包含字符的个数

C语言中的字符串长度指的是第一个‘\0’字符前出现的字符个数

C语言中通过‘\0’结束符来确定字符串的长度

例1:

char g[100];
int main()
{
    g[0] = 'H';
    g[1] = 'e';
    g[2] = 'l';
    g[3] = 'l';
    g[4] = 'o';
    g[5] = '\0';

    printf("length = %d\n", strlen(g));

    printf("size = &d\n", sizeof(g));

    return 0;
}

编译运行得:

改为:

char g[100];
int main()
{
    g[0] = 'H';
    g[1] = 'e';
    g[2] = 'l';
    g[3] = 'l';
    g[4] = 'o';
    g[5] = '\0';

    g[6] = 'H';
    g[7] = 'e';
    g[8] = 'l';
    g[9] = 'l';
    g[10] = 'o';

    printf("length = %d\n", strlen(g));

    printf("size = &d\n", sizeof(g));

    return 0;
}

编译运行得:,结果不变,因为字符串只算第一个‘\0’字符前面的所有字符,后面无论是什么都不值字符串的一部分了,但是后面的和前面的所有内容都是字符数组的内容。

警告:

例2

char* a = "123";

char* b = "1234";

if( strlen(a) >= strlen(b) )  //正常执行

{

        //......

}

if( strlen(a) - strlen(b)   >=  0 )   //两个无符号数相减总是大于等于0的,所以该if总是执行

{

        //......

}

strlen()的返回值是用无符号数定义的,因此相减不可能产生负数,以上的语句不等价


面试题:

size_t strlen(const char* s)
{
    size_t length = 0;  
    assert(s);          //检测参数是否为空
    
    while( *s++ )
    {
        length++;
    }
    
    return length;
}

使用一条语句实现strlen:

size_t strlen(const char* s)

{

           return ( assert(s), ( *s ? (strlen(s+1) + 1) : 0 ));

}      //逗号表达式先assert(),然后三目运算,采用递归实现求长度


注意:

一般情况下,千万千万不要自行编写C标准库已经提供的函数

标准库有时会使用汇编语言实现,目的就是为了充分利用机器所提供的特殊指令以追求最大速度

复用已经存在的函数库会更高效


不受限制的字符串函数

不受限制的字符串函数是通过寻找字符串的结束符'\0'来判断长度,无需提供字符串长度信息

字符串复制:char* strcpy(char* dst, const char* src);

字符串连接:char* strcat(char* dst, const char* src);

字符串比较:int strcmp(const char* s1, const char* s2);

注意:

不受限制的字符串函数都是以'\0'作为结尾标记来进行的,因此输入参数中必须包含'\0'。参数不能是字符数组,否则会调用出错。

strcpy和strcat必须要保证目标字符数组的剩余空间足以保存整个源字符串。

strcmp以0值表示两个字符串相等

        .第一个字符串大于第二个字符串的时候返回值大于0

        .第一个字符串小于第二个字符串的时候返回值小于0

strcmp不会修改参数值,但依然以'\0'作为结束符


面试题:

实现库函数strcpy

char* strcpy(char* dst, const char* src)

{

         char* ret = dst;

         assert(dst && src);

         while( (*dst++ = *src++) != '\0' );

         return ret;

}


长度受限制的字符串函数

长度受限制的字符串函数接受一个现实的长度参数用于限定操作的字符数

字符串复制:char* strncpy(char* dst, const char* src, size_t len);

字符串连接:char* strncat(char* dst, const char* src, size_t len);

字符串比较:int strncmp(const char* s1, const char* s2, size_t len);

以后的工作当中,如果非要调用字符串库函数的话,一定要调用长度受限制的字符串函数,一定要手工指定长度究竟是多少字符,因为这一组函数比长度不受限制的字符串函数要安全的多。

注意:

strncpy只复制只复制len个字符到目标字符串

      .当源字符串的长度小于len时,剩余的空间以'\0'填充

      .当源字符串的长发大于len时,只有len个字符会被复制,且它将不会以'\0'结束

strncat最多从源字符串中复制len个字符到目标字符串中

      .strncat总是在结果字符串中后面添加'\0'

      .strncat不会用'\0'填充目标串中的剩余空间

strncmp只是比较len个字符是否相等

        .相等返回0,大于返回值大于0,小于返回值小于0




原创粉丝点击