C++ Primer Plus 学习笔记(二)

目录

第四章. 复合类型

5. 共用体

6. 枚举

7.指针和自由储存空间

8. new运算符

9. 数组的替代品

第5章. 循环和关系表达式

1. for 循环

2. while 循环

3. do while 循环

4. 基于范围的 for 循环

5. 循环和文本输入

6. 嵌套循环和二维数组


第四章. 复合类型

5. 共用体

用法跟结构一样,区别主要是,结构中所有元素都会分配内存,而共用体(联合)是所有元素共用一块内存,即一次只能表示一种类型,大小为最大类型的大小。

union one4all   // 大小是long的长度
{
    int int_val;
    long long_val;
} pail;
pail.int_val = 15;

6. 枚举

枚举内定义的都是常量,声明一个枚举变量后,该变量的值只能是枚举范围内的值,枚举内定义的常量可以自动转换为int,但int不能自动转换为枚举类型。枚举类型没有定义算数运算,在表达式中出现算数运算,自动将枚举常量转为int。

enum spetrum {red, orange, yellow, green, blue,
                violet, indigo, ultraviolet}; // red-ultra的值为0-7
spetrum band;
band = orange; //有效
band++;  //无效
band = red + green; // 无效,red、green自动转换为int,而int无法转换为枚举,从而无法为band赋值
int color = red; //red被自动转换成int,color = 0
band = 3; // 无效,int不能自动转换为枚举
band = spectrum(5); //有效,5在枚举范围内

枚举常量的值可以初始化,值必须是整数,没初始化的值比上一个大1,枚举常量的值可以相同。枚举的范围是大于最大值的2的最小次幂减一,如果枚举最小值大于0,则下限是0,否则按照上限的方式求下限。但是若int类型常量在枚举范围内,可以强制转换为枚举。

enum bits {one = 1, null = 1, two = 100, three}; // three = 101
// bits 的取值范围是0-127,大于101的2的最小次幂是128,下限是0
// 如果one = -6,则下限是小于-6的2的最小次幂-8,加1,下限为-7
bits num = bits(111); // 有效,111在bits范围内

7.指针和自由储存空间

未初始化的指针不要指向常量,未初始化的指针指向哪未知,该常量储存的内存位置也就不确定,可能产生bug。要将数字值作为地址赋给指针要强制转换。

int *pt;
pt = 0xB8000000; // 无效,0XB8000000是整型
pt = (int*)0xB8000000; //有效
*pt = 200; //不要这样做

指针变量+1时,增加的量是它指向类型的字节数,如上面代码中pt+1的值为0xB8000004(看系统)。数组名可以作为指针常量,即数组名也就是该数组的数组指针,不过数组指针和数组首元素的地址相同。

int num[4];
int *pt = num;
num = num + 1; //无效,数组指针是常量
pt = pt + 1;  //有效,地址值加4

而对数组名用 地址运算符 & 时,会被解释为整个数组的地址,&num+1的值要加16字节,而pt+1的值加4字节。

8. new运算符

typeName * pointerName = new typeName;
delete pointerName;

用new分配一段内存空间,new分配的内存是未使用的,不会产生bug。delete释放完new后,并没有删除new的指针,该指针可以继续指向其他同类型的变量。

typeName * pointerName = new typeName [num_elements];
delete [] pointerName;

new创建动态数组时要告知元素数量,delete时不要忘了[](中括号是空的)。使用的时候跟数组的使用方式一样,指针指向第一个元素。

9. 数组的替代品

#include <vector>
using namespace std;  // 或者通过std :: vector<int> vi使用vector
// vector<typeName> vt(n_elem)  n_elem可以说变量,也可以是常量
vector <int> vi;

要使用vector类,要包含vector头文件,它在std命名空间中。它可以在使用中调整数组长度,因此可以不设置长度。

#include <array>
using namespace std;  // 或者通过std :: array<int, 5> ai使用array
array<int, 5> ai = {1, 2, 3};  
//array<typeName, n_elem> arr   n_elem只能是常量

array类是固定长度的数组,要使用也需要头文件和命名空间std。

第5章. 循环和关系表达式

1. for 循环

赋值表达式的值定义为左侧成员的值。

y = (x = 14); // y的值是14

前缀递增、减和解引用运算符优先级相同,按从右到左的方式结合,后缀递增、减优先级高于解引用。

int *pt = NULL;
int a[2] = {1, 2};
pt = a;
int m = *++pt;  // pt指针先递增后解引用,m = 2;
--pt;
int n = *pt++;  // 因为后缀作用,先赋值,后pt指针递增,而不是值。
                // n = 1, pt指向a[1]

在循环块中定义的变量会隐藏外部的同名变量,在块外,外部变量再重新使用。

int x = 10;
for (int i = 0; i < 3; i++)
{
    cout << x << endl;  // x =  10
    int x = 20;
    cout << x << endl;  // x = 20
}
cout << x << endl;  // x = 10

逗号运算符使得多条语句放在 C++ 句法只能放一条语句的地方。逗号运算符保证从左到右的按顺序计算,即先计算第一个表达式。逗号表达式的值是最后部分的值。

int n = (1, 2, 3); 
cout << n << endl;  // n = 3

for 循环中的三个表达式都可以省略,省略测试表达式时循环会一直进行下去。

字符串数组名与字符串常量本身都表示它们的地址。

char ch[] = "go to sleep";
ch == "mate";  // 比较二者地址是否相同

strcmp(str, str2)函数比较两字符串大小(输入指针),按字符逐字比较(ASCII码),前者比后者小,函数值为负数,两字符串相同,函数值为0,否则为正数。

string类字符串可以直接使用关系符比较字符串。

2. while 循环

clock() 函数返回一个 long 或其他类型的值,单位不定,可能是秒。头文件ctime定义了一个符号常量CLOCK_PER_SEC ,它指系统时间单位为单位的时间,CLOCK_PER_SEC乘以 clock() 的返回值,可以得到秒数,并定义了clock_t 为 clock() 的返回类型的别名。

类型别名有两种方式,#define 预处理器以及关键字 typedef,预处理器方式可能会出问题。

#define CHAR_POINTER char *
typedef char * pt;
pt p1, p2;  // p1, p2为pt类型变量,pt是 char 指针类型,所以p1 p2都是char指针
CHAR_POINTER p3, p4;  // 相当于char * p3, p4, p4是字符变量,不是指针

3. do while 循环

至少执行循环体一次。

4. 基于范围的 for 循环

该方法是C++11新特性,对数组或容器类的每个元素执行相同操作,若要对数组值进行修改,使用引用。

double prices[3] = {4.8, 10.4, 7.99}
for (double x : prices)  // 依次打印prices每个元素
    cout << x << endl;
for (int x : {1, 2, 3})
    cout << x << ' ';  // 依次打印1 2 3 
for (double &x : prices)  
    x *= 0.8;  // prices每个元素缩小0.8倍

5. 循环和文本输入

cin 会忽略空格和换行符,从第一个字符开始,在输入回车时才会发送给程序,之前字符在缓冲区。C++函数重载允许多个同名函数,只要函数参数列表不同就行,如 cin.get() ,可以有两个参数、一个参数或没有参数,这是三个不同的同名函数。cin.fail() 和 cin.eof() 函数检查输入是否是 EOF(ctrl+z和enter(windows下)),是的话,都返回true。

cin.get(ch) 返回一个 cin 对象,istream 类提供了函数将 istream 对象(如 cin)转换成 bool 类型(cin 需要为 bool 时自动调用),可以以此判断输入是否是EOF。

while (cin.get(ch))  // 输入的ch是否是EOF,是eof,函数返回false

cin.get(无参数)返回char类型。

6. 嵌套循环和二维数组

初始化二维数组时,全用逗号。

int buts[2][2] = {(1, 2,), (3, 4)}; // 都是逗号
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值