C语言函数
本节主要讲一些C语言的基础知识,本人是做OC开发的,现在想了解OC的底层实现,就来再次学下C语言,幸好大学的时候学过C语言,有些基础,好学一点,以后会持续更新有关C语言的学习。有写的不对的地方,欢迎大家评论指正,共同研究!
1.什么是函数
- 函数对于C语言来说,我们都是在函数里面编写我们的自性指令,函数是我们C语言的指令载体;
- 对于C语言来说,每条指令语句,后面必须以分号结尾;
2.函数三种命名法则
- 匈牙利命名法则:函数每个单词首字母都大写(例:DidFinishLaunch)
- 驼峰命名法则:函数单词首字母小些(例:didFinishLaunch)
- Linux命名法则:函数每个用 _ 隔开(例:did_finish_launch)
实际开发中具体使用哪种命名方法,取决于企业项目命名规范以及个人习惯,本人做OC开发,习惯使用驼峰命名法。
3.函数四个要素
返回值 函数名称(参数1,参数2…)
{// 函数体开始
}// 函数体结束
// 举例
int getSum(int a, int b){
int c = a + b;
return c;
}
- 返回值 (例中 int,如果没有参数就写void)
- 函数名称 (例中 getSum)
- 参数 (例中 int a, int b)
- 函数体 { } 这个花括号里面就是函数体
函数的返回语句,return关键字,返回的数据要符合函数定义的返回值类型;
3.基本数据类型
1.数据存储
- 内存是存储数据和代码的地方,内存里面存的都是是二进制数据,二进制一位数据,如 100111010101….,我们称之为bit(位),8个bitt为1个Byte(字节),16个bitt为一个WORD(字),32个bit为一个DWORD(双字)…..
- 存储空间描述单位为字节(8bit),1KB = 1024Byte , 1MB = 1024KB , 1GB = 1024MB , 1TB = 1024MB … 。在计算机里面 K 为1024,而不是数学里面的1000。
这也是我们程序员日的由来,1024拆开就是10月24号,所以程序员日就是10月24号,到时候别忘了为我们自己庆祝一下哈!!!
2.数据类型
下面是常用的基本数据类型,当然还有其他的数据类型,不常用这里就不说了
- 字符数据类型:存储英文数字符号的类型 char,占 1 个字节;
- 存储16bit整数的数据类型:short 占2个字节 16bit;
- 存储32bit整数的数据类型:int 占4个字节 32bit;
- 存储64bit整数的数据类型:long long 占8个字节 64bit;
- 存储32bit浮点数数据类型:float 占4个字节 32bit;
- 存储64bit双精度浮点数数据类型:double 占8个字节 64bit;
如果你的数据不是任何数据类型为 void,这是我们经常在OC的方法里面看到这个 void * 这个东西
3.数据正负
计算机的数据正负表示表示,又叫符号数据类型,例如 -4,+4,假如我们用16bit,也就是 short 来存储 -4,+4,应该怎么表示呢?
- 用最高位的一个bit表示正负,1(负),0(正);
- 剩下的15个bit表示我们的数据,4 = 1*2^2 + 0*2^1 + 0*2^0;
所以 4 的二进制为 100,15个bit表示 4 就是000000000000100,然后用最高位的第 16bi t表示正负,0 为正,1 为负; +4 = 0000000000000100;如果是负数,那么就将剩下的15bit取反后再加 1 ,取反:000000000000100 –> 111111111111011 加 1 :111111111111011 +1 –> 111111111111100; 然后在前面添加个 1 :-4 = 1111111111111100;
4.无符号数据类型
对于有符号的数据类型,会用一个bit来存储符号位,如果我们知道了数据就是正数,没有负数,那么就没必要浪费一个bit来存储符号,这是我们就用到无符号类型,在数据类型前面加上 unsigned 就可以了;例如 unsigned char; unsigned short ; unsigned int ; unsigned long long …
5.局部变量
1.什么是局部变量
程序在执行的过程中,实际上就是大量的数据运算,那么我们必然要存储这些数据,在C语言程序设计里面存储数据的内存我们叫做“变量”,变量本质是一块内存,它可以存储数据,还可以修改数据,就像一个仓库,存放什么数据,由编程人员自己决定。
- 局部变量:在函数中定义的变量,成为局部变量,只在函数内部有效;
- C语言定义变量: 变量类型 变量名称; ( int a;)
- 我们可以在定义变量的时候就给他赋值; ( int a = 10; )
比如说我们要交换 a 和 b 的值,要怎么做呢??
int temp;
temp = b;
b = a;
a = temp;
我们为什么要定义一个中变变量 temp 呢?这应用到变量的本质就是一块内存,如果我们直接把 a 赋值给 b ,那么 b 内存里面的值就是 a 内存里面的值,导致 a = b;没有达到交换 a 和 b 值的效果。所有在这期间我们需要再开辟一块内存 temp 来先保存我们 b 的值,然后 b = a,这时候 a, b 两块内存里面的值是一样的,然后再把内存 temp 里面的值取出来赋给 a 就可以了。
2.加、减、乘、除、括号
int a = 1;
int b = 2;
int c = 3;
int d;
d = (a+b*(b+c)+(a*c))*c/4
这里类似于数学里面的运算逻辑
3.逻辑运算
如果符合逻辑,条件成立,那么值为 1 ;如果不符合逻辑或者条件不成立,值为 0;
int a = 1;
int b = 2;
int c = (a > b);
int d = (a < b);;
上面的结果就是: c = 0; d = 1;
运算逻辑有:
- > 大于
- >= 大于等于
- < 小于
- <= 小于等于
- == 等于
- != 不等于
5.程序在计算机运行过程
- 运行程序:程序在运行的时候,编译器会把我们的程序编译成可执行的二进制文件,操作系统会将这个二进制文件指令代码,全部加载到指定的内存中,那么这个内存我们称之为“代码段”。这个应用“代码段”对于我们的应用程序来说,只能读,不能写,防止运行的时候(这里必须强调是在程序运行的时候!运行的时候!运行的时候!)有恶意的程序,修改我们的代码。试想一下如果有恶意程序能够在你程序运行的时候修改你代码,你程序写的明明没问题,却无法运行起来或者运行起来了和你写的不一样,那是多么痛苦是的事情!!
- CPU根据一个指令指针来执行当前指令,执行完之后,指令指针移动到下一条指令(按顺序执行),或调跳转到指定指令(条件、循环)。在“代码段”中每个函数都是一个独立的代码片段;有一个指令指针,来决定当前CPU执行指令。
- 运行的时候,局部变量和函数参数的内存,都是分配在栈里的面的。栈是操作系统会在内存里面额外的专门分配出一个区域,来给我们做栈的内存使用,其中有一个栈顶指针。
- 调用函数的时候分四步:a.分配参的数内存,参数从右向左的顺序分配; b.将数据对应的内存做好数据初始化赋值; c.将我们的下一条指令的位置,保存在栈里; d.保存栈顶在调用函数之前的地址
- 执行return指令分三步:a.回收这个函数里面的局部变量,将栈顶指针拨回到没调用函数之前的地方;b.将指令指针拨回到我们保存的下一条指令要执行的地方;c .保存我们的返回值到一个特定的地方,例如EAX寄存器等。