【无标题】

一、C语言是什么?
        C语言是是一门经久不衰的计算机编程语言,万物始于C,学好C语言,能让我们为编程之路打下坚实基础。(我也不知道写什么,反正非常重要就对了)


二、开发环境

1.编译器
        我们把计算机编程语言称之为高级语言,那什么是低级语言呢?

        在中学物理我们知道:电子元件只能传达"开"或"闭"两种信息,所以电子元件(即晶体管)之间也只能用这两种方式通信。人们把"开"用1代替,把"闭"用0代替。电子计算机在初期时,只能识别0和1两种信号,所以那个时候只有科学家才能进行编程工作,这在那时候是十分困难的。

        上面提到的0/1信号,正好为二进制提供了用武之地,所以我们把最基本的、计算机能够直接读取的语言称之为低级语言。

        在这里,低级语言就是一串由0和1组成的东西,它转换成汇编语言,进而转换成高级语言,才被我们大多数人学习。

        编译器的作用就是把上面的过程反过来,将我们人能看得懂、接近自然语言的、而且能写出来的高级语言转换成机器能够读懂的低级语言。

        笔者最初使用的编译器是Dev C++,然后是Visual  Studio 2019。我比较喜欢VS2019,因为它在我写代码的同时能用中文提醒我的错误,但有时候才vs不能通过的代码反而在Dev C++里能通过,所以目前我以vs为主。

        如果有同学刚接触C,我建议先使用Dev C++吧,熟悉一下编程环境,如果已经有一定基础了,直接上vs2019吧。

三、初始C语言
1.第一个C语言程序
下面以Dev C++为例

(1)先新建源文件:文件->新建->源代码

 (2)写预处理命令,写主函数,建立基本框架

         尖括号(<>)中的stdio.h叫标准输入输出函数,即standard input output.header

        #include是一种预处理命令,它的作用是找到尖括号(或者英文双引号)中的文件,并将它包含到当前文件,被包含的文件中的文本将替换源代码文件(就是我们正在编写的东西)中的#include指令。

         ​看到上面那段话是不是很懵呢,说白了:<>里面的东西有我们等下写代码要用的东西,它所包含的代码会帮我们实现某些功能,它只是个名字,实际上它包含了不少代码。因为那某个功能我们接下来要用很多次,如果每次都把<>里面的东西打出来,就太麻烦了!而#include就用一行代码代替了这么多代码,是不是方便了许多?

举个栗子 

         如果接下来我们要用到从键盘输入或从屏幕输出,那我们就需要#include<stdio.h>来简化我们实现输入和输出功能的步骤。

        这里说得有点啰嗦,我刚接触这个的时候很懵:为什么每个函数都要加上#include<stdio.h>呢?为什么啰嗦这么多呢:如果有初学者看到我的文章,那我希望他能懂:D

        忘了说了,第二种主函数这种写法已经是远古版本了,最好写第一种。

        一个程序/工程只能有一个主函数(  main()),它是程序/工程的入口。注意main不要写成mian!!

2.数据类型
char//字符数据类型//就是不是数字的字符
short//短整型//就是数字小(绝对值)的整数,很少用
int //整型//就是整数
long//长整型//就是数字(绝对值)大的整数
long long//更长的整型//很少用
float//单精度浮点数//就是小数
double//双精度浮点数//小数位数多的小数
§ 为什么会出现这么多类型?

——因为我们现实生活中要用到整数,小数呀

§ 那为什么整数有int 和 short 还用long、long long,小数有float、double这么多种类呢?为啥不只用一种数据类型来表示呢?

——这个问题问得好(精神分裂ing)。单看英文字母和中文字符的复杂程度应该不难猜想:不同字符在计算机中所占大小是不同的,让我简要介绍计算机中的储存单位:最小的单位是bit,8bit = 1Byte,1024Byte = 1KB,接着是MB,GB,TB等。bit(比特)是最小单位。这里说个题外话,不少人在办理宽带有这样的困惑:为什么我明明买的是200M宽带呀,为什么最高才十几二十兆每秒呢?原因是:运营商所宣传的200M宽带实际上是宽带接入的速率为200Mbps,这里的B指的是Byte(字节),换算下来200M宽带理论上峰速为25.6MB/s。这不重要,知道就好,让我们跳回来。事实上,不同数据类型在内存中所占大小是不一样的,如果用大小的盒子装蛋糕,蛋糕有大有小,难免造成空间的浪费,所以人们规定了不同的数据类型,以便空间被物尽其用。

        在这里有一个很重要的思想,我称之为黑屋思想:把内存想象成一个个小黑屋,里面存放着我们想要存进的东西,也存着我们不能动的东西,当然也存着我们想取的东西。

2.1 数据类型的长度


        这里用sizeof()判断数据类型或者表达式长度的运算符,sizeof()不是函数,后面会介绍(好像也没什么介绍的= =)。

        C语言规定sizeof(long long) >= sizeof(long),其他以此类推,上面的结果因编译器和操作平台而异。

3. 变量 && 常量
生活中的有些值是不变的(比如:圆周率,性别,身份证号码,血型等等)
有些值是可变的(比如:年龄,体重,薪资)。

3.1 如何定义变量

格式如下:变量类型  (空格)变量名(自己起);

        最好初始化变量,避免脏数据影响后续调试,如 int a = 0;如果变量名有实际含义,最好用对应的英文(再不行就拼音,或英文简写)表示,后续也会明白。  

3.2 变量的分类 
1.局部变量 && 全局变量

         顾名思义,全局变量就是整个工程都能用的,而局部变量只能在{}内部使用,这里的{}不仅限于主函数的大括号,在后面的循环或判断语句中的{}也同样适用。

//如果全局变量和局部变量名字一样呢?是谁起作用呢?

显然,在这里局部变量会覆盖掉同名的全局变量。 

        这里简要介绍printf(),scanf()函数,顾名思义,前者是打印,后者是扫描,读取(f是函数的意思),从键盘读取输入,它们是被包含在stdio.h头文件中的。gets() && puts()也用同样的功能,具体差异会在后续文章解释。

3.3 变量的作用域和生命周期
1.变量的作用域

        作用域(scope,这个词要记住,后面编译器报错可能会出现)是程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效/可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。

1. 局部变量的作用域是变量所在的局部范围。(就是大括号里边的变量只能在大括号里用)
2. 全局变量的作用域是整个工程。(就是大括号外边的变量在哪都能用)                    

2.生命周期

        变量的生命周期指的是变量的创建到变量的销毁之间的一个时间段
1. 局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。(大括号大括号!)
2. 全局变量的生命周期是:整个程序的生命周期。 (在哪都行!)   

§ 看完了吗?用人话来说作用域就是变量在哪能用,生命周期就是它啥时候产生,啥时候消失。

3.4常量
1.字面常量
        是指可以用字符串表示的常量,包括整型常量,字符型常量,字符串常量,也可以是结构型的符号常量。

2.const修饰的常变量
首先来看没有被修饰的变量:

显然,未被修饰的变量的值是可以被改变的

再来看被const修饰的变量

        编译器告诉我们,a的值是不能改变的,也就是说,它是个常量,但不完全是,人们把它称为常变量。原因是:用const修饰的变量只是在语法上将它作为常量,但它本质还是变量,了解即可。 

 (新增于22/10/3)

        关于“常变量”的理解:用 const 修饰的变量,无论是全局变量还是局部变量,生存周期都是程序从运行开始到运行结束,也就是说,使用 const 修饰过的局部变量有了「静态特性」。什么变量具有静态属性?我们知道全局变量是静态的,静态的生存周期就是程序运行的整个过程。但是一定要区分的是:用const修饰过的局部变量只是有了「静态特性」,并没有说它变成了「静态变量」。

        之所以把const放在最后,是因为理解它的「静态特性」需要理解全局变量和局部变量。

 3.#define定义的标识符常量


        看图里的代码可以知道:格式:#define 常量名 值,在这里常量名和值之间不需要等号。

4.枚举常量
#define MON  1
#define TUE  2
#define WED  3
#define THU  4
#define FRI  5
#define SAT  6
#define SUN  7
       假设我们要用到星期一到星期五7个变量,如果用#define的方法定义变量,我们需要用7行代码,而使用enum(枚举)常量能用更少的代码表示相同的意思。

enum DAY
{
      MON = 0, TUE, WED, THU, FRI, SAT, SUN
};
        第一个枚举成员的默认值为整型的 0,(在这里我用 = 0来表示,实际上它被省略了)后续枚举成员的值在前一个成员上加 1,以此类推。

当然我们可以在定义时修改任意枚举成员的值:

enum DAY
{
      MON = 1, TUE, WED = 100, THU, FRI, SAT, SUN
};
        对于没有指定值的枚举元素,其值为前一元素加 1。在这里TUE = 2, THU = 101,以此类推。

        枚举常量先介绍到这里,实际上初学者的后续项目中用得较少,至少我现在还没遇到过(大一期末)。

打印结果如下:

4.字符串 && 转义字符
4.1 字符串
"hello world!"
        形如这样被双引号扩起来的一串字符称为字符串。

        在vs2019编译器中键入以上代码,按下f10键,依次点击调试->窗口->监视。结果如图。

        我在定义数组时并未初始化数组大小,因为编译器会根据输入的内容判定数组大小。由监视窗口中的值和类型栏中可以看出,虽然显示的是相同的内容,但是由双引号引起的字符串多了一个'\0',它在数组中是有实际大小的。由于人们要对字符串进行一系列的处理,但是我们不是每次都能知道一个文本中的字符个数,若要对处理它,很难保证不越界且不浪费内存,于是人们想到将'\0'当作字符串结束的标志(它是一个转义字符,后面会介绍),这样人们在处理字符串的时候就不必担心数组越界和未知长度的问题了。

        接下来我们定义三个数组,arr1是一个字符串,arr2和arr3都是字符数组,它们的区别在于arr2没'\0',而arr3有,这样的区别会带来怎样的影响呢?让我们打印一下。 

       

        我们先看一样的arr1和arr3,在监视窗口中,它们包含的成员完全相同,当然,我们可以认为字符数组加上'\0'就是一个字符串,那为什么没'\0'的字符数组arr2显示出来但没完全显示出来呢?上面我们提到,'\0'是字符串的结束标志(这里恰好证实了字符数组加上'\0'就是一个字符串这一猜想),打印函数只有碰到'\0'才会停下来,arr2数组里并不包含,所以机器就一直找呀找,找到别的小黑屋里去了,最终出现烫烫烫这样的乱码字符,以后你还会碰到锟斤拷(笑)。

        用一张图简要表示数组在内存中是如何被处理的。 

4.2 转义字符
当我想打印路径c:\code\test.c,结果为什么不是想象中的样子呢?

        这里就不得不提一下转义字符了。转义字符顾名思义就是转变意思。
下面看一些转义字符。

\' 表示单引号'

\" 表示双引号"

\\表示一个反斜杠

\n表示换行

\r表示回车

\t表示水平制表符,相当于按下tab键,还有一些转义字符没有提及,因为刚开始用的很少

补充一下ASCII码表

        简单来说,因为机器内存中只能存储二进制0和1,所以当我们想要使用各式各样的符号时,只要使用对应的ASCII码,编译器会将它们转换成二进制编码,进而被机器识别。现在请将0,a,A对应的ascii码值记住。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值