C/C++和python中的字符串


一、C语言中的字符串

C语言中使用一个以’\0’结尾的字符数组来表示一个字符串;
使用字符串相关函数需要引入库"string.h";
C和C++严格区分单引号和双引号,单引号只能用来表示单个字符。

#include "stdio.h"
#include "string.h"

int main() {
    char a[] = "abcdefg";
    printf("%d\n", sizeof(a));//输出8
    printf("%d\n", strlen(a));//输出7
    return 0;
}
char site2[6] = {'A', 'U', 'N', 'O', 'B'}; //这是一个字符数组
char site1[7] = {'A', 'U', 'N', 'O', 'B', '\0'}; //这是一个字符串

 
C中常用的字符串操作函数(string.h中的函数)

strlen(const char* str); //字符串长度
strcmp(const char* str1, const char* str2); //比较str1和str2,根据结果返回1,0或-1
strcat(char* str1, char* str2); //将str2拼接到str1后面
strcpy(char* str1, const char* str2); //将str2复制到str1中
strchr(const char* str, char chr); //在str中查找chr,并返回以chr开头的字符串,如在“this is a demo”中查找‘a’,返回“a demo”
strstr(const char* str1, const char* str2); //和strchr类似,只是查找的是字符串
strtok(char* str1, const char* str); //可以用于字符串分割,使用方法如下
//strtok使用示例
    char str[] = "this,is a-demo";
    const char delim[] = ", -";
    char *substr;
    substr = strtok(str, delim);
    while (NULL != substr) {
        printf("%s\n", substr);
        substr = strtok(NULL, delim);
    }
//输出this is a demo

 
上述的函数还有对应的变体,如下所示:

size_t strnlen(const char *str, size_t maxlen) //如果字符串长度大于maxlen,就返回maxlen,否则返回字符串长度
int strncmp(const char *str1, const char *str2, size_t n) //只对比str1和str2前n个字符
char *strncat(char *str1, char *str2, int n) //将str2的前n个字符cat到str1后
char *strncpy(char *str1, char *str2, size_t n) //将str2的前n个字符拷贝到str1中,如果str2的长度大于n,就拷贝n个,如果小于n,就用'\0'补成n个
char *strrchr(char *str, int ch) //类似于strchr,只不过从反方向进行查找,结果和strchr是一样的

 
string.h中操作内存的函数,内存的操作都以字节为单位

memcpy(void* dest, void* src, size_t n); //将src开始的n个字节内容复制到dest中 
memset(void* dest, int cont, size_t n); //将dest开始的n个字节内容设置为cont
memmove(void* dest, void* src, size_t n); //作用和memcpy相同,但是在出现src和dest内存区域重叠的时候会更安全

注意:使用C中操作字符串的函数需要注意,在拷贝,拼接等会修改字符串的函数中,要注意是否有足够的内存,或者内存空间是否可读可写。
 

二、C++中的字符串

首先,C++兼容C语言中的字符串,C++自身又提供了字符串类string,使用时需要引入头文件"string",string依然可以使用数组的方式进行元素读取。

#inlcude<string.h>
#include<string>
#include<iostream>

using namespace std;

int main(void) {
    char a[] = {'a', 'b', 'c'};
    char b[] = "abc";
    string c = "abc";
    cout << sizeof(a) << endl; // 3
    cout << strlen(a) << endl; // mingw不会报错,输出3
    cout << sizeof(b) << endl; // 3
    cout << strlen(b) << endl; // 3
    cout << sizeof(c) << endl; // 32
    cout << c.length() << endl;// 3
}

C++区别于C的字符串操作方式

#include<string>
#include<iostream>

string str1 = "string01";
string str2 = "string02";
string str3 = str1 + str2; //字符串拼接
cout << str1.size() << str1.length() << endl; // size和length没有区别
str1.append("end"); //向字符串尾部增加内容
int pos = str1.find("ing"); //查找子字符串的位置
str1.insert(1, "insert"); //在索引1的位置添加字符串
str1.compare(str2); //字符串对比
str1.substr(0,4); //获得从索引0开始,长度为4的字符串
str1.swap(str2); //交换字符串内容
str1.replace(0, 5, "XXX"); //将从0开始往后5个长度的子串替换成XXX

 

三、C和C++中字符串的不同

借用知乎文章C/C++的字符串的内存模型中的描述
 

3.1 C中的字符串内存结构

#include <stdio.h>

char *g="Hello";

int main(int argc, char const *argv[])
{
    char s[]="Hello";
    char *c="Hello";
    printf("字符指针c的内存地址:%p\n",&c);
    printf("数组s的内存地址:%p\n",&s);
    printf("字符指针g的内存地址:%p\n",&g);
    printf("字符指针c指向Hello的的内存地址: %p\n",&c[0]);
    printf("字符指针g指向Hello的的内存地址: %p\n",&g[0]);
    printf("变量s数组的Hello副本的内存地址:%p\n",&s[0]);
    printf("Hello字面量的尺寸 %lu\n",sizeof("Hello"));
    
    return 0;
}

在这里插入图片描述

  • 将同样一份字符串字面量的地址直接赋给不同的字符指针,不会产生额外字符串的副本,这些字符指针指向同一份字符串字面量。
  • 以字符串数组初始化字符串字面量会在对应的函数栈内生成另外一份的字面量副本。
  • 再次,如果你在全局区以字符串数组初始化会,会在全局数据区产生同样的字符串副本。
    在这里插入图片描述
     

3.2 C++中的字符串有动态分配空间的机制

string类型的字符串会根据字符串的长度自动分配空间,C++的string类中的字符串,并不是常量区的字符串,而是堆中重新new出来的字符串,如下图所示
在这里插入图片描述

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

int main() {
    string str1 = "HELLO";
    printf("%p\n", str1.c_str()); //c_str方法返回字符串内部字符数组的地址,使用cout输出的话会自动解引,所以使用printf
    cout << str1.capacity() << endl; //capacity方法获得字符串当前申请的空间大小
    system("pause");
    return 0;
}

 

四、python中的字符串

python中不严格区分字符和字符串,单引号和双引号在字符串问题上没有区别。python中字符串是不可变对象

a = "aaa"
#以下语句并不是修改原先的字符串,
#而是又开辟一块内存,值为"bbb",然后a指向该内存
a = "bbb"

python会对字符串常量进行池化,至于多长的字符串会被池化,在ipython环境中超过100位的英文字符串依然被池化,而包含4个中文的字符串未池化。

a = "abcdefg"
b = "abcdefg"
#以下语句为True
id(a) == id(b)

类似的池化也会发生在整形变量上,ipython环境下,0–256会被池化。
常用的python字符串方法如下

str1 = "string01"
str2 = "string02"
print(len(a)) #字符串长度
print(str1+str2) #字符串拼接
print(str1[0:5:2]) #字符串截取
print(str1.capitalize()) #把字符串的第一个字符大写
str1.endswith("01") #是否以某子串结尾
str1.isdigit() #判断字符串是否都是数字
str1.lstrip() #截取左边的空格
str1.rstrip() #截取右边的空格
str1.replace("aaa", "bbb") #将str1中aaa替换成bbb
str1.find("aaa") #查找字符串
str1.split(",") #使用,分割字符串返回子串列表
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值