【C++】《C++ Primer Plus》笔记(1)

1     面向行的输入
2     string类的其他操作
3     其他字符串类型
4     结构
5     共用体
6    枚举


面向行的输入

1     getline( )
整行读取,通过回车输入的换行符确定输入结尾。
可以使用cin.getline( )
该函数有两个参数,第一个是用来存储输入行数组的名称,第二个是要读取的字符个数。如果要读取的个数参数为20,则最多只能读取19个字符,余下的空间用于自动在结尾处添加的空字符。
getline在遇上指定数目的字符或者回车换行符时停止读取。

例如:
char name[ArSize];
cin.getline(name,ArSize );
cout<

getline() 函数还可以接受第三个参数,具体会在之后的章节进行展开。
getline每次读取一行,通过换行符来确定行尾,但不保存换行符。
在储存字符串的时候,用空字符来替换换行符。
2     get( )
面向行的输入函数。
位于istream中,有十几个变体,其中一个与getline( )函数类似,接受的参数相同,参数解释也一样。 但get函数并不再读取和丢弃换行符,而是将其留在输入队列中。
cin.get(name,ArSize );
cin.get(gender,ArSize ); //会产生问题
这是由于第一次输入后,换行留在队列中,因此第二次调用时,看到的就是换行符,所以误以为到了行尾

解决的办法是使用get函数的另外一种变体,无参数的get( ),它的功能是读取包括换行符在内的下一个字符所以可以:
cin.get(name,ArSize );
cin.get();
cin.get(gender,ArSize ); 

或者使用拼接的方式
cin.get(name,ArSize ).get();
cin.get(gender,ArSize ); //会产生问题

之所以可以这样做是因为,cin.get(name,ArSize)返回的是一个cin对象,该对象随后被用来调用get()

同理可以cin.getline(name1,ArSize).getline(name2,ArSize);

之所以使用get()的原因是老实的c没有getline(),并且get()使输入更加详细,使得检查错误也更加容易

3     空行和其他问题
空行问题:当前的做法是,当get() 读取空行后将设置失效位(fallbit),接下来的输入将会被阻断,但可以用cin.clear()来恢复输入

字符串超长:getline() & get()将会把余下的字符留在输入队列中,而且gerline函数还会设置失效位来阻止之后的输入



#include
#include

void lq_strcpy_strcat_demo()
{
                 using namespace std;
                cout << "-----------不使用string类对于字符串的操作-----------\n" ;
                 char dst[30] = { "Doo..." };
                 char src[30]= "Hello, how are you." ;

                cout << "初始src=" << src << endl;
                cout << "初始dst=" << dst << endl;

                strcpy_s(dst, src); //将字符串src复制到字符数组dst中
                strcat_s(dst, ",sorry..." ); //将字符串src附加到到字符数组dst尾部            
                 // 'strcpy': This function or variable may be unsafe.
                 //Consider using strcpy_s instead.
                 //To disable deprecation, use _CRT_SECURE_NO_WARNINGS.

                cout << "现在src=" << src << endl;
                cout << "现在dst=" << dst << endl;

                cout << "-----------使用string类对于字符串的操作-----------\n" ;
                 string s1 = "To tell you, " ;
                 string s2 = "I am sorry for breaking your heart!" ;
                 string s3;

                s2 = s1 + s2;
                s3 = s2;
                cout << "s1=" << s1 << endl;
                cout << "s2=" << s2 << endl;
                cout << "s3=" << s3 << endl;
                cout << "s2=s1+s2=" << s2 << endl;
                cout << "s3=" << s3 << endl;

}

【C++】《C++ Primer Plus》笔记(1)_第1张图片

其他字符串类型

除了 char, C++中还有wchar_t
C++11中新增了char16_t, char32_t
对于这些类型的字符串面值,c++分别用前缀L,u和U来表示
如:
                 wchar_t title[] = L"Professier" ;
                 char16_t name[] = u"Lewis Müler" ;
                 char32_t car[] = U"VOLK WAGEN SUPER SNIPER" ;

C++11还支持Unicode 的 UTF-8编码方案,根据字符的数字值,可以存储为1~4个八位组。

C++11中还新增一种raw字符串
使用前缀来标定字符,无需使用\,\n也不代表换行

使用括号( )来标定字符串范围
为了避免有时字符串内部有括号的情况,因此R字符串的格式为
R"+*( 字符串 )+*“


结构

结构的赋值
例子:
struct inflatable
{
     char     name[20];
     float     volue;
     double  price;
};

inflatable bouquet={"sun", 0.20, 12.40};

结构体的位字段
C/C++都允许指定占用特定位数的结构体成员,目的是方便创建与某个硬件设备上的寄存器对应的数据结构。
字段的类型为整形或者枚举,接下来是冒号,冒号后面是一个数字,它指定了使用的位数。可以提供没有指定的字段来提供间距。每个成员都被称为位字段(bit field )
位字段一般用于低级编程中.一般来说可以使用整型和安慰运算的方式来代替这种方式.
struct MyRegister
{
                 unsigned int SN : 4;
                 unsigned int : 4;
                 bool RW : 1;
                 bool cs : 1;

};

                 MyRegister r1 = { 10,true ,false };
                 if (r1.cs) { ... };
                 if (r1.RW == 0) { ... };



共用体
union是一种数据格式,它能够存储不同的数据类型,但 只能同时存储其中的一种类型

union one4all //one for all
{
                 int int_val;
                 double double_val;
                 long long_val;
};

                 one4all p;
                 if (case1)
                {
                                p.int_val = 20;
                }
                 if (case2)
                {
                                p.double_val = 3.1245;
                }
                 if (case3)
                {
                                p.long_val = 655637;
                }

共用体的用途之一是,当数据项使用多种格式(但不会同时使用)时可以节省空间


枚举

enum color { red,orange, yellow,green ,blue };
  • color 是一个枚举,是新类型的名称.可以用枚举名来声明这种类型的变量    color mycolor;//mycolor是color类型的一个变量
  • red,orange, yellow,green ,blue 等作与符号变量,对应于整数值的0~4.这些常量叫做枚举量(enumerator)

默认情况下是将整数值赋给枚举量,第一个枚举量的值是0,第二个为1,依此类推.可以通过显式的指定整数值来覆盖默认值

在没有进行强制类型转换的前提下,只能将定义枚举时的使用的枚举量赋给这个枚举的变量.例子中,color变量受到限制,可能的值只有5个.如果将非法的值赋给它,例如,mycolor=20;有的编译器将会报另一些将会发出警告.
对于枚举只定义了赋值运算符,而没有定义算数运算符
mycolor=red;//合法
mycolor++;//非法
mycolor=red+blue;//非法!
...

枚举量是整型,可能被提升为int型,但是,int型不能自动转换为枚举型
int clr=blue;//合法,枚举型提升为int型
mycolor=3;//非法 ,int型不能自动转换为枚举型
clr=red+4;//合法,枚举型转换为int型
...


如果int型是有效的可以通过强制类型转换将它赋值给枚举变量
mycolor=color(3);
如果试图将一个不适当的值通过强制类型转换赋给枚举变量,结果将是不确定的

枚举更常用来定义相关的符号常量,而不是新的类型.例如可以使用枚举来定义switch中常用的符号常量,如果只是使用常量,而不是用枚举类型的变量,则可以省略枚举类型的名称
例如: enum  { red,orange, yellow,green ,blue };

可以使用赋值运算符来显式地设置枚举量的值
例如: enum  bits{ one=1,two=2,four=4;ten=10 };

指定的值必须是整数,可以显式地定义其中一些枚举量的值:
例如:enum step { first , second = 249, third };
first默认为0,后面没有初始化的值比前面的大1,因此例子中的third值为250

此外,还可以创建多个值相同的枚举量
例如:enum   { null , zero =0, first , one = 1 };

新的C++版本可以将long, long long型赋值给枚举型

对于枚举的取值范围:'
取值范围的定义如下:
上限:先找到枚举量的最大值,然后找出2的幂中,比这个最大值大的且离的最近的值,将这个值减一,就得到了枚举值的上限.
举个栗子,上面的step,third是250<256(2的8次幂),所以step的取值上限就是256-1=255
下限:首先,找出枚举值的最小值,如果是大于等于零,则取值范围下限是0
若<0则,采用与找上限相类似的方式,先不看符号,只不过将最后的值加上负号之后,再加上1.例如,如果最小的枚举值是-7,7<8,所以最小值就是-9+1=-7

原先的C++,只有声明中的那些值才有效。现在,通过强制类型转化,增加了可以赋值的范围。
例如,上面的step,取值范围是0~255,之间的所有值都可以取到。
step flag=step(211);//合法,211在0~255之间


你可能感兴趣的:(也说编程)