本篇我着重写C语言的基础,不会很深入的讲,只是介绍C语言,想要认识C语言,本篇绝对会使你有所收获。在以后的篇章里会持续更新C语言的知识,是分开章节的细讲。好了让我们开始C语言之旅。
C语言是一门通用计算机语言,广泛应用于底层开发。
目录:1.数据类型
2.字符串
3.选择语句和循环语句
4.函数
5.数组
6.操作符
7.常见的关键字
8.定义宏
9.指针
10.结构体
一.数据类型
Char(字符数据类型),short(短整型),int(整型),long(长整型),long long(超长整型),float(单精度浮点数),double(双精度浮点数)
Char 就是一些字符例如:a,b,c,#,¥ 等
整型有四种 分别为 short int long longlong ,依据内存所占大小区分,这就是从小到大的排序。整型就是不带小数点的数。
浮点数 有单精度和双精度。字面上也不难理解,浮点数就是有小数点的数,单精度和双精度的区别在于小数点后的位数,分别为6位和15位。
变量和常量
变量和常量的理解:可以像数学里的函数一样,x,y,z都是我们所谓的未知量,并不晓得的它的具体值,但是它也是一个量,所以在计算机里我们需要给它一个初始值,这就是变量。
常量更好理解就是数学公式里的常数,有具体值。
/定义变量:数据类型+名称 例如:int a,float b,char c
变量又分为局部变量和全局变量,他们的区别在于作用域和生命周期,在这里引入作用域的概念:在任意一段代码中,若此变量是有效的,则称此变量在这段代码的作用域中,反之则不在。
/局部变量的作用域是变量所在的局部范围;全局变量的作用域是整个工程(代码)。
/生命周期:变量从创建到销毁的时间段。通俗讲销毁就是内存里没这个变量了。
从以上理解局部变量的生命周期仅仅是进入作用域到出作用域的时间段,而全局变量的生命周期则是进入程序的整个时间段。
/常量分为四种类型:
- 字面常量:很简单的说就是一个常数;
- Const修饰的常变量:如const int a;定义变量前加上const。常变量的意义在于使变量的值不再变化,使变量有了常量的性质。但需要注意的是,它本身还是一个变量,不能当作常量使用。
- #define 定义的标识符常量 :在main函数(主函数)前定义,如#define max 10;这样的用处就是在以下的程序里,max可作为常量使用。
- 枚举常量:直接用例子讲明白,enum(枚举的关键字)
如代码:enum sex
{ male,
Female,
Secret,} sex是枚举常量的名称,大括号里面的是新定义的枚举常量,它们默认是int型,并且有递加的规律,初始默认male为0;依次向下,female是1;secret是2。也可以在这里给与初始值,当然依旧满足递增规律。但需注意的是在其它代码里改变它的值是不可行的。如male =10;这是错误的。在大括号里面才可以初始枚举值。
二.字符串
字符串是用双引号括起来的一串字符,如”SLAKDJASLKDJAS”.需要知道的是在计算机中字符串后默认有’\0’,这是字符串结束的标志,并不算字符串的内容。
\在这里引入一个函数,strlen函数,strlen()用于计算字符的长度(字符的个数),它的计算规律是计算出\0前的字符个数。经常遇见错误的地方是在字符数组,数组会在下文提到,先简单介绍一下这个,char arr []={‘a’,’b’,’c’},字符数组里有三个字符但用strlen计算时却得到一个随机值,这是为什么呢?其实可以猜到,因为它没有\0,于是strlen找呀找呀,乱找啊!找到个\0,于是得出的必然会是个随机值,如果改成 char arr[]={‘a’,’b’.’c’,’\0’}就可以了。
/转义字符
有\?,\’,\\ 等等,为什么会有转义字符的出现呢?
它有俩种作用:1,做简单的指令 例如“\n”,换行,在printf()函数中体现作用;”\r”回车等等
2,打印一些特殊的字符,特殊在它们有一定的作用,导致代码无法有效打印,就是在printf函数中起作用,如想在屏幕上打出,“,如果写这样的代码 printf(“%c”,“”“);这必然是错的,所以转义字符的作用来了,printf(“%c”,”\””)。
所谓选择和循环语句,讲究的是逻辑,通常是写程序的框架,你的逻辑感越好,玩这两种语句就越6。
简单介绍一下:选择语句
有if-else,swich-case 俩类语句,
if语句中,if()括号内容为真就执行if下的语句,系统会默认执行if下的第一条语句,如果想执行多条语句,需要用{}括起来,if()括号内为假则if决定执行的语句不执行,转向执行else的语句。当然else可有可无,看自己所需而定。
基本逻辑就是:if判断这是真的,我就执行if下面的程序,不对我就不执行或者执行else下的程序。
Swich-case语句用于情况比较多的程序,比如一星期有七天,就有七种情况,如果用if-else语句会导致程序重复较多,运行不高效。Swich-case是专门针对着用情况较多的程序的。比如swich()括号内为case对应的情况,执行下面的case语句,case语句多用{}括起来,写成{case1 ;
Break;
Case2 ;
Break;
Case3;
Break
}这种形式,swich()括号里为1就执行case1;为2就执行case2。可能小伙伴不太理解其中的break,break就是跳出这个语句,举例说明,swich括号里为1,执行case1,要是没有break,就会一次执行case2,case3 但是给一个break就直接跳出,不再往下执行。
基本逻辑:swich()判断是那种case,是case几就执行case几,配合上break,让case们的执行更多样化。
循环语句:
有while();do-while;for()三种,在本文不做详细介绍,就简单的讲讲它的逻辑。
While()括号为真,执行下面{}内的程序,这点有点像if语句,区别在于,whle有变量再调整,括号内有一个变量,举例子就是变量 int a,初始值给0。While(a<10){a++;},这就是一个简单的循环,括号内a<10,会执行括号内的语句,同时a++(a+1)变量做出调整,当a不满足<10时循环结束。
Do-while型循环是指,do,一上来就do(做),一上来就执行do下面的程序,whlile()括号内判断还do不do,要是满足了,用do了,循环结束。这语言有的粗暴,但是应该很易懂把。
For()语句,就是while语句的缩合,for(初始变量;判断;调整变量)
循环语句就简单说到这,后期会细细的道来的。
四.函数
函数存在的目的就是简化操作步骤,很多步的操作,写一个函数就足够,之后需要这个函数,直接调用。其实C语言的发展也是这么个过程。有库函数和自定义函数。库函数就是官方直接编到c语言的函数,想用就直接引个头文件就能直接调用了。自定义函数就是我们自己写的函数,自己自用。
比如printf()函数,strlen()函数,printf的头文件是stdio.h,strlen的头文件是string.h。#include<>这是引用的形式。
自定义函数,比如我想做个加法程序,我要加一堆数,总不能一直定义变量,然后求和吧,于是我定义个加法函数。
Int add(int a,int b)
{ int z=0;
Z=a+b;
Return Z;
}
这就是个简单的函数,我们在程序中调用的时候,只需要 add(x,y),x和y是两个整型变量,这样就可以得到求和了。
五.数组
数组是有序的元素集合,数组可以储存一组相同类型元素的集合。比如要存100个整型变量,如果挨个定义变量是非常不方便的。但是利用数组却可以轻松的做到。Int arr[100]这就是定义了100个整型变量,当然我们也需要给其赋值,int arr[100]={1,2,3,4,5,6,7,,,,,,100}.根据元素的不同,数组也有分类:整型数组,字符数组,指针数组等;根据参数个数,可以分为一维,二维,三维。
/比如我只需要了解长度就够了,建立一个一维数组即可;我需要了解面积,也就是得知道长和宽,于是我建立二维数组 int arr[][];类比可知如果我想知道体积:长.宽.高。可以建立一个三维数组,int arr[][][][];这只是举了个小例子,希望帮助大家理解。
六.操作符
简单介绍一下操作符的种类
算术操作符:+,-,*,/, % ,数学运算分别对应加法,减法,乘法,除法,和取余数。运算规则也不完全和我们的数学一样,计算机中的除法还是有区别的,这个之后细讲。
移位操作符:<< ,>> , 这个移位操作符移的是二进制位。
位操作符:& ,^ , |
赋值操作符:= , += , -= , *= , /= , &= , ^= , |= , >>= , <<=
单目操作符:!,-,+,&,sizeof,~,--,++,*,(类型)强制转换。
关系操作符:>,>=,<,<=,!=,==
逻辑操作符:&&,||
条件操作符:表达式1?表达式2:表达式3 这个简单讲一下,就是表达式1做判断,如果表达式1判断为真,就执行表达式2,为假就执行表达式3。
逗号表达式:表达式1,表达式2,表达式3……
下标引用,函数调用和结构成员:
[] () . ->
七.常见的关键字
/所谓关键字,就是c语言本身使用,不能用作标识符,变量名等,有数据类型:int,float,char等;复杂类型关键字:struct,union,enum等;储存类型关键字:auto,extern,const等;结构型语句:if else,for,do,while等;还有预编#define
/ 在这里我想着重讲俩个关建字:typedef和static
Typedef可以看作一种类型的重定义,比如 变量 unsigned int a,无符号的整型变量a,直观的看这个变量是算长的,如果在程序中持续要用,那必定敲的时候费时,所以 typedef它来了,这样用,typedef unsigned int uint;意思是unsigned int被重定义为 uint,那么变量a,可以表示为 uint a。
Static 是用来修饰变量和函数的,修饰局部变量会使局部变量的生命周期变为整个程序;修饰全局变量,会造成一个影响,那就是全局变量无法在除了这个程序以外的程序引用,用extern 也不行。修饰函数也会造成类似全局变量的结果,导致无法在外部程序引用。
八.#define 定义宏
#define 定义的宏,宏给我一种函数的感觉,它不是调用而是替换,比如 #define add(x,y) (x+y)意思就是add(x,y)在程序中为(x+y)。
九.指针
指针:理解指针对于C语言的学习是至关重要的,它的应用,使C语言的代码更为高效。
让我从浅到深的介绍指针。
中国地广物博,共有34个省,省又划分为市,县,镇,村,同理电脑的内存也是很大的,它为了方便管理也区域分布,只不过它更为规整,可以想象为表格。
大家应该都知道电脑有64位和32位的,其实这是根据cpu寄存器的子长来确定的,32位的计算机寄存器一次最多可以计算32位的二进制数据,64位的可以一次最多计算64位的二进制数据。承接上文,内存也是区域化,那么是如何进行地址的储存呢?其实可以这样想像,拿32位的的电脑举例子,总共有32位,电脑以二进制的方式储存,每一位是一或者零。那么总共可以有2^32种储存编号,我们称这个编号就是地址。类比的中国每个地区不是也有邮政编号吗?有了地址我们可以做甚呢?
不难想象,地址里得有内容,就像每个地方住的人,这个人就是内容,这个比喻可能不太恰当,但也足够形象。
/到了这里我就要引入指针的概念了,指针就是方便我们通过地址去引用地址中内容。有了指针,就相当于有了地址就可以用地址里的内容。指针就是一个变量,它的作用就是储存地址。
/举例:int a=1;int *p;p=&a。“int *”就是指针变量的类型,假如要存放字符的地址,那么就是“char*”,根据地址所储存的对象,指针也有了不同的类型,上面的代码里还有个操作符“&”,它的作用就是取地址,翻译一下上面的代码,整型a初始化为1,定义一个整型指针变量p,p中存放a的地址。
/再继续延伸一下,*p=10(接上面代码),这里的操作符“*”的意思是解引用,就是地址里的内容的意思,如果进行,*p=10,变量a会有什么变化呢?答案是,变量a被赋值成10,变量a就是地址的内容嘛,也就是*p=a,对*p进行赋值,那么a的值也就变了。
/上文提到指针变量会有int*,char*,其实还有很多种指针变量,在这里就不全说了。简单介绍这几种,int*,char*,short*,double*;大家可以猜猜它们所占空间大小是多少?可能有人脱口而出,int*四个字节,short*俩个字节,char*一个字节,double*八个字节。其实不是,我们去分析,指针变量是用来存放地址的,地址是32或64的二进制数据,一个字节是8个比特位,按照一个比特位存放一个二进制数去算,那就是32个比特位,也就是4个字节,4个字节去存放地址是比较合适,不浪费空间。所以这四种指针变量所占空间都是4个字节。
十.结构体
看到结构体,那么恭喜你,C语言的简单认识在看完这最后一段,你已经完成了。好,废话不多说,继续讲结构体。
结构体说白了,就是一种复杂类型,类似int ,char……,它只不过是它们的结合而已,就叫结构体。直接举例:我想定义一种类型,它可以帮我描述一个学生的信息,包括:性别,年龄,姓名,学号。
Struct stu
{ char sex[10];
Int age;
Char name[10];
Char ID[10];
}; 其中struct是结构体的关键字,stu是变量名,{}里面的是变量成员。
现在我初始化一个结构体,struct stu w={“男”,19,“张三”,“2002040207”};
我打印它的信息,printf(“sex=%s,age=%d,name=%s,id=%s”,w.sex,w.age,w.name,w.ID);
可以看到后面有个操作符“.”,它的意思就是访问结构体的成员,变量名.成员名。
除了“.“操作符外,还有”->“,它也可以访问结构体的成员,只不过是通过指针来操作,
Struct stu *p=&w;这就是创建了一个结构体指针变量p,并且存放了结构体变量w的地址,那么可以写成“p->sex“的形式访问结构体变量w中的sex信息。
结语:一篇博客,让我们初识c语言,希望每一位读者,可以不断进步,编程能力不断提高!