如何系统学习C 语言(上)之 基础篇
大话C 语言(一)
初识C 语言
老实说,上大学之前我根本不知道什么是C 语言,所以当初学校开设这门课时,我是充满了好奇,所以当初我翻阅了大量的C 语言入门书籍,千篇一律,都是从一些概念、术语和理论讲起,没看多久就会头晕眼花,想睡觉。或许是对历史特感兴趣吧,有两点倒是奇迹般的记在了脑海中:1,C 语言的创始人—— 来自贝尔实验室的丹尼斯.里奇,于1972年发明了C 语言,被称为C 语言之父; 2,C 语言的标准:我当时就想,秦始皇当年统一中国后,他立即进行了“ 书同文,车同轨,统一度量衡”,那使用C 语言的人这么多,如果不同的使用者没有一个共同的标准,那也不可能使得C 语言常年霸占语言排行榜榜首。C 语言的诞生比较久远,在它的发展过程中出过很多标准,目前主流的应该是“C 99” 标准。
C 语言的特点
C 语言程序设计就是结构化程序设计,它的主要观点是采用自顶向下、逐步细分和模块化的程序设计方法,使用顺序、选择、循环三种基本控制结构来构造程序。
世间万物都有两面性,C 语言既有简洁性、灵活性、高效性等优点,又有如 若标识命名不得体,代码编排不规范,使用了野指针,出现内存泄漏等就会使得它原本的优点变成糟糕的缺点。
为何学习C 语言
我们天天使用的操作系统,数据库,游戏引擎等大多都是使用C 语言实现的,还有很多经典算法、框架也是用C 语言来编写的。除此之外,在已经进入了“物联网”时代,嵌入式开发已经非常广泛,学好C 语言也是为嵌入式开发打基础。同时只有当我们懂得了C 语言面向过程的结构化程序设计后,当我们在继续学习其他像Java 这样基于面向对象思想的语言时,我们才能更好的真正理解它。
C 语言基础
1,基本数据类型
C 语言里面有不少数据类型,这里先建议大家从最简单的三类基本数据类型开始了解:整型、实型与字符型。
2,常量与变量
从名字上我们就可以看出他们之间是互斥的关系。“常”有恒久的意思,即在C 语言中能够保持恒久不变的量就叫做常量,反之,若其值能够发生变化的量就称为变量。
常见的「常量」有:整型常量、实型常量、字符常量、字符串常量等;「变量」与常量除了其值是否能发生变化之外,两者之间的形态也有所不同。常量通常以值得形式存在,而变量看上去却像一个“容器”。不同类型的变量就像不同大小的“容器” ,里面可以放置不同类型和大小的数据。
3,C 语言运算符
什么是运算符呢?当然是能进行相关运算的一些符号啦!就像小学数学里所学到的“+、-、×、÷”四则运算符。C语言中还有大量的运算符,这些运算符若从所需要的操作数个数上看,可分为一目、二目和三目运算符。例如赋值运算符,它需要左右两个操作数,所以它就是二目运算符;对于用作说明一个数是正数还是负数的正号运算符“+”和负号运算符“–”,由于它只需要一个操作数,所以它就是一目运算符!至于三目运算符,就是同时需要三个操作数了。其实C语言中只有一个三目运算符,物以稀为贵,下面就重点说一下~ 不过先提醒一句,C语言中的所有运算符都需要使用英文字符,千万不要使用中文的标点符号了(初学者常犯的错误)。
条件运算符: “?:” —— 一个英文的问号和一个英文的冒号,使用方式如下:
操作数1 ? 操作数2 : 操作数3
那这个运算符如何使用呢?简单的说就是,根据操作数1 是真是假这个条件,来决定结果是操作数2还是操作数3,二者必选其一。如下例:
int a,b;
a= 1 ? 10 : 100; //条件运算符的结果为操作数2的值
b= 0 ? 10 : 100; //条件运算符的结果为操作数3的值
4,标准 I/O 函数
一个好的程序应该会将运行的状态和执行的结果以信息的形式告知用户,甚至在某些情况下会要求得到用户的特定信息,这种与程序进行交流的行为就称为交互。
我们把一个程序获取用户的信息称为程序的输入,将信息告知用户称为程序的输出,拥有这种功能的函数就称为I/O函数(Input/Output),即输入/输出函数。如果是通过控制台窗口来完成这些I/O操作的,即为标准I/O函数,C语言中有许多标准I/O函数,其中使用最广泛、功能最强大的是printf函数和scanf函数了。
C 语言流程控制
大家是否记得这样一个经典小品呢?是有关脑筋急转弯的,其中有宋丹丹问赵本山:“把大象装进冰箱需要几步?”。赵本山顿时一懵,答不出来,宋丹丹笑着说:“只需要3 步:第一步打开冰箱门,第二步把大象装进去,第三步把冰箱门关上。” 惹得观众哄堂大笑····
为了简单起见,下面直接通过简单的实例来体会如下3 种结构: 顺序结构、分支结构和循环结构。
1,顺序结构
顺序结构是最简单的一种流程结构,它采用自上而下的方式逐条执行各语句。如下:
#include<stdio.h>
int main(){
int a,b; //定义整型变度
float res; //定义单精度变量,保存结构
printf("Please input two integer:
"); //提示输入
scanf("%d%d",&a,&b); //获取用户输入
res=(float)a/b; //计算结果
printf("a/b = %.2f
",res); //输出结果
return 0;
}
2,分支结构
C 语言的分支结构可以控制程序的部分流程是否被执行,或是从多条执行路径中选择一条来执行。
#include<stdio.h>
int main(){
int score; //保存分数
printf("Please enter a score between 0 and 100:
");
scanf("%d",&score);
if(score>=90)
printf("A
");
else{
if(score>=80)
printf("B
");
else{
if(score>=60)
printf("C
");
else
printf("D
");
}
}
return 0;
}
用另外一种分支语句(switch…case) 来实现:
#include<stdio.h>
int main(){
int score; //保存分数
printf("Please enter a score between 0 and 100:
");
scanf("%d",&score);
printf("Grade:");
switch(score/10)
{
case 10:
case 9:
printf("A
");
break;
case 8:
printf("B
");
break;
case 7:
case 6:
printf("C
");
break;
default:
printf("D
");
break;
}
return 0;
}
3,循环结构
循环结构平常用的比较多,下面就列举循环结构样式:
1,while 语言
while(表达式)
语句
2,do...while 语句
do{
语句
}while(表达式);
3,for 语句
for(表达式1;表达式2;表达式3)
语句
注:for 语句小括号中的3 个表达式根据需要是可以省略掉其中一个、两个,甚至是全部都不要也是OK 的~
函数
就跟玩积木一样,一座壮观的城堡是有许多块不同的小积木搭成的,一个大的程序也是由若干个小的子程序构成的,这种以大化小、化整为零的程序设计过程就是模块化,而那一个个模块就是我们这里所说的主角—— 函数。
1,函数的定义
就像变量在使用前是要定义的一样,函数在使用前也是需要定义的。函数的定义格式如下:
数据类型 函数名 ([数据类型 参数1],[数据类型 参数2]...)
{
语句
}
关于自定义函数的两个注意点:
- 在c 语言中,函数是不允许嵌套定义的,即不能在一个函数中定义另外一个函数,所有的函数都是平行关系、平等的地位。但可以在一个函数中调用另外一个函数。
- 特别需要注意你定义的函数所在的位置,如果函数的定义是在函数调用代码之后我们还要进行函数声明,否则在编译时会报错。
2,函数的分类
从函数的撰写者的角度,可以把函数分为库函数和自定义函数;从有无返回值的角度,可以分为有返回值函数和无返回值函数;而从函数有无参数的角度,还可以把函数分为有带参函数和无参函数。
上面说的这些基本就是些简单的概念,写出来的唯一作用就是提醒大家回想一下,加之篇幅限制,所以这里就不在给出具体实例进行分析了~~~
3,递归调用与递归函数
递归调用的原理很简单,就是函数的自身调用。他其实是一种特殊的函数嵌套调用。为了防止死递归的发生,需要有效的控制递归调用,那怎样才能让递归调用终止呢?那只有依靠我们的老朋友——return 语句了呀~
那下面我们自己编写一个递归函数实现一个求和的小功能吧
//编写一个递归函数,能够计算1~n 的累加值,其中n 的值大于等于1
int sum(int n){
if(n==1) //若n 的值等于1,则表示求“1-1”的累加和
return 1; //通过return 语句返回1,并终止递归调用
return sum(n-1)+n; //若n 的值不为1,则进行分解
}
4,库函数
如求幂、平方根、三角函数等我们就可以调用c 语言的数学库函数即可,只需要包含一个”math.h” 这个头文件,就可以使用这些和数学有关的库函数啦。类似的还有”时间函数”、”随机数函数”、”字符处理函数”(包含“ctype.h”头文件) 等等。
C 标准库中的函数有几百个之多,更多的库函数需要我们在编程中自己去学习和研究。毕竟库函数都是大师们的精华之作,经历了千锤百炼,多多熟悉和掌握它们,我们会受益匪浅的 ~ ~