C语言中的字符串

来源:互联网 发布:js获取页面所有内容 编辑:程序博客网 时间:2024/05/21 08:53

指针和数组(上)

专题四:指针和数组(上)。包括以下章节:

  • 指针基础
  • 数组基础
  • 数组与指针分析
  • C语言中的字符串

C语言中的字符串

  • 从概念上将,C语言中没有字符串数据类型
  • 在C语言中使用字符数组来模拟字符串
  • C语言中字符串是以’\0’结束的字符数组
  • C语言中的字符串可以分配在栈空间、堆空间、只读存储区

4-1.c

#include<stdio.h>#include<malloc.h>int main(){    char s1[] = {'H', 'e', 'l', 'l', 'o'};//栈上定义字符数组    char s2[] = {'H', 'e', 'l', 'l', 'o', '\0'};//栈上定义字符串    char* s3 = "Hello";//s3指针指向只读存储区的{'H', 'e', 'l', 'l', 'o', '\0'}字符串    char* s4 = (char*)malloc(6*sizeof(char));//堆上申请字符串    s4[0] = 'H';    s4[1] = 'e';    s4[2] = 'l';    s4[3] = 'l';    s4[4] = 'o';    s4[5] = '\0';    printf("%s, %0X,  %0X\n", s1, s1, &s1);    printf("%s, %0X,  %0X\n", s2, s2, &s2);    printf("%s, %0X,  %0X\n", s3, s3, &s3);    printf("%s, %0X,  %0X\n", s4, s4, &s4);    free(s4);    return 0;}

结果:
这里写图片描述

字符串的长度

  • 字符串的长度就是字符串包含字符的个数(’\0’除外)
  • C语言中通过’\0’结束符来确定字符串的长度

4-2.c

//size_t strlen(const char* s)//{//  size_t length = 0;////  assert(s);////  while(*s++)//  {//      length++;//  }////  return length;//}#include<stdio.h>#include<string.h>int main(){    char g[100];    g[0] = 'J';    g[1] = 'a';    g[2] = 'c';    g[3] = 'k';    g[4] = '\0';    g[5] = 'h';    g[6] = 'e';    g[7] = 'l';    printf("g = %s\n", g);    printf("length = %lu\n", strlen(g));//字符串是以'\0'结尾,'\0'后的字符不读    printf("size   = %lu\n", sizeof(g));    return 0;}

结果:
这里写图片描述

  • 警告
    • strlen的返回值是无符号数,因此相减不可能产生负数,所以以下语句不等价
char* a = "abc";char* b = "abcd";if(strlen(a) >= strlen(b)){}//size_t为strlen函数返回值类型//size_t为无符号整形(unsigned int),两个size_t相减还是size_t,不可能为负数if(strlen(a) - strlen(b) >= 0){}

实例分析4-1:一条语句实现strlen函数(面试题)

4-3.c

#include <stdio.h>#include <assert.h>size_t strlen(const char* s){    return ( assert(s), (*s ? (strlen(s+1) + 1) : 0) );    //考察点1:安全编程策略    //考察点2:逗号表达式运用    //考察点3:递归思想}int main(){    char *s = "Hello";    printf("s=%s,length=%lu\n",s, strlen( s));    printf("%lu\n", strlen( NULL));    return 0;}

结果:
这里写图片描述

注意!

  • 一般情况下,千万不要自行编写C标准库已经提供的函数
  • 标准库有时会使用汇编语言实现,目的是为了充分利用机器所提供的特殊指令以追求最大的速度
  • 复用已存在的函数库会更高效
  • 重复发明轮子并不是一件有创造性的工作

不受限制的字符串函数

  • 不受限制的字符串函数时通过寻找字符串的结束符’\0’来判断长度
    -char* strcpy(char* dst, const char* src);//字符串复制
    -char* strcat(char* dst, const char* src);//字符串连接
    -char* strcmp(char* s1, const char* s2);//字符串比较
  • 注意事项
    -不受限制的字符串函数都是以’\0’作为结尾标记来进行的,因此输入参数中必须包含’\0’
    -strcpy和strcat必须保证目标字符数组的剩余空间足以保存整个源字符串
    -strcmp不会修改参数值,但依然以’\0’作为结束符
    -strcmp以0值表示两个字符串相等
    • 第一个字符串大于第二个字符串时候返回值大于0
    • 第一个字符串小于第二个字符串时候返回值小于0

实例分析4-2:实现库函数strcpy

4-4.c

#include <stdio.h>#include <assert.h>//1,函数的参数可以作为返回值返回//2, 安全编程策略//3, 指针递增比下标的方式效率高char* strcpy(char* dst, const char* src){    char* ret = dst;    assert(dst && src);    while( (*dst++ = *src++) != '\0' );    return ret;}int main(){    char dst[20];    printf("%s\n", strcpy(dst, "Delphi Tang!"));    return 0;}

结果:
这里写图片描述

长度受限制的字符串函数

  • 长度受限制的字符串函数接收一个显示长度的参数用于限定操作的字符串
    -char* strncpy(char* dst, const char* src, size_t len);//字符串复制
    -char* strncat(char* dst, const char* src, size_t len);//字符串连接
    -char* strncmp(char* s1, const char* s2, size_t len);//字符串比较
  • 以后编码一定要使用长度受限制的函数,因为更安全
  • 注意事项
    -strncpy只复制len个字符串到目标字符串中

    • 当源字符串长度小于len时,剩余的空间以’\0’填充
    • 当源字符串长度大于len时,只有len个字符会被复制,且她不会以’\0’结束

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

    • strncat总是在结束字符串后面添加’\0’
    • strncat不会用’\0’填充目标字符串中的剩余空间

    -strcmp只比较len个字符是否相等