指针的应用场景
- 交换两个变量的值
void swap(int *pa,int *pb)
{
int t = *pa;
*pa = *pb;
*pb = t;
}
- 当函数需要返回多个值,则必须通过指针带回,传入的参数实际上是需要保存带回的结果的变量
eg:
#include <stdio.h>
void minmax(int a[], int len, int *max, int x*min);
int main(void)
{
int a[] ={1,2,3,4,5,6,7,8,9,12,13,14,16,17,21,23,55,};
int min,max;
minmax(a, sizeof(a)/sizeof(a[0] ),&min,&max);
printf ( "min=%d , malx=%d\n", min,max) ;
return 0;
}
void minmax(int a[], int len, int *min,int *max)
{
int i;
*min =*max=a [0];
for ( i=1; i<len; i++ ) {
if ( a[i] <*min ) {
*min = a[i];
}
if ( a[i]>*max ) {
*max = a[i];
}
}
- 函数返回运算的状态,结果通过指针返回
常用的套路是让函数返回特殊的不属于有效范围内的值来表示出错:
·-1或0(在文件操作会看到大量的例子)
·但是当任何数值都是有效的可能结果时,就得分开返回了
之后的语言(C++,JAVA)采用了异常机制来解决这个问题
eg:
#include <stdio.h>
/**
@return如果除法成功,返回1;否则返回0
*/
int divide(int a, int b,int *result);
int main(void)
{
int a=5;
int b=2;
int c;
if ( divide(a,b,&c) ) {
printf ( "%d /%d=%d\n", a, b,c);
}
return 0;
}
int divide(int a, int b, int *result)
{
int ret = 1;
if ( b == 0 ) ret = 0;else {
*result = a/b;
}
return ret;
}
指针最常见的错误
- 定义了指针变量,还没有指向任何变量,就开始使用指针
eg:int *p;
*p = 12;
这种写法是错误的,在定义*p后,p指向的地放不确定,若把12写入,但那个地方不能写入东西,此时程序会崩溃。
指针与const
- 指针本身是const
表示一旦得到了某个变量的地址,不能再指向其他变量
int*const q = &i; //q是const
*q= 26; //OK
q++; //ERROR - 指针所指的值是const
表示不能通过这个指针去修改那个变量(并不能使得那个变量成为const)
const int*p = &i; <==> int const *p = &i
*p = 26; // ERROR!§是const
i = 26;//OK
p = &j; //OK
判断哪个被const了的标志是const在*的前面还是后面
- 转换
总是可以把一个非const的值转换成const的
void f(const int* x);
int a = 15;
f(&a); // ok
const int b = a;
f(&b); // ok
b = a + 1; // Error !
当要传递的参数的类型比地址大的时候,这是常用的手段:既能用比较少的字节数传递值给参数,又能避免函数对外面的变量的修改
const数组
- const int a[ = {,2,3,4,5,6,};
- 数组变量已经是const的指针了,这里的const表明数组的每个单元都是const int
- 所以必须通过初始化进行赋值
保护数组
- 因为把数组传入函数时传递的是地址,所以那个函数内部可以修改数组的值
- 为了保护数组不被函数破坏,可以设置参数为const
- int sum(const int a[], int length);