C++ 字符的特殊处理

本文深入探讨C++中字符串与字符数组的处理方式,包括NULL与空字符串的区别、字符数组初始化、字符串操作函数的使用,以及字符相加减的底层实现原理。通过实例分析,读者将理解不同情况下字符串的表现和注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 字符NULL、 {}、 \0 ''
      // char*数组中
      char p0[2] = { NULL };
	  char p1[2] = {};
	  char p2[2] = {0};//把ascall码0对应的字符赋值给数组,不加 " " 引号赋值都是以ascll码赋值。
	  char p3[2] = {'\0'};
	  char p4[2] = ""; 这5个都是一样的

上面五种情况都表示空字符。

  • 带引号的字符串应至少包含一个字符,不允许出现 '' 空的现象。
    char a = ‘’ //错误带引号的字符串应至少包含一个字符
  • 对字符数组取值:在char p[2]={}中p为数组指针,指向了第一个数组元素所在的位置。 *p就是取的数组的第一个元素的值。 *p==p[0] 为true 即 *(p+n)为p[n]
  • string中NULL和"": NULL代表声明了一个空对象,根本就不是一个字符串。 ""代表声明了一个对象实例,这个对象实例的值是一个长度为0的空字符串。
    NULL代表声明了一个空对象,对空对象做任何操作都不行的,除了=和== 。""是一个字符串了,只是这个字符串里面没有内容了
    String s=null;只是定义了一个句柄,也就是说你有了个引用,但是这个引用未指向任何内存空间
    String s="";这个引用已经指向了一块是空字符串的内存空间,可执行+=操作。
  • C与C++中的NULL:
    #ifdef __cplusplus
    #define NULL 0
    #else
    #define NULL ((void *)0)
    #endif  
    
  • " \"的作用:
    1、C/C+中转义符, "\\\\.\\"就相当于\\.\
    2、续行符:#define SomeFun(x, a, b)
    续行符作用:宏定义的时候,代替的语句很长或者是个语句块甚至函数的时候,就需要用到这个反斜杠了。
    实例分析:
char s[] =“ \\141\141abc\t ”;
cout << s  << strlen(s) << endl;
\141aabc   9

分析:\141 是一个字符 a ,为什么呢?因为 \141 是一种用八进制数字表示字符的形式,\o \oo \ooo 这三种形式,当然 o 必须是正确的八进制数(0~7) strlen() 函数是不计入 \0 的。\t:水平制表(跳到下一个Tab位置)\n:换行
\r:回车,将当前位置移到本行开头,不会换到下一行,如果接着输出的话,本行以前的内容会被逐一覆盖。

  • 字符相减: 对应到ASCII码相减得到整数值,ASCII码中同一字母的小写字符的ASCII值比大写的ASCII值大32。例如 ‘a’-‘A’ 的就是:32
    char a = 'a';
	char A = 'A';
	cout << a - A << endl; // 32

利用字符相加减可以实现字符的大小写转换,这也是c++ 库 toupper和tolower的底层实现原理。

int tolower(int c)
{
	if ((c >= 'A') && (c <= 'Z'))
		return c + ('a' - 'A');
	return c;
}
 
int toupper(int c)
{
	if ((c >= 'a') && (c <= 'z'))
		return c + ('A' - 'a');
	return c;
}
char string[] = "THIS IS A STRING";
string[i] = tolower(string[i]);
  • 在c语言中,将字符串作为字符数组处理,最后一个字符串结束标志\0是系统自动加上的。 注意sizeof和strlen处理的区别,strlen只计算有效字符的数目,直到遇到\0或null停止计算,参数为字符数组名char[] 的名字指针char *的名字。sizeof计算数组所占的全部内存大小包括空字符, 参数为数组char[] 的名字,不能为指针char*的名字,否则只计算指针本身的大小。
char str1[]="0123456789";   // 字符串结尾还有一个结束标志\0
char str2[]={'0','1','2','3','4','5','6','7','8','9'};
sizeof(str1);    //11
sizeof(str2);    //10
strlen(str1);    //10
strlen(str2);    //不确定的值,未知到哪个位置会遇到\0或者null。

char str3[8]={'a',};
sizeof(str3);    //8
strlen(str3);    //1,只有一个有效值,其它位置为空字符。
const char * str4="abcd";
sizeof(str4);    // 4   指针本身所占的大小,若以指针名char*  传给sizeof 会只计算指针的所占的大小,要传数组名char name []。
strlen(str4);    //4
  • char * 赋值: 不同于char []声明定义时即分配了内存空间,声明char* 后未知其所指向的内存空间,若对char* 赋值要先分配一个内存空间再赋值地址给char* 或者直接指向一个已赋值的内存空间地址。char[]的数组名代表了数组的起始地址,是一个地址常量,而常量是不能改变的。对字符串中的某个位置修改的话,此字符串不能是char*,因为char* 存储在常量区,可以用char[]存储可修改值的字符串,char[]的地址在可修改值的堆栈中。
char *p;
p=(char*)malloc(6);
strcpy(p,"abcde");
//或p="abcde"; //p指向常量区的内容

char a[] = "abcde"; //正确
char b[6];
b = "abcde"; //错误,数组名代表了数组的起始地址,是一个地址常量,而常量是不能改变的。b的地址在堆栈,不能转为常量区地址
  • 若想在同一个数组中保存并传输多种数据类型,应把数组声明为char类型。而且需要额外做一些指针及数组运算。指针强制转换仅仅是将地址后的内容按照不同的类型进行变量解释和读取。但是如果强制转换的指针所指向数据的字节数不一样,会存在数据错误。 比如:一个指向char型数据的指针p,p指向的内容只有一个字节,*p是将地址后面的一个字节的内容按照char进行解读取;但是如果将其强制转换成int型指针*pn,*pn将地址后面的四个字节的内容按照int进行解读取,这样就会多读了后面的内存,出现错误。
char p[];
scanf("%d",(int*)&p[i*4]);
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值