《c++ primer》5——c风格字符串

字符串字面值的类型就是const char类型的数组。

c风格字符串

c风格字符串既不能确切地归结为C语言的类型,也不能归结为c++类型,而是以空字符null结束的字符数组。

     char ch1[] = { 'a', 'b', 'c' };
     char ch2[] = { 'a', 'b', 'c', '\0' };
     char ch3[] = "abc";
     char *ch = ch2;    
可以理解成没有以\0结尾的字符数组只是普通的字符数组,而以\0结尾的字符数组,就是字符串,c风格的字符串。

1.c风格字符串的使用
int main()
{
     char s[] = "hello";
     char *ps = s;
     cout << s << endl;
     cout << ps << endl;
     while (*ps)//若*ps==null则循环终止
     {
          *ps = toupper(*ps);
          ++ps;
     }
     cout << s << endl;
     //cout<<ps<<endl;注意此时输出ps指向的字符串没有意义,因为ps指向的位置早已到了字符串末端的下一个位置
     getchar();
     return 0;

}
如果ps指向的字符串中没有\0(null结束符)则会一直循环下去,知道在内存中找到\0

2.c风格字符串的标准库函数
使用时,添加头文件
#include <cstring>
strlen(s)
strcmp(s1,s2)
strcat(s1,s2)
strcpy(s1,s2)
strncat(s1,s2,n)
strncpy(s1,s2,n)

3.永远不要忘记字符串结束符null
int main()
{
     char ch[] = { 'a', 'b', 'c' };
     char ch1[] = { 'a', 'b', 'c' ,'\0'};
     cout << strlen(ch) << endl;
     cout << strlen(ch1) << endl;
     getchar();
     return 0;
}
对于第一种输出情况,结果是不确定的,strlen遍历字符串,知道遇到空字符才停止,所以一定不要忘记空字符。

4.调用者必须保证目标字符串具有足够的大小
在调用strcpy和strcat等函数时,strcpy(char*,char*);必须确保第一个实参数据有足够的大小,能够实现字符串的拷贝,并且在第二个实参长度发生变化时,第一个参数需要做适当的调整。

5.使用strn函数处理c风格字符串
strncpy和strncat在复制和连接函数时能够控制复制和连接的函数的个数
int main()
{
     char *ch1 = "hello";
     char *ch2 = "world";
     char ch3[20];
     strncpy(ch3, ch1, 6);//复制ch1中6个字符到ch3,包括null
     cout << ch3 << endl;
     cout << strlen(ch3) << endl;//输出ch3字符串的长度,不包括null
     strncat(ch3," ", 2);//ch3连接两个字符,一个空格,一个null字符,其中空格会覆盖前面的null
     cout << strlen(ch3) << endl;//共有7个字符,字符串的长度为6
     strncat(ch3, ch2, 6);//ch3连接ch2中6个字符,包括null,最前面的字符会覆盖前面的null
     cout << ch3 << endl;
     cout << strlen(ch3) << endl;
     getchar();
     return 0;
}

6.尽可能的使用标准库类型string
标准库将负责处理所有的内存管理问题



创建动态数组

普通数组在编译时必须知道其长度,动态数组则不必在编译时知道其长度,可以在运行时确定数组长度
普通数组只在定义他的域内存在,动态数组则一直存在,直到程序显式释放
普通数组与动态数组长度都是固定的。
堆区(heap)是程序在运行过程用于存放动态分配的对象的内存空间。

1.动态数组的定义和初始化
int *p=new int[10];//返回分配的内存空间的第一个位置的指针。
初始化:
1)数组元素是类类型,用该类的默认构造函数初始化
2)数组元素是内置类型,不会初始化,可以显式的初始化
     int *p=new int[10]();
注意:只能初始化为元素的默认值,不能像数组一样,用初始化列表提供各个元素的初值
int main()
{
     int *p = new int[10]();
     for (size_t index = 0; index != 10; ++index)
     {
          cout << p[index] << " ";
     }
     cout << endl;
     getchar();
     return 0;
}
int类型的默认值0,char类型的默认值空白字符(空格)

2.const对象的动态数组:
const对象在创建时必须进行初始化
const int *p=new int[10];//error
const int *p=new int[10]();//ok
const string *s=new string[10];//ok default construct function

3.允许动态分配空数组:
char ch[0];//error不允许创建0长度的数组
char *pc=new char[0];//ok
用new创建长度为0的数组时,new返回有效的非零指针,该指针与new返回的其他指针不同,不能进行解引用操作,因为他没有指向任何对象,允许进行比较运算。

4.动态空间的释放
delete [] p;//释放p指向的数组,把相应的内存还给自由存储区(堆区)
[]表示指针指向的是自由存储区的数组,而非单个对象
int main()
{
     int *p = new int[10];
     for (size_t index = 0; index != 10; ++index)
     {
          p[index] = index;
          cout << p[index] << " ";
     }
     cout << endl;
     cout << p << endl;
     delete[] p;
     cout << p << endl;//空间释放后,p指向的位置发生变化
     getchar();
     return 0;


}


新旧代码兼容:

1.混合使用标准库类string和c风格字符串

c风格字符串和字符串字面值具有相同的数据类型,因此可以把c风格字符串用在任何可以使用字符串字面值的地方:
int main()
{
     char *s = "hello world";
     string s1(s);//ok
     string s2("hello world");//ok
     cout << s << endl << s1 << endl;
     cout << s << endl << s2 << endl;
     getchar();
     return 0;

}
2.在要求c风格字符串的地方不可直接使用标准库string类型对象
int main()
{
     string s("hello world");
     //char *p = s;//error
     //char *p1 = s.c_str();c_str()返回const类型的c风格字符串
     const char *p2 = s.c_str();

     cout << p2 << endl;
     getchar();
     return 0;
}
c_str()返回const类型的c风格字符串。
注意:如果下面的操作改变s的值,则函数的返回值会失效,所以如果持续访问s数据,则应该复制c——str的返回值
int main()
{
     string s("hello world");
     //char *p = s;//error
     //char *p1 = s.c_str();
     const char *p2 = s.c_str();
     s = "hello";
     cout << p2 << endl;
     getchar();
     return 0;
}
运行结果输出hello

3.使用数组初始化vector对象
必须指出初始化数组的第一个元素和最后一个元素的下一个位置
int a[]={1,2,3,4,5,6};
vector<int> ivec(a,a+3);//1,2,3






























































  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值