4.2 字符串
1:针对字符数组,有两种简单的初始化方式:
const int size = 24;
char name1[size];
cin >> name1;
char name2[size] = "helloworld!";
2:两种求取字符串长度的函数
//1:sizeof,包括'\0'在内
sizeof(name1);
//2:strlen,不包括'\0'在内
strlen(name1)
3:cin使用空格,制表符和换行符来确定字符串的结束位置。
4:C++中面向行的读取方法,两种(getline , get)。他们读取一行,直到遇见换行符为止。但是其中getline将换行符从缓冲区中丢弃,但是get将换行符保留在缓冲区中。
cin.getline(chararray_address , char_length);//读取不超过char_length-1个字符到字符数组中,还有第三个参数。
cin.get()有几种变体:
1):cin.get(chararray_name,char_length);
2):cin.get();不带任何参数的get可以读取缓冲区中的下一个字符,就算是换行符也可以被读走。
5:get与getline的比较:
一般在使用中通常选用get,因为get比getline对输入更加细致。比如说,将一行字符读入到字符数组中,如何知道数组停止读取的原因是因为字符数组已经装满了,还是因为遇见了换行符。如果使用get的话,可以通过读取下一个字符是否是换行符来确定字符数组停止读取的原因。但是getline就无法进行判断。
6:当get读取空行时,会设置failbit位,在进行cin.clear()之前,cin都不会再接受输入。
#include<iostream>
using namespace std;
int main() {
const int size = 100;
char name1[size];
cout << "请输入你的名字:";
cin.get(name1,size);
cout << "your name is " << name1 << endl;
cout << "failbit is " << cin.failbit << endl;
cin.clear();
int num[size/10];
int i = 0;
while (i < size / 10 && cin >> num[i]) {
i++;
}
for (int j = 0; j < size / 10; ++j) {
cout << num[j] << endl;
}
return 0;
}
//当cin.clear()被注释掉,不会执行num数组的输入。会直接打印num数组,因此看见的都是乱码or默认值。
7:C++中的原始字符串,就不会对字符串进行转义等等,通过前面加一个R来表示:
cout << R"(Jim "king" \n \" end)" << endl;
//输出就为:Jim "king" \n \" end 括号内是什么就显示什么。
//在" 和 (之间还可以添加其他字符来表示原始字符串的开始,相应的在结尾的)和"之间也要添加相应的其他字符。
4.4:结构体
8:C++结构体中的位字段(方便与硬件打交道)
struct register
{
unsigned int sn : 4; //sn占用4bit
unsigned int : 4; //字段之间提供间距,这4bit不能使用
bool flag : 1;
}
4.5:共用体
共用体是一种数据格式,它能够存储不同的数据类型,但是在某一时刻,只有其中一种类型起作用。比如:
union Name
{
int int_val;
double dou_val;
char char_val;
}
//
Name n1;
n1.int_val = 10;
n1.dou_val = 20.0;
//共用体n1有时是int,有时是double。n1不能同时存在这三个元素的值,在某一时刻只能访问其中一个。
//因此,共用体所占的内存就是内部包含的数据类型中最大的一个。
void TestUnion() {
union DataType {
int int_val;
double dou_Val;
bool val;
};
//DataType dt = { 10,20.0,true }; 会出错,提示初始值太多
DataType dt;
dt.int_val = 10;
cout << "dt.int_val = " << dt.int_val << endl;
cout << "dt.dou_val = " << dt.dou_Val << endl;
dt.dou_Val = 20.0;
cout << "dt.dou_val = " << dt.dou_Val << endl;
cout << "dt.int_val = " << dt.int_val << endl; //这里输出是一个默认值,不是我们前面赋的值
}
4.6:枚举
enum name {enum element};//当枚举的元素没有显示指定其对应的值时,其从0开始,依次加1;
给枚举变量赋值,必须在可能的枚举元素内进行赋值。否则是无效的
枚举量之间不能进行算数运算。
枚举量是整形,可以提升为int类型,但是int类型的值不能自动转换成枚举类型。
如果只使用常量,而不考虑枚举类型的变量,可以省略枚举类型的名称。
//通过赋值运算符来显示的设置枚举量的值
enum bits {one = 1, two = 2, four = 4, eight = 8 , ten};
//其中没被显示指定的值就是为前一个值加1
枚举的取值范围:每个枚举都有取值范围,通过强制类型转换,可以将取值范围中的任何整数值赋给枚举变量,即使这个值不是枚举值。
enum bits{one = 1, two = 2 , four = 4, eight = 8};
bits myflag;
myflag = bits(6); //合法的
取值范围的定义是:首先找到枚举量的最大值,然后找到大于这个最大值的,最小的2的幂,将它减去1,得到的便是取值范围的上限。计算下限需要知道枚举量的最小值,如果不小于0那么下限就为0。小于0的话,就是找到比最小值的绝对值大的最小的2的幂然后减一,再加上负号就是下限。
4.8:指针
1:指针和数组的区别:一般的指针是可以修改指向的,但是数据名是常量。而且对数组名求sizeof时得到的是数组的大小,但是对指针求sizeof时得到的是指针的大小。
2:数组指针和指针数组
数组指针:datatype (*pointer)[size]; pointer指向size这么大的datatype类型的数组。访问其数组元素就是(*pointer)[i];
指针数组:datatype *pointer[size];pointer[i]是一个指针,包含size这么多个指针。
3:存储方式
1)自动存储:在函数内部定义的常规变量使用自动存储空间,被称为自动变量。通常存储在栈上。
2)静态存储:使变量成为静态的方式有两种,一种是在函数外面定义的变量,另一种就是在变量类型前加static。
3)动态存储:new