VS2019 C++编程学习问答——未完

写在前面

这篇博客是阅读《C++ primer》时的一些自我问答。
不得不说,这本书非常的棒。一点点地展开整个C++世界,并告诉你这些做法这些规定的缘由。之前我很喜欢慕课的那本C++教程,但现在觉得不如这本。之前由于听说,很难懂,又是大部头,800多页,就直接没打算。蝙蝠时期,由于困在家里,就想着从头读读看。结果找到宝了。
另一个亮点是,书中各种检索做的一目了然。很适合留在身边当工具书。
不过,需要注意的是,这本书有时候有些地方是比较难懂的,一是可以直接在vs2019里输入代码,看看IDE怎么报的错,二是可以做标记继续看下去,往往在几段后前面的疑惑就解决了(比如顶层const和底层const)。

vs下的调试界面输入如何结束?

while(std::cin >> value)
	...
return 0;

该段程序用于读取数量不定的参数。用空格或者回车隔开参数,全部输入完毕后,ctrl+Z,再敲回车,即可关闭 输入流。

如何在vs中实现文件重定向(从文件读入数据,输出流cout写入文件)?

移植性较高的方式是采用c++中的对文件使用的读写函数。不过,有时没那么高要求,可以直接改变命令行参数。
右键单击要改变的项目 -> 属性 -> 调试 -> 命令参数中改为 >data.txt
则该项目运行时的cout将输出到data.txt中,路径为项目所在路径。要改输入则改为 <in.txt。 注意,此处的箭头是与流运算符朝向相反的。

endl与\n的差别?

在输出中,都表现为换行。只是endl可以刷新缓冲区,保证没有字符因意外留在缓冲区,未来得及打印,主要用于保证程序的报错时能够准确定位。 \n则是普通的换行转义符。

C++11引入的列表初始化有何意义?

long double ld = 3.1415926536;
int a{ld};
int b = ld;

运行上面这段程序看报错信息就可以理解。a这一行会报错误,说明会信息丢失,而b这一行只是warning,也就是说 列表初始化组织了信息丢失情况下的编译,降低了程序错误运行的风险。

声明和定义的区别?

声明是指让程序知道有这个变量,定义则是指创建一个实体对象,并为其开辟存储空间。定义包含了声明。
纯粹声明,主要与关键字extern有关。用于在文件A中使用文件B中的变量。

extern int a;// 声明变量a
int b; //定义变量b

但注意,extern关键字的意义在于,多个文件共用一个变量,且变量不会被反复更改。因此 虽然extern int a = 5合法,但一般不会用,因为相当于是定义了。

命名规范

1.类大写字母开头,
2.变量全小写,
3.常量全大写,
4.单词之间用下划线_隔开。

显示访问全局变量

假设同时有局部变量a和全局变量a,在内层作用域,默认的a为局部变量a。此时若要使用全局变量a,则::a
一般没啥用,因为我们一般不会有同名的变量。

左值引用(lvalue reference)与指针

左值引用是通过将声明符写成&d的形式来定义引用类型,其中d是声明的变量名。(普通的定义里,声明符就是变量名。)

int &refVal = ival; // refVal指向 ival,是ival的别名

相比之下,指针有以下不同之处:
1.指针本身是一个对象,允许赋值和拷贝,在其生命周期里可以先后指向不同的对象。
2.指针无须赋初值,会有一个不确定的值。
指针的声明符为 *d。可使用解引用符 * 来访问指针指向的对象。

如何生成空指针

C++11以后,可以int *p = nullptr,也可以int *p = 0;另一种是 = NULL,需要包含头文件 cstdlib。不过不建议。
疑问 :51页 double* dp= &i是否合法?
答:合法但容易产生误导,比如double* dp,x,dp是指针,x是double基本类型。同理,double& 也合法。

复合定义的读法:从右往左,与变量名最近的代表其声明符,其余表示引用或指向的数据类型。如:

int *&r = p; // &说明r是引用,*说明引用对象是一个指针

该例中,r与p等价。*r 代表了 *p。

const限定符的使用

const用于定义一个不想被修改,修改了会有警告的变量。
基本语法:const int a = 10;
对a的常量赋值语句都会报错。故const对象必须在定义时初始化,初始化动作既可在编译时进行,也可以在运行时进行。
const对象的作用域仅为当前文件。
若需要在不同文件中共同使用一个const对象。则对该对象的声明和定义语句都需要变成 extern const

常量引用:

const int &r = i;

i既可以是double(因为编译时会强制类型转换),也可以是普通变量(无const修饰)。此时代表的意思为:r为i的常量引用,不可以通过r来修改i,但i可以通过其他方式修改。

常量指针

创建指向const的指针必须有const修饰。如:

const a = 5;
int *p = &a; //非法
const int *p = &a; //合法 

与常量引用相同,无法通过指针来修改指向的对象,不过可以将指针改为指向一个 非const。

const指针

const指针是指指针本身是个const,即无法重新选择指向的对象,至于const指针所指向的是不是const无所谓。通过const指针可以修改对象,只要对象不是const。

const int *const p = &i;

疑惑:以下定义有无不合法的

如何定义类型别名

新标准引入using的用法。

using ts = time_second;
ts a; //等价于 time_second a

在之前都是用typedef。

auto的使用注意

auto很方便,但要注意,如果参数类型不一样,必须分成小句子,用多个auto。如:

int i = 0;
const int ci = i;
auto &n = i,*p2 = &ci;// 该语句错误,因为i的类型是int,&ci类型是const int.而*和&是声明符的一部分,而非基本数据类型的一部分。

类型检验的方法:在VS2019中,鼠标悬停在变量上方即可。

string中字母的遍历方法

string ss;
for(auto &c : ss)

需要注意的是,c必须是引用类型的,否则修改的只是ss的一个复制体。

string遍历、vector遍历和迭代器差异

前两者基本一样,都可以用范围遍历for(auto a:b)来实现,迭代器在使用时需要注意,(*it)才表示元素,it仅仅是一个iterator,另外,(*it).men与it->men等价,都表示对成员的访问,比如it->empty()。

引用传递

C++中尽量多使用引用传递,而非值传递或者指针传递。这样可以节省时间。如果不想改变原有的数据,则可以使用常量引用。例子如下:

int reset(int &val){...}

int reset(const int &val){...}

此外,当需要输出多个变量时,可以将其加入到形参列表中,用引用进行数据传输。

疑问:请举出形参不能是引用类型的例子?

C++11新特性:列表initializer_list

该类型定义在同名的头文件中,使用时一般为:

void error_msg(initializer_list<T> i1) //T为列表项的类型
{...}

同其他的模版一样,该类型有迭代器的其他特性,如 size,begin,end。

返回数组指针

比如定义一个接受一个int实参,返回一个指向int[10]的指针,传统写法为:int (*func(int i)[10]);
而C++11允许使用尾置返回类型:auto func(int i) -> int(*) [10];
但我不太清楚为什么int*需要加括号。

不会做的习题

  1. P205 编写一个递归函数,输出vector对象的内容。

友元

当使用class后,所有成员默认为private,此时写于外部的接口函数如read,print等会没有访问权限,解决方法是在类内增加一条以friend关键字开始的函数声明。
但是这只是权限的声明,函数本身的声明仍然需要。一般友元函数的声明位置与类在同一头文件。

.和->的差别

在开源的C++代码中经常可以看到这两个的身影,给我们的感觉就是访问成员的运算符,好像两个都可以用,其实有点差别。
.是访问对象的成员,而->是访问指针的成员。
比如Pointcloud A用A.访问成员,而Ptr* A用A->访问

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值