c语言的指针确实很灵活,尤其和数组结合起来用的时候,非常方便。二维数组和指针结合起来用的时候要复杂一些,注意一下形式的定义:
int (*p)[4]; //定义一个指向包含4个整数元素的指针
int *p[4];//定义一个指针数组,该指针数组包含4个指向整形变量的指针
定义以下一个二维数组
int array[n][m];
则要注意一些与指针有关的如下概念:
array为数组名,也是数组的首地址
array[i]为第i行第0列元素的地址,等价于*(array + i);
&array[i]则为第i行的首地址,等价于array+ i;
需要注意的是&array[i]和array[i]的值是一样的,但是他们的含义是不同的,前者是第i行的首地址,而后者是是指第i行第0列元素的地址
根据上面的讨论可以知道,要对数组中的元素array[i][j]引用的话有3种方法:
1)最直观的方法就是用下标名,array[i][j];
2) 用array[i],则array[i][j]表示为*(array[i] + j);
3) 用*(array+i),因为*(array+i)等价于array[i],所以array[i][j]表示为*(*(array+ i) + j)
另外,当指针作为函数的参数传递的时候,函数返回后,实参指针所指向的内容可能就已经被函数给改变了,这一点非常重要。c语言虽然在函数返回的时候只能返回一个值,但是通过这种方式,就相当于返回了多个值。需要注意的是用指针来传递函数的实参给形参的时候,指针必须是一个确定的值。
同时对函数指针也稍微复习了一下,尽管在实际中没有用过函数指针,但是今天复习的时候感觉还是很有用的,注意下面两种定义形式的不同:
1)int (*p)(); //函数指针,也就是函数的入口地址
2)int *p(); //指针函数,也就是函数返回的值是一个指向整数的指针
函数指针在模块化程序设计中还是比较多的,尤其是在多次调用函数的时候,用函数指针是非常好的。指针函数当然没有什么可多说的,和其他形式的函数一样,只是返回的是一个指针。
对于排序算法,主要复习了一下选择排序和冒泡排序。
1)冒泡排序是很容易理解的,就是比较相邻的两个元素,把较小的(或者较大的)调到前面,这样经过第一趟冒泡以后,最大的(或者最小的)就到来整个元素的最后。那么对于有n个元素的排序,就需要n-1趟,对于第i(0<i<=n-1)趟排序,需要(n-i-1)次比较调换。这用一个双重循环是很容易实现的。
2)选择排序的思想其实在我们日常生活中也是很常见的,就是选出所有待排序的元素中,选择出最大的和最小的,然后和待排序元素的第一个元素交换,这样之后待排序的元素就减少一个,然后从剩下的待排序元素中重复上述的过程,知道待排序元素剩下最后一个。可以总结为四个字:选择交换。
看一个选择排序的例子:8,6,2,4,9,按从大到小排序
第一次选择9,交换(第一个元素为8):9,6,2,4,8
第二次选择6,交换(第一个元素为9):9,8,6,2,4
第三次选择6,交换(第一个元素为6):9,8,6,2,4
第四此选择4,交换(第一个元素为2):9,8,6,4,2
可见对于5个元素的选择排序,经过(5-1)=4次选择交换就可以完成排序。
这样用一个循环来选择,一个变量来记录待排序的第一个元素就可以完成一次选择交换,很明显选择排序的算法时间复杂度要比冒泡排序的低。