1.前言
经过上一个小项目的洗礼,如果你真的是0基础,可能会有点怀疑人生的感觉。
所以本章节暂时不做项目了,而是将前面重要的知识点再深入讲解一遍,给大家讲讲有哪些坑,同时也会添加一些后面可能会用到的新知识点。
前面的章节中,我用到了一些东西,在当时为了不过于陷进去,并没有深究,所以首先我们先来将前面提到过的一些东西,在这里好好的理一遍。
2.强制类型转换
如其名字,也就是类型之间的转换,但是要强制进行,如果不强制进行,就不会转换。
首先来看为什么需要强制类型转换,以及强制类型转换到底干了一件什么事情。
现在来观察下面这段代码:
#include<iostream>
using namespace std;
int main() {
char c = '1';
cout << c<<endl;
cout << (int)c << endl;
}
运行结果为:
1
49
这是为什么?明明是同一个变量c
,为什么通过强制转换,将char
转换为int
后,输出的值就不一样了呢?难不成强制类型转换还会改变变量的值不成!
但事实是,强制转换并没有改变任何值,它只是让编译器在解释这个字符c
时的方式发生了变化。
前面我提过一嘴,我们所能看到的一切字符都是通过一张表给映射出来的。
比如上面的代码就是通过ASCII码表映射出来的,更详细的内容可以查看:ASCII码表。
我们首先给字符变量c
赋值了一个字符 ‘1’
,但如果你用鼠标放在这个字符 1
上 ,你就会发现一件神奇的事情:
其实这个字符‘1’,是数字49
强制转换为而来的!
因为‘1’这个字符在ASCII码表中对应的数字就是49
,计算机本身存储的仅仅只是数字而已,就算这里写的char
类型,其本质上依旧只是数字。
唯一不同的地方在于输出,比如当cout
看到这个数字是49
,但由于它是char
类型,所以就将其输出为了字符‘1’,而如果是int
类型,那就会直接根据ASCII码表将其转换为字符‘49’,与数字本身的值相同。
比如:
int a=100;
double b=3.14;
如果像char
那样,直接将数字映射为字符的话,输出int
,就是一个字母,因为ascii
码表中数字100
对应的一个字母。
而double
,这种小数因为没有映射关系,甚至没办法输出成字符到屏幕上让我们看到。
所以为了能够让我们直接能够输出100
,都是需要将上面这些东西进行转换的。
比如数字100
,先拆成 1 0 0
三个字符,然后映射到ASCII
表,分别代表数字 49 48 48
,然后就可以直接根据这三个数字输出对应的字符了,也就能够输出我们在控制台上看到的100
。
综上我们可以得知,所谓强制转换,就是一个东西本来是可以有多种解释方法的,但编译器默认了其中的一种解释方法,这时我们就能够通过强制类型转换,来强制编译器将它解释为另外一种意思。
在C/C++编程中,强制类型转换我们会经常用到,请务必理解其精髓:给目标换一种解释方式。
更底层的原理,你还可以参考本站的另一篇文件:数据类型。
3.输入输出
在C/C++的学习过程中,最重要的一块就是输入与输出,但C/C++
在输入与输出这一块的坑那也是相当的多,且需要理解一些理念。
最常见的坑就是使用scanf
时,变量前面必须带取址符&
,但如果你要接受的是一个字符串又不用加,这是为什么呢?
这就是因为scanf
是根据变量的地址来找内存的,所以变量就得取地址,而字符串属于字符数组,其名字就代表数组的起始地址,所以不用加:
char c;
char buf[30];
scanf("%c %s",&c,buf);
其次就是这些众多的控制符,实在让人望而生畏,所以有了c++中的cin
,其目的就是为了简化这一步骤,它可以自己识别出变量的类型。
但cin
也有缺点,那就是如果输入的东西很多,它就会变得很长,与cout
一样,这就取决于你具体的使用场景了。
而C++中进行格式控制也会相比较于C要繁琐的多,比如要控制输出数字的宽度为5:
#include<iostream>
#include<iomanip>
using namespace std;
int main() {
printf("%5d\n",100);
cout << setw(5) << 100;
}