从人类第一门高级编程语言Fortran开始,那些远古大神们变想着开创出一门更好压榨硬件性能,兼容性更好,编写程序更加流畅方便的语言,最终C语言应运而生,C语言适逢Unix操作系统诞生,C自然与Unix渊源不浅,而现代所有的操作系统OS基本均可以追溯到Unix上,无论是制霸服务器的linux,还是微软的window,亦或是macOs,这些OS均与Unix有关。而凭此C语言便有了C生万物的名号,只要用到现代操作系统就一定会有C语言的存在,所以C语言也成为大多数人学习的第一款编程语言,C便是道家“道生一”中的那个”一“,有了C语言的底子,学习其他语言也会事半功倍,可触类旁通。
我对C语言的认识可追溯到大学的一年级,那时由于学校C语言老师的水平使得我对C语言可谓一塌糊涂,简直如读天书,后学习单片机结果自然也是可想而知,找工作便因此碰壁,被HR评价为基础薄弱,屡屡碰壁自然便有了重新拾起C语言的念头,恰巧在B站上有幸遇到当年学习java语言的翁恺老师的C语言程序入门课程,便将自己之前所学的不成系统的C语言忘掉,重新开始。此帖便为我学习C语言的感想整理,以便日后回顾。(ANSI与C99以及C11为主要的三大版本,其中有些地方细节略微不同,我主要学的是C99)
本次学习所用集成开发环境IDE为DEV C++5.7版本。
C语言最初接触的一定是从“Hello World!”开始。在此之前我们打开DEV C++新建项目创建源代码,映入眼帘的应该是整个程序的大框架:
【md】#include <stdio.h>
int main()
{
return 0;
}
在这个框架里,#include <stdio.h>表示的是头文件,这个是必备的它包含有标准输入输出格式的原型,只有引用此头文件我们之后的scanf()&printf()才可以使用。int表示的是整型变量,main代表函数入口,其实在main这里有个函数预处理的过程,我们的shell用来找到main函数并且进入,且由于此函数是整形int的故需要返回值,也就是如下的return 0,直到这里我们已经介绍到了C语言的变量、函数的概念。
下边代码便是经典Hello World!的输出,其中有pringf()函数用来输出。
include <stdio.h>
int main()
{
printf("Hello World!");
return 0;
}
变量定义的一般形式是<类型名字><变量名称>;【注意C语言中一个语句的完成后边必须加一个分号】【变量的名称由数字、下划线、字母构成,其中变量名称不可以数字开头】
我们的C语言有许多保留字,这些保留字不可做为自己设置的变量名称。
Column 1 |
Column 2 |
Column 3 |
Column 1 |
Column 2 |
Column 3 |
auto |
break |
case |
short |
long |
register |
char |
const |
continue |
return |
signed |
unsigned |
default |
do |
double |
sizeof |
static |
struct |
else |
enum |
extern |
switch |
typedef |
union |
float |
for |
while |
void |
volatile |
inline |
goto |
if |
int |
restrict |
赋值运算符=,自此我们已经可以进行变量的初始化<类型名称><变量名称>=<初始值>;
C是一种有类型的语言,所以定义变量的时候必须定义它的类型,而且一旦确定变量的类型后,此变量便只能写入它定义的类型,如果不符合会报错。
在上述的保留字中有一个const,const是一个修饰符,表示为不可修改的常量,const常量的名称一般为大写来强调。
const int A =9;//这表示A是一个常量。
A = 10;//这是错误的,因为A为常量不可修改
下边代码是两个数字相加
int a;
int b;
printf(请输入两个数:");
scanf("%d %d",a,b);
printf("%d+%d=%d\n",a,b,a+b);
其中\n为换行符。【注意%d %d之间必须是空格,否则的话会出错】
我们已经知道了int为整型,我们还有float为浮点型也就是小数型,double为双精度型,对此输出时候对应不同的格式。
int a;
float b;
double c;
scanf("%d %f %lf",a,b,c);
printf("%d %f %f",a,b,c);
运算符,指进行运算的动作,比如+-*/%=,赋值符号=也是运算符,在运算符左右的是算子。
需要注意的是复合赋值的时候,两个=之间不能有空格;递增递减运算符的算子必须是变量否则没有意义。
++为递增运算符,--为递增运算符;cnt++与++cnt有细微的不同->cnt++为后缀表示cnt加一,表达式的值为cnt原来的值;++cnt表示cnt加一,表达式的值为cnt加一以后的值。--同理。
所有的事物进行必须先进形条件判断,符合执行一条语句,不符合执行另外一条语句,比如买票的时候只有我的金额A>票价B时,售票机才会给我票以及找零,否则的话会要求我继续投币,而这便用到了条件语句:
在if后边的()里边应该是判断条件,而在C语言中关系运算符的结果为1或0;【JAVA中是boolean值】
此时我们便有了优先级:算术运算>关系运算>赋值运算。if-else的良好习惯是加{};【注意】else只与最近if相关,与缩进没有关系。
表示分段函数的时候我们用到了级联的if-else:
If( exp 1)
{str1;}
else if ( exp 2)
{str 2;}
else
{str 3;}
多路分支一般使用switch-case:
switch (type){
case 1:break;
case 2:
case 3:break;
case 4:break:
default:
}
【注意】case并没有分割,只有遇到break;才会不执行case,我们可将case视为路牌。假如进入case 2会继续执行case 3然后才跳出。
while与do-while循环:do-while先执行然后判断条件,while先判断后执行,二者相差一次有细微差别。【可自行画出流程图比较】
do{
<循环体语句>
}while(<循环条件>);
【*注意*】循环函数的循环体内一定要有改变条件的机会
测试程序常使用边界数据,也就是特殊的数据,如有效范围两端的数据、特殊的倍数等,个位数、10、0、负数。
测试时候常用的小套路:printf("in loop/here");
int x;
int ret = 0;
scanf("%d",&x);
int t=x;
while (x>1){
x/=2;
ret++;
}
printf("log2 of %d is %d",t,ret);
|