一.指针的作用
(1)交换变量。
函数返回多个值,某些值只能通过指针返回。
传入的参数实际上是需要带回的结果的变量。
#include<stdio.h>
void swap(int *pa, int *pb);
int main()
{
int a = 5;
int b = 6;
swap(&a,&b);
printf("a=%d,b=%d\n",a,b);
}
//交换变量 的地址
void swap(int *pa,int *pb)
{
int t = *pa;
*pa = *pb;
*pb = t;
}
(2)带回的结果的变量。
#include<stdio.h>
int minmax(int a[],int len,int *max,int *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,max = %d\n",min,max);
return 0;
}
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];
}
}
}
(3)让函数返回不属于有效范围内的值表示出错
#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;
}
// 用0 和 1 里控制 主函数中if 函数执行与否
int divide(int a,int b,int *result)
{
int ret = 1;
if(b == 0) ret =0; // 除数为 0 , 则不成功。
else{
*result = a/b;
}
return ret;
}
易错点: 定义了指针变量却没有让它指向任何地址。
#include<stdio.h>
void f(int *p);
void g(int k);
int main(void)
{
int i = 6;
int *p; // 定义了指针变量却没有让它指向任何地址。
// int *p = 0; 它会指向另外一片奇怪的地方
/*
int k ;
k = 12;
*p = 12;
以上式错误的赋值方式。因为*p没有与任何具体的变量联系在一起。
本地变量
*/
printf("%i= %p\n",&i);
f(&i);
g(i);
return 0;
}
void f(int *p)
{
printf("p = %p\n",p);
printf("*p = %d\n",*p);
*p = 26;
}
void g(int k)
{
printf("k = %d\n",k);
}
二.指针和数组
(1)实际上,数组变量是const的指针。
int b[] // 《=》int *const b;
int b[] = a // 错误的赋值方式
int *q = a;
我们取数组的地址,直接就是数组变量名。
即: a[0] == &a[0]
以下四种函数原型是等价的:
int sum(int *ar, int n)
int sum(int ar[],int n)
int sum(int* ,int)
int sum(int[], int) //可以省略变量名
#include<stdio.h>
//也能写成 int *a
int minmax(int a[],int len,int *max,int *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;
printf("main sizeof(a) = %lu\n",sizeof(a));
//数组名为地址 ,长度/单个数组的空间- =数组的个数
minmax(a,sizeof(a)/sizeof(a[0]),&min,&max);
printf("min = %d,max = %d\n",min,max);
printf("main a=%p\n",a);
printf("a[]0%=d\n",a[]0);
return 0;
}
// 为什么我们不用sizeof 对数组进行求值呢?
void minmax(int a[],int len, int *min,int *max)
{
int i;
a[0] = 1000;
// 仔细观察 main 函数 和 minmax 函数中通过 sizeof 算出来的值是什么
printf("minmax sizeof(a) = %lu\n",sizeof(a));
// 观察两个地址 ,一模一样 !!!
printf("main a=%p\n",a);
*min = *max = a[0];
// 遍历数组
for(i = 1; i < len; i++){
if(a[i] < *min){
*min = a[i];
}
if (a[i] > *max){
*max = a[i];
}
}
}
(2)const 的位置决定谁不能变。
const 在* 前面还是后面,const在前,值不能变。
const 在后,不能通过指针访问。
int* const q = &i; // q是const ,指向的i 不是const
*p = 26; //所以能够通过指向i 的方式改变 q 的值
q++; // ERROR
const int *p = &i; //(*p) 是 const, 所以不能通过 p 去做修改
*p = 26; // 所以这种方式是错误的。
//以下这两种是正确的
i = 26;
p = &j;
(3) 将非 const 的 值转换成 const。
在结构体当中 ,当要传递的参数的类型比地址大的时候,
我们用比较少的字节数传递值 给 参数,这是能避免函数
对外面的变量的修改 。
void f(const int *x); // grarantee保证不会动指针所指向的值
int a = 15;
f(&a);
const int b = a;
f(&b);
b = a + 1; //Error!!!
//const 数组
const int a [] = {1,2,3,4,5,6}; //数组内的所有的单元都是const int
// 为了保护数组不被函数破坏,可以这只参数为const
int sum(const int a[],int length);