《C++ Primer Plus》学习笔记2
第五章 循环和关系表达式
===================================================================================================================
1、cout.setf(ios :: boolalpha)函数设置调用设置一个标记,该标记命令cout显示true和false,而不是1和0。
2、for循环中for(int i = 0;i < len; i++)这里的变量只存在于for语句中,也就是说离开循环后,这种变量就会消失。所以如果后面还需要用变量i,我们需要把i在循环之前声明。int i;
3、在同一条语句中,不要对同一个值递增递减很多次,这样会模糊。
4、前缀与后缀的格式
for(n = lim; n > 0; --n)
for(n = lim; n > 0; n--)
前缀和后缀最终效果是一样的,前缀效率比后缀高。前缀将值减去1,之后直接返回;后缀则首先复制一个拷贝,将其减去1,之后将复制的拷贝返回。
5、递增/递减操作符和指针
1)前缀递增、前缀递减和解除引用操作符的优先级别相同,以从右到左的方式进行结合
2)*++pt 先将++应用与pt -> 将取指针用在被增后的pt
3)++*pt 先取得pt指向的值,之后将这个值加1
4)(*pt)++ 首先对指针解除引用,之后再++
5)*pt++ 由于后缀操作符++优先级别更加高,这就意味将操作符用于pt,而不是pt,因此对指针递增,但是后缀操作符意味着将对原来的地址而不是递增后的新地址解除引用,也就是说*pt++的值为arr[2],但是执行结束之后,pt的值将为arr[3]的地址
6、注意区分操作符(==)与赋值操作符(=)不要使用=来比较两个量是否相等,否则往往会进入死循环,因为将一个非零值赋给变量或者数组元素,肯定为true
7、数组名是数组的地址,同样用引号括起来的字符串常量也是其地址。“mate”
8、strcmp()测试C-风格字符串是否相等
1)如果str1和str2相等 strcmp(str1, str2) == 0;
2)如果str1和str2不相等 strcmp(str1, str2) != 0;
3)如果str1在str2的前面 strcmp(str1, str2) < 0;
4)如果str1在str2的后面 strcmp(str1, str2) > 0;
9、区分下C风格字符和string类字符串的区别
for(char ch = 'a'; strcmp(word, "mate"); ch++)
for(char ch = 'a'; word != "mate"; ch++)
10、等待一段时间,编写延时程序
long wait = 0;
while(wait < 10000)
wait++;
11、do while循环
如果请求用户输入时,程序必须先获得输入,之后对它进行测试,我们这个时候就要使用do while
格式:statement1
do
statement2;
while(test_expr);
statement3;
12、区分原始cin输入和cin.get(char)进行补救
1)cin读取char值时,与读取其他类型一样,cin将忽略空格和换行符,所以输入中的空格没有被回显,当然也没有包含在计数内。
2)用cin.get(char)这个就会回显每个字符,并将全部字符计算在内,其中包括空格。
13、区分C语言环境下和C++环境下的cin.get()
C中cin.get(name, Arsize)
C++支持函数重载的OPP性,除了C那种方式还可以使用cin.get(char)
14、文件结尾条件
如果输入来自于文件,我们可以使用EOF,检测到EOF后,cin将两位eofbit和failbit都设置为1.
所以可以写成while(cin.fail() == false)检测EOF
在Windows系统中运行该程序,按下Ctrl + Z和回车键来模拟EOF的条件;UNIX和Linux用户应该按Ctrl + D
常见字符输入做法:
char ch;
cin.get(ch);
while(cin.fail() == false)
{}
15、通常EOF设置为-1,因为没有ASCII为-1的值
16、常见字符输入输出的方法
int ch;
while((ch = cin.get()) != EOF)
{
cout.put(char(ch));
++count;
}
这里一定要注意两个地方,①!=优先级别比=高,所以必须加上括号 ②用cout.put() 因为括号里面原型是char,所以我们必须将整型强制转化为char型。
区分下cin.get(ch)和ch = cin.get()
前者是将值赋给参数ch;后者是将行数返回值赋给ch,所以这里是整型。
17、二维数组初始化几种形式
1)char *cities[Cities]=
{
“…………”,
"…………",
}
2)char cities[][] =
{
{……………},
{……………},
}
3)string cities[Cities] =
{
"…………",
“…………”,
}
===================================================================================================================
第六章 分支语句和逻辑操作符
1、if ……
else if ……
else ……
2、字符函数库cctype
1)isalnum() 检测字母或者数字
2)isalpha() 检测字母
3)isblank() 检测空格或者水平制表符
4)iscntrl() 检测参数是控制字符
5)isdigit() 检测参数是数字
6)isgraph() 检测参数是除空格之外的打印字符
7)islower() 检测参数是小写字母
8)isprint() 检测参数是打印字符包括空格
9)ispunct() 检测参数是标点符号
10)isspace() 检测参数是标准空白字符
11)isupper() 检测参数是大写字母
12)isxdigit() 检测参数是十六进制的谁
13)tolower() 如果参数是大写字母,转为小写字母
14)toupper() 如果参数是小写字母,转为大写字母
3、 ?:操作符 这是C++中唯一一个需要三个操作数的操作符,这个适用于简单的关系和简单的表达式x = (x > y) ? x : y;
4、switch语句
switch(integer-expression)//常量
{
case 1: statement1(s);
break;
case 2: statement2(s);
break;
case 3: statement3(s);
break;
……
default: statement4;
}
注意break语句用来确保只执行switch语句的特定部分,所以我们可以通过对break的控制,来精致输出,也就说说如果case 1,case 2输出一样,我们可以
case 1:
case 2: statement1(s); break;
因为之前我们学习了枚举,所以我们可以用枚举量作为switch的标签。
如果既可以使用if else if语句,也可以使用switch语句,当选项不少于3个时,应使用switch语句
5、break跳出循环的剩余部分,到达下一条语句;continue跳出循环体余下的代码,并开始新一轮的循环。
===================================================================================================================
第七章 函数——C++的编译模块
1、要使用函数,必须要提供定义和原型,并调用该函数。
1)C++定义函数,分为没有返回值的函数和有返回值的函数,对于有返回值的函数,返回类型有一定的限制,不能是数组,但可以是其他任何类型——整数、浮点数、指针、甚至可以是结构和对象;注意但是C++可以将数组作为结构或对象组成部分来返回。
2)原型,一般一定需要,因为原型描述了函数到编译器的接口,避免使用函数原型的唯一方法是在首次使用函数之前定义它,但这并总是可行的。
2、函数参数,定义函数时候,如果函数的两个参数的类型相同,则必须分别指定每个参数的类型,而不能像发声明常规变量那样,将声明组合在一起。
void fifi (float a, float b)
void fufu (float a, b) (无效)
3、R=(51∗50∗49∗48∗47∗46)/(6∗5∗4∗3∗2∗1)
long double result = 1.0;
for(n = numbers, p = picks; p > 0; n--,p--)
result = result*n/p;
区分下(10∗9)/(2∗1)和(10/2)∗(9/1)
如果因数越多,我们第一种方法的中间值越大,容易溢出。
4、函数头
int sum_arr(int arr[], int n)
注意实际情况arr实际上并不是一个数组,而是一个指针,
int sum_arr(int *arr, int n) 在C++中,当且仅当用于函数头或原型中
int *arr和int arr[]的含义才相同,他就意味着arr是一个int指针;注意在其他的上下文中,这两个东西的含义是不相等的。
5、数组和指针两个恒等式
arr[i] == *(arr + i)
&arr[i] == arr + i
记住,将指针(数组名)加1,实际上是加上了一个与指针指向的类型的长度相等的值,对于遍历数组而言,使用指针加法和数组下标是等效的。
6、为了将数组类型和元素的数量告诉数组处理函数,我们需要通过两个不同的参数来传递给他们void fillArray(int arr[], int size)
而不要试图使用方括号表示法来传递数组长度
void fillArray(int arr[size]); (无效)
7、使用数组区间的函数
for(pt = begin; pt != end; pt++)
total = total + *pt;
end-begin是一个整数值,等于数组的元素的数目。其实这就是指针的减法规则
8、如果数据类型本身并不是指针,则可以将const数据或非const数据的地址赋给指向const的指针,但只能将非const数组的地址赋给非const指针。
9、区分下指向const的指针和const指针
1)int gorp = 16;
int chips = 12;
const int p_snack = &gorp;p_snack = 20; (无效)禁止修改指针指向的值
p_snack = &chips;(有效) 指针可以指向另一个变量
2)int gorp = 16;
int chips = 12;
int const p_snack = &gorp;p_snack = 20; (有效)可以修改指针指向的值
p_snack = &chips;(无效) 禁止改变指向的向量
10、函数和二维数组
int data a[3][4] = {{1,2,3,4}, {9,8,7,6}, {2,4,6,8}};
int total = sum(data, 3);
原型:两种方法
1)int sum(int (ar2)[4], int size);
2)int sum(int ar2[][4], int size);
11、将C风格字符串作为参数的函数
表示字符串的三种方式
1)char数组 char ghost[15] = "galloping";
2)用引号括起的字符串常量 int n = strlen("gamboling")
3)被设置为字符串的地址的char指针 char str = "galumphing“;
12、C风格字符串与常规的char数组之间一个重要的区别,字符串有内置的结束字符,这就说明我们可以不必将字符串的长度作为参数传递给函数,而函数可以使用循环依次检查字符串中的每一个字符,直到遇到结尾的空值字符为止。这里要注意包含字符,但不以空值字符结尾的char数组只是数组,而不是字符串。
(重要)处理字符串中字符的标准方式
while(*str)
{
statements
str++;
}
//统计字符串中字符ch出现的次数.cpp
int c_in_str(const char *str, char ch)
{
int count = 0;
while(*str)
{
if(*str == ch)
count++;
str++;
}
return count;
}
这里使用const好处很多,如果错误地址函数修改了字符串的内容,编译器将捕获这种错误。
12、返回C风格字符串的函数
函数无法返回一个字符串,但可以返回字符串的地址,这样做的效率更高,函数接收两个参数:一个字符和一个数字。函数使用new创建一个长度与数字参数相等的字符串,之后将每个元素初始化为该字符。
//创建一个含有n个ch的字符串.cpp
char *buildstr(char c,int n)
{
char *pstr = new char[n+1];
pstr[n] = '\0';
while(n-- > 0)
pstr[n] = c;
return pstr;
}
这里需要注意的是使用delete
13、结构体成员和
//时间相加.cpp
struct travel_time
{
int hours;
int mins;
};
travel_time sum(travel_times t1, travel_time t2)
{
travel_time total;
total.mins = (t1.mins + t2.mins)%60;
total.hours = t1.hours + t2.hours + (t1.mins + t2.mins)/60;
return total;
}
14、处理空间结构
//将直角坐标转化为极坐标.cpp
struct rect
{
double x;
double y;
};
struct polar
{
double distance;
double angle;
};
//将弧度值转化成角度值,以为着需要将弧度值乘以180/pi约为57.29577951
polar rect_to_polar(rect xypos)
{
polar answer;
answer.distance = sqrt(xypos.x * xypos.x + xypos.y * xypos.y);
answer.angle = atan2(xypos.y, xypos.x);
return answer;
}
15、传递结构的地址
//将直角坐标转化为极坐标.cpp
void rect_to_polar(const rect *pxy, polar *pda)
{
using namespace std;
pda->distance = sqrt(pxy->x * pxy->x + pxy->y * pxy->y);
pda->angle = atan2(pxy->y, pxy->x);
}
16、递归
与C语言不同的是C++不允许main()调用自己,这种功能叫做递归。
包含一个递归调用的递归
void recurs(argumentlist)
{
statments1
if(test)
recurs(arguments)
statments2
}
完结于2014.7.16 0:17