C++中字符数组和字符串string

布满荆棘的人生 2022-08-12 05:29 244阅读 0赞

字符数组

C++中字符数组用char str[]可以用来表示一个字符串。

(1) 数组的大小和字符串的长度。

数组的大小一定要大于字符串的长度,因为系统会自动补上一个’\0’作为字符串的结束标志。当然对于未初始化的也补’\0’.

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4. int main()
  5. {
  6. char str[11] = "I am happy"; // 系统会自动补上'\0'空字符作为结束标志,,未有初始化的也补'\0'
  7. //char str[10] = "I am happy"; // 出错 系统自动补上'\0' 此时字符数组长度不够
  8. //char str[13] = "I am happy"; // 后面未有初始化的也补上'\0' 为 I am happy\0\0\0
  9. if(str[10] == '\0')
  10. {
  11. cout << "hello world!!" << endl;
  12. }
  13. cin >> str; // 输入输出
  14. cout << str << endl;
  15. return 0;
  16. }

另外注意:

(1)

char *val = “abcdef”; // 在栈上存放了一个指针变量val,使其指向常量区的abcdef,,一般情况下常量区比较大,大多数情况下f后面常量区没有分配出去,即为NULL,有时会遇到不为NULL,就会出现问题。
cout << val << endl; // 输出结果为abcdef 直到空指针为止

(2)

char b[2]={‘b’,’a’};
char a[4]={“abc”};
cout << b <<endl; // 输出为ba乱码 由于没有\0 不会截止
cout << a << endl; /// 输出结果为abc 直到\0为止
cout << strlen(a) << endl; // 结果为3

(3)

char *val = “abcdef”;
cout << val << endl; // 输出结果为abcdef 直到空指针为止
cout << strlen(val) << endl;
char *new_val = new char[strlen(val)+1]; // new_val 为val的值 最后一位以\0填充
strncpy(new_val, val, strlen(val)+1);
cout << new_val<< endl; // 输出为abcdef 直到\0截止

函数原型char*strncpy(char*dest,char*src,size_t n);

(c/c++)复制字符串src中的内容(字符,数字、汉字….)到字符串dest中,复制多少由size_tn的值决定。如果src的前n个字节不含NULL字符,则结果不会以NULL字符结束。如果src的长度小于n个字节,则以NULL填充dest直到复制完n个字节。src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符长度+’\0’。来自:http://baike.baidu.com/link?url=lxi\_91JHsW-4omg\_8DcV\_3APvcwUL9oFFtku6V-VR\_t9-Pf5DJzVu886fvGCM\_YzXhd-hXdwqMyiGcZwWGXR-\_

(4)

int *pa = ‘\0’;
int *pb = 0;
int *pc = NULL; // 三者等效

(5)

int a[5]; sizeof(a) 就等于5*sizeof(int) = 20;

如果 是 int*p = new int[5]; 此时p为一个指针那么sizeof(p) 就等于4 == sizeof(int*) 包括double*,void* 或者类类型指针等的字节数都为4

char *p = “abc” 那么sizeof(p) == 4 因为p是一个指针。

char p[4] = “abc”, 那么sizeof(p) == sizeof(char) * 4 = 4;;;此时为数组

char *p[5]; 因为[]优先级高于*,所以把它看做类似于int p[5],,那么就是定义了一个长度为5的数组,只不过数组中的元素都是char*指针,即指向char类型的指针。所以sizeof(p) = sizeof(char*)*5 = 20,,而*p是一个指针,所以sizeof(*p) == 4 == sizeof(指针)————————一个数组 类比于char p[5][] 第二维不确定

char (*p)[5]; 类比于 int a[5],此时*p等于a,那么就是说p是一个指针,指向一个指向字符数组的指针,,相当于char p[][5],,

所以sizeof(p) == sizeof(指针) = 4,,而*p是一个数组的首地址,,所以sizeof(*p) == sizeof(char)*5 = 5.————p是一个指针,类比于char p[][5] 第一位不确定

如果p的值为0x00的话 那么p++的值就为0x05, p虽然是一个指针,但所指向的对象为一个数组的首地址,其大小为sizeof(char)*5,,所以p+1,这里加的是一个数组的字节数即为sizeof(char)*5;;;;;;; 而如果 int *px= new int,,, 此时px指向的对象为int,其大小为sizeof(int), 所以p+1加的是sizeof(int)字节。。。如p(int*类型)所指的内存地址为0x0000,,即p值为0x0000,那么p+1所在的内存地址就为0x0004,通常我们将一个字节作为一个内存单元进行存放。。一个指针变量加(减)一个整数并不是简单地将原值加(减)一个整数,而是将该指针变量的原值(是一个地址)和它指向的变量所占用的内存单元字节数加(减)。

以下代码会输出hello world

  1. #include <stdio.h>
  2. #define TESTSIZE 20
  3. int main(void)
  4. {
  5. char szTest[][TESTSIZE] = {"hello", "world"};
  6. char (*p)[TESTSIZE];
  7. p = szTest;
  8. for(int i = 0; i < sizeof(szTest)/TESTSIZE; i++)
  9. {
  10. printf("%s ", p + i);
  11. }
  12. }

strlen与sizeof

  1. int main(){
  2. char dog[] = "wang\0miao";
  3. cout << strlen(dog) << " " << sizeof(dog) << endl; // 4, 10 strlen遇到\0就结束了且不包括\0
  4. char xx[] = {"hello"};
  5. cout << strlen(xx) << " " << sizeof(xx) << endl; // 5, 6
  6. char *val = "abcde";
  7. cout << strlen(val) << " " << sizeof(val) << endl; // 5, 4 val是一个指针,大小为4个字节
  8. cout << sizeof(long) << sizeof(bool) << endl; // 4, 1
  9. return 0;
  10. }

strlen遇到\0就结束了,且不包括\0 这个字符。即使char a[10]={“hello”}; strlen(a)返回的仍然是5; 而sizeof(a)会等于10

char a[]=”ABCDEF”;char b[]={‘A’,’B’,’C’,’D’,’E’,’F’}; a的长度比b的长。。多了一个\0,,但是strlen(b)会是一个随意值,因为b没有以\0结束

(6) char *val; val = “helloworld”; 是正确的;; 而char val[10]; val= “helloworld”; 是错误的。

  1. char b[]={'A','B','C'};
  2. cout << strlen(b) <<" "<< sizeof(b) << endl; // 15 3
  3. char d[]="ABC";
  4. cout << strlen(d) << " " << sizeof(d) << endl; //3 4

(2)getline()

getline函数可以读取文本或者输入流的一行,此时包括前面输入的空格,只到回车换行才结束

  1. #include <fstream>
  2. #include <iostream>
  3. #include <string>
  4. using namespace std;
  5. int main()
  6. {
  7. ifstream in("E:\\algorithmZack\\testString\\input.txt");
  8. if(!in)
  9. {
  10. cerr << "some errors happened";
  11. return -1;
  12. }
  13. string str;
  14. while(getline(in, str)) /// getline 从文件input.txt中按行读取文件
  15. // while(getline(cin, str)) // 从输入流中按行读取 不包括换行符
  16. {
  17. cout << str << endl;
  18. }
  19. return 0;
  20. }

SouthEast

SouthEast 1

(3)比较,连接,赋值,实际长度用函数strcmp, strcat, strcpy,strlen

参见blog:http://see.xidian.edu.cn/cpp/biancheng/view/158.html

字符串string

(1)String可以看做一个类库,需要有包含头文件#include .

操作包括:连接(+=,append) 赋值(=, assign) 比较(>=,compare) 查找(find)

替换(replace) 删除(erase) 插入(insert) 字串(substring) 交换(swap)

特性(length sizec_str) 正反向迭代器(interator reverse_iterator)

其中使用append,assign,compare的好处在于参数可以为字符数组

详细见blog:http://www.cnblogs.com/xFreedom/archive/2011/05/16/2048037.html

(2)一个简单的例子

从txt中读入以空格为单位的字符串,并对其进行去重排序输出

  1. #include <iostream>
  2. #include <fstream>
  3. #include <string>
  4. #include <vector>
  5. #include <algorithm>
  6. #include <iterator>
  7. using namespace std;
  8. int main()
  9. {
  10. ifstream in("E:\\algorithmZack\\testString\\name.txt"); // fstream
  11. string str;
  12. vector<string> vec; //vector
  13. while(getline(in, str)) // string
  14. {
  15. int pos = 0;
  16. while((pos = str.find_first_of(' ', pos)) != string::npos)
  17. {
  18. vec.push_back(str.substr(0, pos));
  19. pos ++;
  20. }
  21. vec.push_back(str.substr(str.find_last_of(' ')+1)); // 将最后一个字符放入进来
  22. }
  23. sort(vec.begin(), vec.end()); // algorithm
  24. /*注意这里去掉了相邻的重复元素,因此在调用unique之前需要排序 但vec大小没变,在其后面添加了两个空格。但是对于int,则将重复的元素放在后面 */
  25. vector<string>::iterator it = unique(vec.begin(), vec.end()); // algorithm 返回去重后最后一个元素
  26. copy(vec.begin(), it, ostream_iterator<string>(cout, "\n")); // iterator ostream_iterator<string> iterator
  27. cout << endl;
  28. copy(vec.begin(), vec.end(), ostream_iterator<string>(cout, "\n"));
  29. /*for(vector<string>::iterator iter = vec.begin(); iter != vec.end(); iter++)
  30. {
  31. cout << *iter << " ";
  32. }
  33. cout << endl;*/
  34. return 0;
  35. }

SouthEast 2

SouthEast 3

注意:这里的unique去掉了vector中重复元素,但其大小没有变,重复的元素用空格代替放在其后面。但是对已vector,则将重复的元素放在后面。

(3)copy函数

Copy函数包含在头文件#include头文件中。主要有三个常用的用法

copy(IteratorInput it1, IteratorInput it2, IteratorOnput it3) // algorithm

1: 用数组对vector进行赋值

2:用cin对vector进行赋值

3:将vector 进行输出

copy函数原型解释见blog:http://blog.csdn.net/jerryjbiao/article/details/7376088

  1. #include <iostream>
  2. #include <vector>
  3. #include <iterator>
  4. #include <algorithm>
  5. #include <string>
  6. using namespace std;
  7. int main()
  8. {
  9. vector<int> vec;
  10. cout << "hello world!!" << endl;
  11. //int a[] = {3,2,1,1,2,3};
  12. //copy(a, a+6, back_inserter(vec));
  13. //vec.resize(6);
  14. // copy(a, a+6, vec.begin());
  15. copy(istream_iterator<int>(cin), istream_iterator<int>(), back_inserter(vec));
  16. copy(vec.begin(), vec.end(), ostream_iterator<int>(cout, " "));
  17. cout << endl;
  18. sort(vec.begin(), vec.end());
  19. vector<int>::iterator it = unique(vec.begin(), vec.end());
  20. copy(vec.begin(), it, ostream_iterator<int>(cout, " ")); // 输出
  21. return 0;
  22. }

SouthEast 4

(4)一个简单的例子

过滤一行开头和结尾的所有的非英文字符。这里只是为了说明find函数find_first_of函数的区别。Find是从pos开始查找字符串s在当前串中的位置;而find_first_of是从pos开始查找当前串中第一个在s的前n个字符组成的数组里的字符的位置。

如: str.find(str1) 是返回字符串str1 第一次出现字符串str中的位置,如果找不到则返回string::npos(结束标志). str.find_first_of(ch)是返回字符ch第一次出现在字符串str中的位置,如果找不到则返回string::npos. str.find_first_of(str1)是返回str的第一个可以在字符串str1中找到的字符在str中的下标

如str=“———-hello,world——————”; str1 = “abcdefghidklmnopk”; 则str.find_first_of(str1) ,从str第一个字符开始,发现第一个字符h可以在str1中找到,因此返回字符h在str中的下标7

  1. #include <string>
  2. #include <iostream>
  3. using namespace std;
  4. int main()
  5. {
  6. string strinfo = "//*----Hello world!.....----";
  7. string strset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  8. int first = strinfo.find_first_of(strset);
  9. if(first == string::npos)
  10. {
  11. cout << "not find any characters" << endl;
  12. return -1;
  13. }
  14. int last = strinfo.find_last_of(strset);
  15. if(last == string::npos) //string::npos =-1 没有找到 结束标志
  16. {
  17. cout << "not find any characters" << endl;
  18. return -1;
  19. }
  20. cout << strinfo.substr(first, last - first +1) << endl;
  21. string str = "hello world!!!";
  22. string str2 = "hlo";
  23. // 注意 find和find_first_of()区别很大
  24. int j = str.find(str2); // 从pos开始查找字符串str2在当前串str中的位置
  25. int i = str.find_first_of(str2); // 从pos开始查找当前串str中第一个字符在str2的前n个字符组成的数组里的字符的位置。
  26. cout << i << endl;
  27. return 0;
  28. }

Center

参见其它blog:1:http://www.cplusplus.com/reference/string/string/:

2:http://blog.csdn.net/yangtrees/article/details/7577263

3:http://www.cnblogs.com/uniqueliu/archive/2011/07/28/2119328.html

4:http://blog.csdn.net/jerryjbiao/article/details/7376088

5:http://www.cnblogs.com/zkliuym/articles/909245.html

32位和64位系统区别及int字节数

一)64位系统和32位有什么区别?

1、64bit CPU拥有更大的寻址能力,最大支持到16GB内存,而32bit只支持4G内存

2、64位CPU一次可提取64位数据,比32位提高了一倍,理论上性能会提升1倍。但这是建立在64bit操作系统,64bit软件的基础上的。

什么是64位处理器?

之所以叫做“64位处理器”,是因为电脑内部都是实行2进制运算,处理器(CPU)一次处理数据的能力也是2的倍数。8位处理器、16位处理器、32位处理器和64位处理器,其计数都是2的倍数。一次处理的数据越大,该电脑处理信息的能力越来越大;因此64位处理在先天就比32位处理器具有快速的能力。那为什么不用更高级的128位处理器呢?因为位数越高,处理器芯片的设计也就越复杂,目前的技术水平暂时无法制造这么复杂的芯片。

64位处理器之失

※硬件———缺乏驱动程序,很多现有硬件无法使用

※软件———操作系统不是问题,但是软件出现不兼容难题

64位处理器之得

※硬件———更快的执行速度,更大的内存管理

※软件———最新的尖端软件首先出现在64位平台

(二)数据类型对应字节数

程序运行平台
不同的平台上对不同数据类型分配的字节数是不同的。
个人对平台的理解是CPU+OS+Compiler,是因为:
1、64位机器也可以装32位系统(x64装XP);
2、32位机器上可以有16/32位的编译器(XP上有tc是16位的,其他常见的是32位的);
3、即使是32位的编译器也可以弄出64位的integer来(int64)。
以上这些是基于常见的wintel平台,加上我们可能很少机会接触的其它平台(其它的CPU和OS),所以个人认为所谓平台的概念是三者的组合。
虽然三者的长度可以不一样,但显然相互配合(即长度相等,32位的CPU+32位的OS+32位的Compiler)发挥的能量最大。
理论上来讲 我觉得数据类型的字节数应该是由CPU决定的,但是实际上主要由编译器决定(占多少位由编译器在编译期间说了算)。

常用数据类型对应字节数
可用如sizeof(char),sizeof(char*)等得出

32位编译器:

char :1个字节
char*(即指针变量): 4个字节(32位的寻址空间是2^32, 即32个bit,也就是4个字节。同理64位编译器)
short int : 2个字节
int: 4个字节
unsigned int : 4个字节
float: 4个字节
double: 8个字节
long: 4个字节
long long: 8个字节
unsigned long: 4个字节

64位编译器:

char :1个字节
char*(即指针变量): 8个字节
short int : 2个字节
int: 4个字节
unsigned int : 4个字节
float: 4个字节
double: 8个字节
long: 8个字节
long long: 8个字节
unsigned long: 8个字节

  1. 16位操作系统中,int 16位;在32位操作系统中,int 32位。但是现在人们已经习惯了 int 32位,因此在64位操作系统中,int 仍为32位。64位整型用 long long 或者 __int64

发表评论

表情:
评论列表 (有 0 条评论,244人围观)

还没有评论,来说两句吧...

相关阅读