C/C++ 指针和字符串

字符串在计算机编程中具有广泛的应用。字符串指的是由字符组成的序列,它是一种常见的数据类型,用于表示和处理文本数据。在这一篇文章中,我们将会字符串相关的内容:

  1. 字符串原理
  2. 字符串和内存
  3. 字符串操作函数

1. 字符串原理

C 语言中的字符串是字符序列 + 特殊的 \0 字符组成,注意 \0 字符串并不是数字 0,一个字符 0, 如下图所示:

为什么要在结束位置加上 \0 字符呢?

字符串数据不同于 int、double 等类型,它的数据长度不固定,读取时就没办法确定字符串的结束边界,因此,C 字符串使用 \0来作为结束符,即:当知道首字符的地址时,我们就一直往后读取,直到 \0 字符结束。

注意:指针无论存储什么类型的数据,都是存储其首字符地址。

2. 字符串和内存

在 C 语言中,字符串定义时会存在各种方式,我们需要了解不同方式定义时,内存分配是怎么样的,下面全面总结了各种情况:

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


// 1. 第一种情况
// p1 变量存储在全局区,由于 const 修饰,只读
// "hello world" 存储在字符串常量区,只读
const char* p1 = "hello world";


// 2. 第二种情况
// p2 存储在全局区,数组名不允许修改指向,只读
// "hello world" 存储在全局区,可读可写
char p2[] = "hello world";


int main() {

    printf("p1 = %s\n", p1);
    printf("p2 = %s\n", p2);

   // 3. 第三种情况
   // p3 存储在栈区,由于 const 修饰,只读
   // "hello world" 存储在字符串常量区,程序运行期间不会被销毁,只读
   const char* p3 = "hello world";
   printf("p3 = %s\n", p3);

   // 4. 第四种情况
   // p4 存储在栈区,数组名不允许修改指向,只读
   // hello world" 存储在栈区,函数结束则会被销毁,可读可写
   char p4[] = "hello world";
   printf("p4 = %s\n", p4);

   // 5. 第五种情况
   // p5 存储在栈区,函数结束则会被销毁,可读可写
   // "hello world" 存储在堆区,用户决定何时销毁,可读可写
   char* p5 = (char *)malloc(strlen("hello world") + 1);
   strcpy(p5, "hello world");
   printf("p5 = %s\n", p5);


    return 0;
}

另外在定义字符串常量时,务必加上 const 修饰,这是因为标准规定字符串常量不允许修改,但是有些编译器是允许修改的,如下代码在 Borland C++ 编译器中是合法:

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


int main() {

    char* p = "hello world";
    // 下面代码在 VC++ 中是不允许的,在 Borland C++ 中是允许的
    p[0] = 'A';

    // 为了统一字符串常量的行为,强烈要求同学们如下定义字符串常量
    const char *p = "hello world";
    // 下面代码无论在 VC++、Borland C++ 行为都是一样的,都禁止修改
    p[0] = 'A';


    return 0;
}

3. 字符串操作函数

下面给出 C 字符串常用的操作函数。

  1. strlen(str):返回字符串 str 的长度(不包括终止符 ‘\0’)。
  2. strcpy(dest, src):将字符串 src 复制到 dest 中,并返回 dest。
  3. strncpy(dest, src, n):将字符串 src 的前 n 个字符复制到 dest 中,并返回 dest。如果 src 的长度小于 n,则剩余的字符会用 ‘\0’ 填充。
  4. strcat(dest, src):将字符串 src 连接到 dest 的末尾,并返回 dest。
  5. strncat(dest, src, n):将字符串 src 的前 n 个字符连接到 dest 的末尾,并返回 dest。如果 src 的长度小于 n,则剩余的字符会用 ‘\0’ 填充。
  6. strcmp(str1, str2):比较字符串 str1 和 str2 的大小。如果两个字符串相等,返回 0;如果 str1 小于 str2,返回一个负数;如果 str1 大于 str2,返回一个正数。
  7. strncmp(str1, str2, n):比较字符串 str1 和 str2 的前 n 个字符的大小。如果两个子字符串相等,返回 0;如果 str1 小于 str2,返回一个负数;如果 str1 大于 str2,返回一个正数。
  8. strchr(str, c):在字符串 str 中查找字符 c 第一次出现的位置,并返回该位置的指针。
  9. strrchr(str, c):在字符串 str 中查找字符 c 最后一次出现的位置,并返回该位置的指针。
  10. strstr(str1, str2):在字符串 str1 中查找字符串 str2 第一次出现的位置,并返回该位置的指针。
  11. strtok(str, delim):将字符串 str 按照分隔符 delim 进行分割,并返回第一个分割得到的子字符串的指针。
未经允许不得转载:一亩三分地 » C/C++ 指针和字符串
评论 (0)

8 + 7 =