递归函数:
直接或间接调用函数本身,则该函数称为递归函数;不能称为内联函数;
例子 :
阶乘
int fun(int n)
{
if(n==1||n==0)
return 1;
return n * fun(n-1);
}
内联函数存在的作用
内联函数被发明出来就是为了取代C中的宏,因为宏是单纯的替换而没有类型检查所以经常出毛病;
指针:
指针:就是一个用来存储地址的变量,变量的内容为一个地址。
int b;就是一个用来存储整型的变量b,变量的内容为一个整型数据
指针定义
指针类型 *变量名 = NULL; //指针定义时,最好赋空
指针类型:char short int long long long float double。。。
*:在定义时有这个*,表示定义是指针变量
变量名:跟数据类型命名规则一致;
*
1、在运算当中,可以是乘号
2、用来做指针变量的定义(只做识别指针变量定义用)
3、表示指针所指向的对象的值(解引用,找到对应内存里面的值)
char *p1; short *p2; int *p3; float *p4;
char *p1;//定义一个p1指针变量,指针指向存放char数据类型的地址
在32位系统中,指针变量长度统一为4个字节
为什么 任何类型的指针 都占4字节?
虽然各种类型所占内存 都不一样
但是 她们的地址长度都一样
变量的地址长度取决于系统的寻址能力
也就是 cpu的字长,在32位 系统中,任何地址都是4字节的
就像一座大楼里面的房间虽然都各不同,但是房号都是3位。
int *p= NULL;
int a = 100;
p = &a; //将变量的地址赋给了p
练习:
1、利用指针,实现3个数从大到小排序。
初时还觉得这题没考到指针的运用,做了以后才发现,他就利用的指针的解引用,做交换,而不是对数据进行基本的交换。
2、利用指针,实现两个数交换。
同理
--------------------------------------------------
一维数组及指针
int a[10];
a是数组名,是第一个元素的地址&a[0]
a ===========等价于===========&a[0];
为什么呢? 这很简单
&: 作用是取内存的首地址;也就是小明发所在的宿舍号
*:解引用;就是,通过本房间里面的人,知道小明在哪个宿舍号,并且找到他;
& 与 * 可以认为 是互相抵消的;
[]的作用与*相同,不过[]可以存多几个指针;
&a表示指向整个数组的地址
a[0] == *(a+0) == *a == *(&a[0]) == a[0];
a[1] == *(a+1) == *(&a[0]+1)== *(&a[1]) == a[1];
1[a] == *(a+1) == *(&a[0]+1) ==*(&a[1]) == a[1];
p = p+1;
p == a+1 == &a[0]+1
int *p1 = &a[8];
int *p2 = &a[1];
神奇的是地址之间的减法操作得出的答案居然是元素的个数差!!!
原来
p1 - p2;还要 除去 数据类型长度; 系统默认的;
(( int )p1 - (int) p2)/sizeof(int) == 元素个数差
两个指针相加,无意义。指针相减(要数组范围)
1)进入GDB #gdb test
test是要调试的程序,由gcc test.c -g -o test生成。进入后提示符变为(gdb) 。
2)查看源码 (gdb) l
源码会进行行号提示。
如果需要查看在其他文件中定义的函数,在l后加上函数名即可定位到这个函数的定义及查看附近的其他源码。或者:使用断点或单步运行,到某个函数处使用s进入这个函数。
3)设置断点 (gdb) b 6
这样会在运行到源码第6行时停止,可以查看变量的值、堆栈情况等;这个行号是gdb的行号。
4)查看断点处情况 (gdb) info b
可以键入"info b"来查看断点处情况,可以设置多个断点;
5)运行代码 (gdb) r
6)显示变量值 (gdb) p n
在程序暂停时,键入"p 变量名"(print)即可;
GDB在显示变量值时都会在对应值之前加上"$N"标记,它是当前变量值的引用标记,以后若想再次引用此变量,就可以直接写作"$N",而无需写冗长的变量名;
7)观察变量 (gdb) watch n
在某一循环处,往往希望能够观察一个变量的变化情况,这时就可以键入命令"watch"来观察变量的变化情况,GDB在"n"设置了观察点;
8)单步运行 (gdb) n
9)程序继续运行 (gdb) c
使程序继续往下运行,直到再次遇到断点或程序结束;
10)退出GDB (gdb) q
===================================================
涉及到地址或者指针运算
1、加减整数的时候,记得要考虑指针或者地址所指向的对象大小;
2、两个指针相减 一般在数组内才有意义,得到的是中间元素的个数;