1.打开解决方案
因为上一章我们已经建立了一个叫Start C++
的解决方案,并在其中有一个叫day1
的项目,所以现在我们就可以直接打开它。
首先来到保存项目文件的位置:
这里的D:\Program
是我前一章节创建该解决方案时选的位置,然后找到和解决方案同名的文件夹:
其中以.sln
结尾的文件就是我们的解决方案文件了,直接点击它就会自动用vs打开我们上次创建的解决方案。
同时你应该也注意到了其它三个文件,既然看到了,这里也说明一下。
.vs
: 该文件为隐藏文件,如果你没有打开文件夹中查看隐藏文件选项,是看不到该文件的。
该文件是vs为该解决方案生成的配置文件,比如你上次打开了某个窗口,这次打开你发现窗口依旧还是打开的,连位置大小都没变,这就是这个文件夹的作用了。
day1
:该文件夹就是我们创建的项目,里面存放着我们写的源代码文件。
比如上一章我们写的main.cpp
文件就在该文件夹里面,如果后面在该解决方案内再创建一个day2
项目,就会再多出一个文件夹day2
,里面就存放项目day2
的文件。
x64
:里面存放的是VS对源码进行编译后生成的文件。
没错,里面就有你常常看到的.exe
文件,不过暂时来说它还无法使用,直接点击会一闪而过,后面会解释原因。
当然了,上面只是较为粗略的解释,目的是为了让你有个大概的印象,不至于突然看到一大堆陌生的东西而陷入迷茫。
后面在有必要的时候,我会再对各个文件夹里面的结构进行讲解,不用着急!
这里需要注意,x64
这个文件之所以有,是因为我在VS中选的是x64
:
然后点击运行,就会出现x64
这个文件夹,如果你选的是x86
,就完全不一样了,关于x86
的内容,后面再讲。
2.创建新项目
首先右键解决方案->添加->新建项目:
依旧选择空项目:
现在我们就只需要写项目名称就行了,因为我们是在已有的Start C++
解决方案中创建一个项目,至于下面的位置就不建议更改了,默认即可,然后点击右下角的创建:
然后就可以看到现在解决方案里有两个项目了:
但你应该也注意到了,day1
项目名称明显比day2
的名称亮!
这就牵扯出了另一个知识点,一般一个解决方案里只会运行一个项目,正如我前面提到的QQ解决方案里面有很多.exe
文件的项目,解决方案是以项目为单位运行的。
而项目名亮的就是实际启动的项目,如果你此时点击运行,会发现day2项目没有任何作用,依旧输出的day1
项目中的内容。
所以我们需要更换启动的项目,方法很简单,直接右键day2
项目,点击设为启动项即可:
现在就可以看到day2
项目名亮了起来,day1
项目就可以折叠起来了,因为暂时用不上了:
为什么我要这么麻烦的新建一个项目呢?
毕竟我可以直接把day1
项目中的main.cpp
文件删除掉重建一个文件,又或者把原代码删除掉,重新写代码不就行了?
是的,这样完全可以,且没有任何问题,但我的目的是用最少的章节将你以后可能会遇到的问题进行说明。
3.学习输入
此时如果你直接点击运行,会发现直接报错:
为什么?上一章说过,每一个C/C++程序都需要一个最基本的结构,还能想起来吗?
而项目day2
我们还没有任何文件,所以需要新建一个叫源文件,一般我们取其名字为main.cpp
,除了鼠标挨着点击,是不是还有快捷键来着?Ctrl+Shift+A
此时我们可以看到上面有两个main.cpp
文件,一个是项目day1
的,另一个是项目day2
的。
虽然文件名都一样,但可以通过下图箭头所示看到源码所属的项目:
该文件名的正下方就是所属项目,就可以点击文件名旁边的X
,关闭day1
项目的文件。
然后我们就可以写出最基本的结构了:
本小结我们将要学习输入,C方式的输入为scanf
,C++方式的输入为std::cin
。
让我们来看看一个输入程序最基本的写法:
#include<iostream>
int main() {
int a;
int b;
scanf("%d", &a);
std::cin >> b;
std::cout << a << ";" << b << ";";
}
上面的代码实现了将我们输入的数字存储到a
与b
变量中,然后通过std::cout
将结果输出,运行一下试试?
会发现报错,遇到报错不要慌,直接点否,然后回到VS,看错误列表:
如果没找到这个界面,可以通过下图步骤找:
可以看到下面的错误信息:
错误 C4996 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
如果你英语不好,就使用翻译软件,程序员大多英语也一般,只是看多了便基本能看懂这些英语是什么意思,毕竟编程中用到的单词数量真的不多,至于实在看不懂的,都是用翻译软件直接翻译即可。
这里大概的意思就是scanf
这个函数不安全,请使用scanf_s
函数代替,或者使用_CRT_SECURE_NO_WARNINGS
禁用这个错误。
为了避免复杂化,我这里使用第二种方法,即使用_CRT_SECURE_NO_WARNINGS
来禁用这个错误。
在程序最前面添加下面这行代码
#define _CRT_SECURE_NO_WARNINGS
现在运行就不会报错了:
那上面这玩意是个啥?
它的名字叫做宏,暂时来说还没到它真正发挥用处的时候,所以这里暂时不提,如果你感兴趣,可以直接去本站其它文章了解:宏。
运行后,输入100 300
这两个数字,发现都能被正常输出,这说明我们成功将输入的值存入了a与b这两个变量中:
前期而言,我们只需要学会如何使用即可,下面来对比一下输入输出、C与C++的区别:
- C的输入与输出类似,都是第一个参数为字符串,字符串中包含要进行输入或输出的格式控制符,比如
%d
,不同之处在于scanf
需要在变量前面加上&
符号,该符号为取址符号,意思就是得到变量a
的地址,往该地址里面存数。 - C++的输入与输出也很类似,前面的
std::
一样,一个是cin
,一个是cout
,输入用>>
,输出用<<
。
这么看来, C++明显比C简单的多,因为可以不用自己指定数据类型,即不用指定%d
之类的东西。
但如果输入或输出的变量多了之后,可能你又会觉得C比较简洁,这个完全可以看自己个人喜好选用。
如果你习惯于使用C形式的输入,即使用scanf
,那么后面的变量都应该为地址。
这句话的意思就是,请注意当你想要输入字符串的时候,即char
类型的数组,其变量名本身就是地址,不需要&符号!
4.学习变量
事实上,前面我们已经使用过了变量,就是我写的一堆a,b,c,d
等等。
当然,这样的习惯并不好,你应该尽可能使变量名能够见名知意,例如用 int time;
表示这是一个int
型变量,叫做time
,用于存放时间:
int time;
char c; //等等,int ,char 等是基本数据类型,而紧跟数据类型身后的就是变量名time, c
所谓变量名,通俗来说就是给内存取一个名字,方便你下次还能够使用它,比如你需要改变该内存的值,或者输出内存的值,就需要用到该内存的名字。
既然是变量,自然是可以变的:
int a=100;
a=50;
a=30;
最后的结果就是a=30
,意思就是名字为a
的那块内存现在存的值为30
。
既然是名字,肯定也有一定的规则,比如中文名的规则就是姓在前名在后,英文名的习惯便是反过来的,而编程语言中变量的取名规则相对固定,即使是不同编程语言,取名规则基本都是一致的,详情可以参考另一篇文章:常量与变量。
而这里我要讲的是另一个非常重要的点,那就是生命周期。
见名知意,就是变量能活多久?文章常量与变量中同样也有介绍。
但简单来说,可以总结以下规律:
- 变量只有在它所在的
{}
里面才能使用。 - 如果
{}
里面还有{}
,依旧可以使用。
举个例子:
#include<iostream>
int main() {
int a; //a在main后的大括号里面
a = 0; //同大括号,可以使用
{
a = 10; //内嵌大括号,依旧可以使用
}
}
特殊一点的就是,不在任何{}
里面,这称为全局变量:
#include<iostream>
int a; //全局变量,不在任何大括号里面
int main() {
a = 0;
{
a = 10;
}
}
全局变量,就可以在程序中的所有地方使用。
这里需要注意,前面说过,程序是从main
后面{}
中开始顺序执行的,另一层含义就是,你所使用的任何变量,在使用它之前是必须存在的!
举个简单的例子就是int a;
语句永远在a=某个数
之前,下面这样就是错误的:
划红线,代表vs
提示你这里出错了。
5.学习判断语句
判断语句的用途就非常广泛了。
上面不是刚学输入语句吗?如果现在需要你对输入的数据进行判断,比如当输入的数值大于50,就输出 大于50,否则,输出小于等于50。
这个时候判断语句就派上用场了,基本结构如下:
if(判断语句){
//如果判断语句为正,或者说判断语句不为0,则执行,否则不执行
}
举个例子:
if(a>50){
std::cout<<"大于50";
}
如果输入的数a大于50,则输出大于50,
但你很快发现,如果小于50怎么办?这就可以在后面跟上else
语句了,如下:
if(a>50){
std::cout<<"大于50";
}else{
std::cout<<"小于等于50";
}
意思就是如果数a大于50,那就输出大于50,否则输出小于等于50。
很简单对吧,但很快又有了新问题,如果我需要多级判断呢?比如还需要加上个:如果大于100,输出大于100 ,如果大于50小于100 ,则输出大于50小于100。
这就可以在if
与else
之间添加else if
语句了,如下:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
int main() {
int a;
std::cin >> a;
if (a > 100) {
std::cout << "大于100";
}
else if (a > 50) {
std::cout << "大于50小于等于100";
}
else {
std::cout << "小于等于50";
}
}
如果还有判断语句,也可以继续添加else if
,其后紧跟的小括号里就是判断条件,如果满足,就执行紧跟其后的大括号中的内容。
稍微总结一下就是,简单判断语句就一个if(){}
,()
中为判断条件,{}
中为满足条件后,要执行的语句。
稍微复杂一点的就是添加else if
语句,增加判断条件。
最后,如果上面都没有满足条件的,就可以用else
来执行紧跟其后的语句。
6.学习循环
说到循环,这可是个好东西啊,比如现在需要你输出1万遍“C++是世界上最好的语言!”时,你该怎么办?
按照前面学习的思路,可能你就得自己手写一万句printf
或std::cout
,这很明显不可能:
于是就有了循环,其目的就是为了解决这类重复的操作。
C/C++里面,简单来说只有两种循环,一种是while
循环,另一种是for
循环。
其中while
循环格式如下:
while(判断语句){
//当判断为真时,要执行的语句
}
该while循环并不像以前的输入输出以及if
语句等等,只执行一次就结束了。
因为它是为了解决循环问题嘛!如果执行一次就结束了,还怎么解决循环问题?
该语句的效果是:只要while
后面紧跟的判断语句为真(不为0则为真),他就会不停的执行后面{}
中的语句。
此时上面输出一万遍的任务就可以这样写:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
int main() {
int a = 10000;
while (a != 0) {
std::cout << "C++是世界上最好的语言!\n";
a--;
}
}
其中a--
为自减符号,当然你也可以写成 --a
,一样的效果,但这两者也有细微差别,主要体现在表达式中。
这个时候,浏览器就又派上用场了,试试搜索一下 --a
与 a--
关键字,学习C/C++,就得有这种专研精神!
这看上去是不是简便很多?可如果你悟到了“不为0则为真”这句话时,其实还可以这样写:
int a = 10000;
while (a) {
std::cout << "C++是世界上最好的语言!\n";
a--;
}
甚至还可以这样写:
int a = 10000;
while (a--) {