概述
C语言入门基础知识
- 一、计算机眼中的数字
- 1.二进制数的换算
- 二、计算机的内存
- 1.内存的基本单位bit
- 2. 内存大小的换算
- 三、C语言是什么
- 1.一门语言
- 2.main函数-程序的入口
- 四、常见数据类型
- 1.整型
- 2.浮点型
- 3.变量的定义方式
- 五、常量和变量
- 一、常量
- 1.字面常量
- 2.常变量
- 3.标识符常量
- 4.枚举常量
- 二、变量
- 1.全局变量
- 2.局部变量
- 3.变量的使用
- 4.变量的作用域和生命周期
- 六、字符与字符串
- 1.字符
- 2.字符串
一、计算机眼中的数字
- 二进制数的换算
通常再生活中我们所使用的是十进制数,数字都是0~9这十个数字,除开数学领域外,普通人几乎不会涉及到其他进制的应用,正因为十进制在生活中的使用的快捷性和实用性,人类对其的应用非常广泛。
而对于计算机来说,它认识哪些东西呢?
相信大家都知道,计算机中的一切数据其实都是由1和0组成的,也就是说计算机所认识的数字只有1和0,与我们习惯使用十进制数一样,计算机所使用的数字也与计算机的组成息息相关。电路可以说是计算机最重要的元件,而每一条电路都只有两种状态:开或者关,两种状态恰好与1和0相对应,这也就解释了计算机使用二进制的原因。
1.二进制数的换算
我们如果想将二进制数与十进制数互相转换,那该如何实现呢?
下面我会用例子给大家说明
例:二进制数 ‘1010’ 如果转化为十进制数是多少呢?
运用类比思想 ,我们可以想:十进制数例如 ‘121’
个位上1的权重为10的零次方
十位上的权重为10的一次方
百位上的权重为10的二次方,于是可以表示为
1*102+2 *101+1 *100 运算结果是 121。
所以对于‘1010’
最低为为第一位,则第n位的权重位2的n-1次方,于是可表示为
1 *23+0 *22+1 *21 +0 *20运算结果是 10。
即等于十进制的10.
而对于二进制数的各种运算就不做详细阐述了,运用类比的思想,将十进制数的运算方法照搬过来,其实也就是二进制数的运算方式了。
二、计算机的内存
1.内存的基本单位bit
通常我们的电脑有32位计算机和64位计算机,而这里的‘位’到底是什么呢?
这里所说的位数其实是计算机的地址线根数,而我们知道每根地址线会存在两种状态,即正和负,这些所有的地址线的状态则可以表示为很多个二进制数。
在高中数学中我们学习过排列组合,因此不难知道,假如地址线有x根,则这些地址线状态总共就有2的x次方种(每一根有两种,x根的组合).
这里我们以32位计算机为例子:
00000000000000000000000000000000
这里有32个0,代表32根地址线都处于负
我们一直对其进行加1的操作
00000000000000000000000000000000
(+1)
00000000000000000000000000000010
(+1)
…………
……
…
(+1)
11111111111111111111111111111111
最终变成了32个1组成的二进制数
那这个数为多少呢?
根据排列组合的知识很容易的出其值为
2的32次方-1=4294967295.
2. 内存大小的换算
仍然以32位计算机为例,可以知道32位计算机可以表示从0到4294967295这么多的数字。
在日常生活中,每户人都有属于自己的街道名称,门牌号等住址信息,这样就方便了我们寻找一个地址。
计算机也是这样,计算机中的数据也会有一个自己的”地盘“,并且拥有明确的编号,像下面这样每一个编号都代表着一块空间,于是内存就被分配了编号和大小。
|
00000000000000000000000000000000 | 0 |
---|---|
00000000000000000000000000000001 | 1 |
00000000000000000000000000000010 | 2 |
… | – |
11111111111111111111111111111110 | 4294967294 |
11111111111111111111111111111111 | 4294967295 |
– | – |
而这里的每一个编号所代表的空间的大小就为1个byte(字节)
不同内存大小的换算如下:
1pb=1024tb
1tb=1024gb
1gb=1024mb
1mb=1024kb
1kb=1024byte
1byte=8bit
通过这样的计算方法也可以计算出32位计算机的内存大小约为4GB.
三、C语言是什么
1.一门语言
既然是一门语言,那么如同日语、英语一样,是供人们之间交流的。
计算机语言就是人和计算机交流的媒介,它使得我们可以命令计算机处理执行一些我们想让他做的事。
2.main函数-程序的入口
1.main函数一定要有
2.main函数在一个程序中有且只有一个
框架:
int main()
{
return 0;
}
接下来我们在VS2019环境下证实一下
我们将断点设置在引用头文件的位置,看看其从哪里开始执行
调试后直接跳到了主函数内部的第一个位置
据此,我们可以证明main函数的确是程序的入口
四、常见数据类型
如果我们想表示一个人的年龄,那么可以用一个整数来表示,那如果想表示一本书的价格呢?那是不是就该用一个小数来表示了呢?于是浮点型和整型的数据类型便诞生了。
1.整型
数据类型 | 解释 |
---|---|
int | 整型 |
char | 字符 |
short | 短整型 |
long | 长整型 |
longlong | 超长整型 |
2.浮点型
数据类型 | 解释 |
---|---|
float | 单精度浮点型 |
double | 双精度浮点型 |
- 注意:双精度浮点型精度更高
3.变量的定义方式
通常定义一个变量的方式为: 数据类型+变量名;
以int为例
我们来定义一个名字为i的变量
int i=0;//使用int类型创建了一个变量i,
//i向内存申请了一块空间,空间名叫i
i=10;//向i空间内放入整型10
于是一个类型为int,名称为i的变量就创建好并被赋值啦。
注意:C语言没有字符串类型
五、常量和变量
一、常量
常量即为不能改变的量
- 字面常量
- 常变量
- 标识符常量
- 枚举常量
1.字面常量
- 字面常量就是直接写出来的数
例如:10,99等这样的数字
2.常变量
- 常变量即被const修饰的变量
例如:const int i=9;// i 就不能再被赋予其他值了,我们来尝试一下:
int main()
{
//const-常属性
const int i = 9;
i = 1;
return 0;
}
可以看到这里已经报错了
值得一提的是该定义方式下的变量为常变量,之所以叫常变量,是因为虽然不能再被赋值,但是 i 仍为变量,只不过具有了常属性,所以叫常变量。
- 注意:这里的 i 不能作为定义数组时的数组元素个数[i]
3.标识符常量
- 标识符常量是由#define定义的常量
例如:#define MAX 10
即定义了MAX为常数 10
在程序中遇到MAX后会直接将MAX替换为10
接下来我们来试试:
#include<stdio.h>
#define MAX 10
int main()
{
printf("%d", MAX);
return 0;
}
运行结果如下:
注意:这里的 a 能作为定义数组时的数组元素个数[a]
4.枚举常量
字面意思就可以知道”枚举“就是一一列举
并且由关键字enum修饰
接下来举一个例子:
#include<stdio.h>
enum sex //枚举关键
{
MALE, //表示枚举出来的可能值
FEMALE,
neutrality
};
int main()
{
enum sex a = MALE; //给相应的变量赋值
enum sex b = FEMALE;
enum sex c = neutrality;
printf("a=%dn", a); //依次打印出变量的值
printf("b=%dn", b);
printf("c=%dn", c);
return 0;
}
输出为:
a=0
b=1
c=2
表明在枚举时系统会按照顺序依次从0开始对枚举出来的MALE/FEMALE/neutrality的赋值
如果我们稍稍改变一下上面的代码,来看看它如何对枚举常量赋值。
#include<stdio.h>
enum sex
{
MALE,
FEMALE=2,
neutrality
};
int main()
{
enum sex a = MALE;
enum sex b = FEMALE;
enum sex c = neutrality;
printf("a=%dn", a);
printf("b=%dn", b);
printf("c=%dn", c);
return 0;
}
输出依次为:
a=0
b=2
c=3
可以看出其赋值是依次递增1的,如果人为的给其赋值,则下一个仍然是递增一个1
二、变量
- 全局变量
- 局部变量
- 变量的使用
代码块— { }
1.全局变量
全局变量—定义在块之外的变量
2.局部变量
局部变量—定义在块之内的变量
3.变量的使用
接下来举一个例子来更好的认识全局变量和局部变量
#include<stdio.h>
int a = 0;
int b = 0;
int main()
{
int x = 0;
int y = 0;
return 0;
}
a和b是定义在{ }之外的叫做全局变量
x和y是定义在{ }之内的叫做局部变量
C语言规定:定义变量必须在当前代码块的最前面(C99之前)
4.变量的作用域和生命周期
生命周期大家都知道指的是事物的存在时间,人的生命周期是从出生到死亡,而在我们活着的这段时间里我们可以做很多事情,而当我们的生命周期结束——即死亡后,便彻底消失在了这世界上。
因此,我们所创建的变量在内存中也有它的生命周期
在创建一个变量时就会占用一部分内存,这个变量的生命周期开始,而内存时有限的,我们不能只向内存索取,而不给予内存空间反馈,这样最终内存会耗尽。
因此,在变量使用结束后我们会销毁这个变量,并将空间还给操作系统,这样,一个变量的生命周期就结束了
作用域
我仍然使用人来作为例子,在人处于生命周期内,也就是活着的时候,我们可以做很多事情,旅游、学习,甚至时改变世界,因此我们活着时,所处的世界就是我们的作用域…
而当我们的生命结束,便无法对这个世界再产生影响,也就是脱离了我们的作用域了。
局部变量也是这样,变量的作用域就是其所在的块内,在它的块内时,它处于生命周期中,并且可以发挥作用。
因此局部变量的作用域:其所在的块内。
而全局变量就如同长生不老的神一般,世界创世之初就存在,只有这个世界消失了,它才会跟着消失。
而对于全局变量来说它所处的世界就是一个工程,因此
全局变量作用域是整个工程。
总结:
1、局部变量的生命周期:进入作用域开始,出作用域结束
2、全局变量的作用域:整个工程
六、字符与字符串
- 字符
- 字符串
1.字符
字符:被‘ ’括起来的一个字母、数字或者是符号
例:‘a’,’c’,‘#’ 这些都是字符
- 可我们之前说了计算机只认识0和1两个数字,那么字符在计算机中是如何存储的呢?
我们从计算机的数据的存储方式来说:
数据在计算机上存储的时候,存储的是二进制的数,因此需要存储字符时,实际存储的是某一个数,也就是ASCII码值。
2.字符串
被” “括起来的一串字符,
例如:”hello world!“就是一个字符串。
接下来我将会使用一个代码讲述字符串一个很容易忽视的细节
int main()
{
char arr[] = "hello";
char arr1[] = { 'h','e','l','l','o' };
printf("%dn", sizeof(arr));
printf("%dn", sizeof(arr1));
return 0;
}
运行结果输出为:
6
5
通过上运行结果可看出可以看出,arr和arr1的大小是不同的。
表面上看好像上面两个数组中存放的都是 ‘h’ ’e‘ ’l‘ ’l‘ ’o’ ,但我们通过调试可以看到:
arr比arr1这里多了一个’ ‘(终止字符)
也就是说在字符串“hello”中实际在末尾还有一个’ ‘作为字符串结束的标志。
也就能解释在用sizeof对两个数组求大小时出现的大小不同的情况了。
除此以外还有一种情况让我们值得思考:
strlen函数是用于求出字符串的长度,并且不包括’ ‘,仅仅知道即可,目前不必深究。
那就是利用strlen函数求出arr和arr1的字符串长度,代码如下:
int main()
{
char arr[] = "hello";
char arr1[] = { 'h','e','l','l','o'};
printf("%dn", strlen(arr));
printf("%dn", strlen(arr1));
return 0;
}
运行结果输出为:
这里又是为什么呢?明明strlen求的是字符串的长度,与’ ‘无关了,为什么还会得出一个相差如此大的结果呢?
这就要从strlen的实现来解释了,strlen函数是从字符串的第一个字符开始,每跳过一个一个字符计数器count就会+1,直到遇到字符串结束标志为止。
而arr1在内存中的位置是随机的,无法确定arr1后面遇到的第一个’ ‘在哪里,所以strlen(arr1)是个随机值。
如果将上面的代码改为:
int main()
{
char arr[] = "hello";
char arr1[] = { 'h','e','l','l','o','