C++ Primer Plus 学习笔记
本文是几年前学习C++ Primer Plus过程中整理的一些知识点,无意间翻到,没有什么技术含量,简单记录一下。
struct 类型加强
C++对C语言的结构体进行了重要增强:
- 定义变量时不需要使用
struct关键字 - 结构体内可以直接定义成员函数
第一章 - C++基础特性
作用域运算符的使用
namespace Maker
{
int c =30;
}
int main()
{
cout << Maker::c << endl;
}
//命名空间可以取别名,例如:
namespace Maker1 = Maker;
三目运算符对比
C与C++的三目运算符有本质区别:
/* C 语言实现方式 */
int a = 10, b = 20;
*(a > b ? &a : &b) = 100; // 必须通过指针操作
// 等号左侧需要可修改的左值,因此需要取地址操作
//-----------------------------------------
/* C++ 实现方式 */
int x = 10, y = 20;
(x > y ? x : y) = 100; // 直接赋值
// 返回变量引用(左值),类型安全且无需取地址
主要改进:
- 类型系统更严格,避免指针操作风险
- 返回值可直接作为左值使用
- 代码可读性更好,更符合面向对象思维
C++ 不能优化的情况
- 不能优化自定义数据类型
- 如果用变量给const修饰的局部变量复制,不能优化
- 编译器在编译阶段来优化数据
C和C++的区别
- C语言的结构体不能写函数,C++可以
- 结构体定义变量时,C++不需要加struct关键字
- 更加严格的类型检查
- const修饰的变量,C++有时没有内存,C语言的都有内存
- 三亩运算符返回值不一样
- 引用和C的指针功能一样
引用
引用是和C语言的指针一样的功能
引用是给空间取别名
引用的语法
//C语言中指针 int a = 10; int *p = &a; *p = 100; //这样输出a是100; int a = 10; int &b = a; //给a的空间取别名叫b,标志作用。现在a和b都代表那一个空间 b = 100; cout << a << endl; //输出为100 //C++引用的使用 void func(int &a) { a = 200; } void test02() { int a =10; func(a); cout<< "a= "<< endl; }引用的注意:
引用创建时,必须初始化 引用一旦初始化,不能改变他的指向 引用必须用一块合法的内存空间int a = 10; int &pac = a; //取别名 int b = 20; pac = b; //赋值操作 cout << &a << endl; cout << &pac << endl; //得出相同值
数组引用
int main()
{
int arr[] = {1, 2, 3, 4, 5};
// 第一种方法
typedef int(My_Arr)[5];
// 建立引用
My_Arr &arref = arr; // 建立引用,int &b = a;
// 第二种方法
// 直接引用
int(&arref2)[5] = arr; // int &b = a;
// 第三种方法
typedef int(&My_Arr3)[5]; // 建立引用数组类型
My_Arr3 arref3 = arr;
for (int i = 0; i < 5; i++)
{
cout << arref[i] << endl;
}
for (int i = 0; i < 5; i++)
{
arref2[i] = 100 + i;
cout << arref2[i] << endl;
}
}
使用const代替define
- define没有数据类型,const修饰的变量有数据类型,可以进行数据类型检查
- const修饰的变量有作用域,define不重视作用域,不能限定常量的使用范围
指针引用
//C语言版本
void func(char * *tmp)
{
char *p;
p = (char *)malloc(64);
memset(p, 0, 64);
strcpy(p, "小花");
*tmp = p;
}
void test02()
{
char *mp = NULL;
func(&mp);
cout << mp << endl;
}
//C++版本
void func(char *&tmp)
{
char *p;
p = (char *)malloc(64);
memset(p, 0, 64);
strcpy(p, "小花");
tmp = p; // 省了*
}
void test02()
{
char *mp = NULL;
func(mp); // 省了&
cout << mp << endl;
}

引用的使用场景
引用作为函数参数
void func(int &a,int &b) { int sum = a + b; cout << "sum= " << sum << endl; } void test01() { int a = 10; int b = 20; func(a,b); }作为函数的返回值
int &func2() { int b = 10;//注意1.不要返回局部变量的引用 int &p = b; return p; } int &func3() { static int a = 10; return a; } void test2() { int &q = func2(); q = 100; cout << q << endl; //输出100 func2() = 200; cout << q << endl; //-------上面是代码错误,只是编译器没有检测出来 //输出200,但是错误 cout << "func2= " << func2() << endl; //输出10,没有改变 func3() = 199; //注意2.如果要函数当左值,那么该函数必须返回引用 cout << "func3 = " <<func3()<< endl; //输出199,成功改变 }常量引用
//普通引用 int a = 10; int &ref = a; ref = 20; // int &ref2 = 10;//不能给字面量取别名 const int &ref3 = 10;//可以给const修饰的引用赋予字面量 // 编译器会把上面的代码变为:int tmp =10;const int &ref3 =tmp;
内联函数
inline int func(int x,int y)
{
return x < y ? x : y;
}
何时不会成为内联函数:
- 存在过多的条件判断语句
- 函数体过大
- 对函数进行取址操作
内联函数的好处:
- 有宏函数的效率,没有宏函数的缺点
- 类的成员函数默认加上
inline
第四章
程序执行的四步:预处理,编译,汇编,链接
每次读取一行字符串输入
getline ()
读取整行,使用回车键的换行符来确定结尾。使用 cin.getline 调用
注意:getline 不读取换行符,而 cin.get 的读取换行符
get ()
cin.get 调用 cin. get ( char , int )
注意:get 读取换行符,每次使用后要再使用一次 cin.get()来把换行符读取走
推荐使用 cin. get ()
何时使用句点运算符,何时使用箭头
如果结构标识符是结构名,则使用句点运算符;如果标识符是指向结构的指针,则使用箭头运算符。
第六章
6.7 输入验证实现
实现安全的数字输入循环:
for (int i = 0; i < Max; i++)
{
std::cout << "Round#" << (i + 1) << ": ";
// 输入验证循环
while (!(std::cin >> golf[i]))// 如果用户输入错误
{
// 重置输入流状态
std::cin.clear();
// 清除错误输入
while (std::cin.get() != '\n') {
continue;
}
std::cout << "Invalid input. Please enter a number: ";
}
total += golf[i];
}
#include<iostream>
const int Max = 5;
int main()
{
using namespace std;
int golf[Max];
double total = 0.0;
cout << "Please enter your scores you mast enter "
<< Max << " courses" << endl;
for (int i = 0; i < Max;i++)
{
cout << "Round# " << i + 1 << ":";
while (!(cin >> golf[i])) // 如果用户输入错误
{
cin.clear(); //重置输入
while (cin.get()!='\n') //清除输入
continue;
cout << "Please enter a number: ";
}
total += golf[i];
}
cout << "average score is: " << total / Max << endl;
return 0;
}
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 炸薯条的博客
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果