第一篇文章,作为一个C的新手,一个刚刚开始接触C的未来程序员,不知道该写点什么。
参加培训第20天,终于搞明白了C的大致框架和基本的语言结构。
一点点给自己汇总下:
2天的Unix学习:(确切的说应该是Linux操作系统。)
Uinx的学习,主要还是熟悉下基本的shell指令,了解到Unix的基本架构。
ls 查看目录下的文件属性,可以跟 -l -a -R -t 等等,其他的用的不多。
cd 更改当前工作目录。
chmod 改变文件或者目录的权限。可以用u g a o 表示user group all other 更改权限, 或者777 8进制的数字来表示各个用户的权限。
ps 查看进程
mkdir 新建文件夹 跟-p 可以建立目录树
rm 删除文件 -r 删除目录
rmdir 删除空目录
find 查找文件
more 分屏显示
cp copy文件
mv move文件
su 切换用户
ifconfig 查看网络连接信息
tar 压缩成tar文件
其他的也用的不多,还有一些命令可以用man来查看,man是一个很强大的男人。
C语言的学习
1.常量
常量是不是可以理解为一个常态类型的变量呢?
常量应该分为:字符常量,整形常量,浮点型常量,枚举常量。
常量应该算是一个程序最基础也是最常见的了。
2. 变量
变量顾名思义应该就是一个会变化的量,是一块内存的别名,而名字是可以自己取的。
基本上变量的命名在商业化角度上,应该要有一套命名规则,方便程序的阅读。
(ps.前段时间稍微看了下有些命名的规则,可以沿用
int nValue;//来表示一个整形的数。
string strName;//表示一个字符串型的name。(当然 string是C++里面的类型)
用的不好,但是还是试着去用用,总比用a,b ,c要稍微规范一点。
还有就是变量的命名应该规避一些关键字 保留字 以及尽量不要使用_开头的变量,貌似在某些库里面是使用下划线开头作为变量命以避免和函数内变量重名的问题。
数据类型:char , short, int, long, long long, float, double, long double,
当然还有无符号类型:unsigned
变量的声明和定义,当你创建这个变量而暂时不需要为其分配内存空间时,应该算是变量的声明;
当你声明变量并为之分配内存空间的时候称之为 定义。
(函数的声明和定义也是类似的原则。)
每个变量都有自己的作用于,有定义在函数体外的:全局变量;有定义在函数体内的局部变量;有定义在循环内的块变量。
每个变量又有自己的作用域,全局变量的作用域在程序return 0之后被释放,内存空间在0x80区域(全局区)
局部变量的作用域在该函数体内,内存空间在栈区,有部分使用mallco出内存存储的变量 空间在堆区域中。
块变量作用域在循环体内,同样在堆栈区域。
变量在出了自己的作用域之后内存空间被释放。
3.表达式
表达式应该是一个程序的基本元素吧,算不算?写出这句话又发现貌似变量和常量才是最基本的元素 。
表达式是一个由变量或者常量等通过运算符(operator)组合而成的一个公式,可以通过赋值号"="给变量赋值,也可以不用赋值直接作为某些函数的参数。
表达式在数学上应该看到的算是比较多的;
如: int a = 1; int b = 2;int c = a + b ;//这个就是一个简单的表达式。
1+2;//这个也是一个基本上毫无意义的表达式。
当然表达式的语法规则有很多,在一个程序中会看到各种表达式 以及相关的用法,这个比较基础,就不多写了,主要是我也写不清楚。
4.函数体
每个程序都有一个main函数,是该程序的主函数,也是程序的入口,由return 0结束程序。
int main (void)
{
(函数体(代码)... ...)
return 0;
}
除了main函数之外,还可以用其他的程序,可以让这些程序实现一些特定的功能。
返回类型 函数名 (形参表){
函数体
}
返回类型由程序的返回来决定, 函数名则是别的函数可以调用该函数的标识符,函数的命名也可以同样参考一些比较正规命名规则。
形参表是主调函数传递过来的值的类型,定义形参的时候和定义变量是一样的,要注明类型 和形参名, 形参表里的形参的个数按实际需要分配。
备注:定义变量的时候可以把相同类型的放在一起定义,形参表里的定义却不行,必须分开。
形参和实参一样,有独立的存储空间,在传递值的时候有一个规则: 按值传递,形参改变不改变实参的值/形参变实参不跟着变。
按地址传递,形参改变的同时也改变实参的值。
还有书上的一条基本原理:形参相当于函数中定义的变量,调用函数传递参数的过程相当于定义形参变量并且用实参的值来初始化。
5.分支/判断
在一个函数中,if/else是一个被使用频繁的判断语句,具体用法就不多说了,C语言书里面都有,也基本上已经融入了我的思想。
基本用法:
if(控制表达式)
条件真->语句/表达式(可以用{}来写一个复合语句。)。
else
条件假->语句/表达式(可以用{}来写一个复合语句。)。
-------------------------------------------------------------------------------------无敌分割线-------------------------------------------------------------------------------------
if(控制表达式)
条件真->语句/表达式(可以用{}来写一个复合语句。)。
else if(控制表达式)
条件假->语句/表达式(可以用{}来写一个复合语句。)。
else if(控制表达式)
条件假->语句/表达式(可以用{}来写一个复合语句。)。
……
else if(控制表达式)
条件假->语句/表达式(可以用{}来写一个复合语句。)。
else
条件假->语句/表达式(可以用{}来写一个复合语句。)。
和if/else有点类似的还有一个三目运算符:
(控制表达式)?(表达式1):(表达式2);//条件为真,返回表达式1,否则返回表达式2;
分支语句还有switch语句,
switch (控制表达式) {
case 常量表达式: 语句列表//一般在语句列表里面会有一个break;方便程序跳出,不然将顺序执行下去直到break或者switch结束。
case 常量表达式: 语句列表
...
default: 语句列表
}
一般在语句列表里面会有一个break;方便程序跳出,不然将顺序执行下去直到break或者switch结束。
case分支的常量表达式必须互不相同。
6.循环
1). for循环
for(控制表达式1; 控制表达式2; 控制表达式3){
循环语句块
}
控制表达式1:初始化语句,进入循环的第一个执行的语句,整个循环从开始到结束只执行一次。
控制表达式2:条件判断语句,在执行完控制表达式1之后执行的语句,条件真则执行循环体的语句或者复合语句,条件假则是退出循环。
控制表达式3:在循环开始后,每一次执行完循环体的语句或者复合语句之后,就会执行一次控制表达式3,一般将控制语句2里面的变量自增或者自减放在控制语句3内。在控制表达式3执行完之后,重新进入控制表达式2进行条件判断,直到控制表达式2条件为假退出循环。
2). while循环
while(控制表达式){
循环语句块
}
控制表达式,条件为真时,执行循环,条件为假,退出循环。
ps:
while(1){
循环语句块
}
//比较实用也比较简单的死循环的写法,在部分特殊的场合使用。
3).do……while循环
do{
循环语句块
}while(控制表达式);
do...while循环和whil循环的差别在于 while循环是先执行判断条件为真循环,条件为假则不执行循环;而do……while循环是先执行一次循环,然后进入控制语句,条件为真则继续循环,条件为假则退出循环。
do……while循环在while后面别忘记加分号哦。这点我开始的时候总是忘记。
4).break和continue语句
break和continue语句确切的说不应该算是循环,但是这两个关键字的语句是控制循环体的一部分,当循环语句执行到break时,直接从该语句无条件退出循环,跳过后面的循环语句和条件判断;当循环语句执行到continue是,直接从该语句跳到循环语句的条件控制语句,执行下一次循环,如果是for语句则直接跳到控制表达式3,再继续下面的循环。
5).相互嵌套的循环
相互嵌套的循环是按照具体实现要求来执行的
for(控制表达式1;控制表达式2;控制表达式3)
{
for(控制表达式1;控制表达式2;控制表达式3)
{
循环语句块1
}
循环语句块2}
类似的循环可以有很多,可以for和while嵌套 等等,具体问题可以具体分析和实现。
7.数组
数组是一个复合的数据类型,可以由多个相同类型的元素组成一个在内存连续存储的数据结构。
eg. int nArrey[10];
一个由10个整型变量,在一块连续的内存但愿存储的数组名叫nArrey的数组nArrey[10]。
nArrey是一个常指针,nArrey[i]表示的是从数组nArrey[10]的首地址nArrey开始往后数i个int数据类型的空间地址表示的数据。
数组的操作就是指针的操作。当然指针和数组也还有一个区别,除了一个是常指针之外,还有就是sizeof数组返回的是一个数组的长度。而sizeof指针返回值是4.
nArrey[i]就是一个变量。nArrey是这个数组的首地址,i是数组元素的下标。
nArrey[i]也可以表示成*(nArrey+i),来表示这个内存空间的值。
数组的返回应该时刻注意数组的越界问题。
还有特殊的数组,字符串和多维数组。
字符串可以看成一个char类型的字符数组。可以和数组一样通过下标访问数组的元素。但是字符串的字面量常量却是不能修改的。
字符串以“\0“结束
数组型字符串处于栈区,值可变,地址不可变;
指针型字符串处于全局区,就是指向字面值常量的字符串,地址可变,值不可变;
指针指向字符数组,地址和值都不可变。
8.指针
指针,首先可以确认的一点是,它是个变量,有自己的内存空间。空间里面存的是一个地址。
定义:int* pi; 定义了一个整数类型的指针,指针指向的是一个整数的内存空间。
使用指针必须保证其指向的地址为有效的地址,坚决杜绝野指针。所以指针在定义之后要初始化,如果无法确认需要指向的空间时,可以先将指针置为空指针NULL。
指针比较常用的是用于函数的传参,可以实现实参和形参的双向传递,如果传递的参数不想在函数中对该地址的变量有更改的风险,可以在类型前面加const做修饰。
指针在用于函数的时候,如果被作为返回值返回的时候,不可返回一个局部变量的内存空间地址。
指针还可以用于构建动态分配内存的数组。
指针的加法和减法是将指针指向下一个内存单元或者是上一个内存党员。
还有双指针,指向一个地址的指针。或者说是指针的指针。
万能指针(void*),代表任何类型的指针,但是万能指针有一个不同的地方是 不能进行*运算。因为void*在返回的时候不知道应该取多少个字节作为返回。
9.宏/预处理
预处理指令:include 基本上在每个程序的起始位置都能看打一个这样的指令。
include预处理指令其实就是把后面跟的那个文件用复制的方式在预处理阶段直接粘贴到源文件中。
10.结构
不知不觉已经过去2个多小时了,后面的几点知识点留待明天回来再整理,突然发现坐在电脑前默默的思考整理学过的一些知识点还是很有帮助的,可以加深自己的记忆。
当然 ,高手路过的话,看到我哪里有什么不对的地方,希望可以稍微滞留一会帮忙指正,先行谢过。
乱七八糟的整理了一下自己学过的内容。
花了点时间又整理了一部分,相信再过几个晚上,应该就能整理完毕了!