一、 指针作为函数的参数
1. 使用指针作为参数,可以实现两种功能:
可以读取上一层函数中的变量的值 *p
可以修改上一层函数中的变量的值 *p(普通函数无法做到)
①代码时间
#include <stdio.h>
void test(int* p) //把一个内存地址传给一个函数
{
//使用星号操作*p,来读写内存
printf("before test: %d ",*p); //输出0
*p = 1;
}
int main()
{
int a = 0;
test(&a);
printf("now :%d ",a); //输出1
return 0;
}
求和函数
交换两个变量的值函数
2. 传递数组作为参数
数组名,实质是一个指针类型,传递数组,就是传递指针
②代码时间
#include <stdio.h>
int avg(int* p, int len)
{
int sum = 0;
for( int i = 0; i < len ; i++ )
{
sum += p[i];
}
return sum/len;
}
int main()
{
int arr[] = {1,2,3,4};
int ret ;
ret = avg(arr ,4); //从arr[0]到arr[3]
ret = avg(arr,3); //从arr[0]到arr[2]
ret = avg(arr + 1, 3); //从arr[1]到arr[3]
return 0;
}
注意:
1) int avg(int* p , int len)和int avg(int p[] , int len); 这两种方法是完全等价的。
2) 传递数组时,总是要另外传递长度信息,不能只把手地址传给函数,这样是不够的。int avg(int* p , int len); //总是要传长度信息
3. 函数传递指针的作用
1) 返回多个值:return只能返回一个值,如果一个函数要返回多个值,必须使用指针参数(输出参数)
2) 传递指针效率高
③代码时间
写一个函数,求出数组中的最小值和最大值
注:把用于输入的参数称为输入参数,如p ,len
把用于输出的参数称为输出参数,如max , min
viod max_min(int*p , int len , int* pmax , int* pmin )
{
int _max = p[0];
int _min = p[0];
for( int i = 1 ; i < len ; i++ )
{
if( p[i] > _max )
_max = p[i];
if( p[i] < _min )
_min = p[i];
}
*pmax = _max;
*pmin = _min;
}
总结:
1) 把变量的地址传给函数
2) 把数组传递给你函数,传数组时必须传递数组的长度信息
3) 用指针作为输出参数,返回多个值
4) “传值和传地址”的区别,及效率上的差异
二、 const指针的用法
4. 定义:在普通指针类型前面,加上const修饰
如:
const int* p;
const char* p;
const double* p;
- 5. 加不加const的区别
1) 不加const
int a = 10 ;
int* p = &a;
*p = 11; //可写
int b = *p; //可读
2) 加上const修饰
int a = 10;
const int* p = &a;
*p = 11; //错误!! 不可写
int b = *p; //可读
所以,const的作用是封装(限制)星号操作里的写内存功能
称为:只读ReadOnly,这块内存只能读不能写
6. const指针的用途
const用于限定函数的参数
int avg(const int* p , int len)
{ }
用于显示的指定:该函数是输入参数,在函数里只是读取这个内存,而不会修改这个内存的值。
当你不需要修改内存时,在指针前面加上const修饰,避免一不小心的错误。
①代码时间
int avg ( const int* p , int len )
{
for( int i = 0; i < len ; i++ )
{
printf( "%d " , *p); //可以读
p = p + 1 ; //没问题
}
}
const只是封禁的是星号操作,不允许写内存,但对于普通的指针加减是没关系的
7. 指针常量
②代码时间
int a;
int b;
int* const p = &a;
p = &b; //语法错误 p不能修改