指標作為函式傳參
一、使用指標作為引數,可以實現兩種功能:
(1)可以讀取上一層函式中的變數的值*p
(2)可以修改上一層函式中變數中的值*p(普通引數無法實現)
#include<stdio.h>
void test(int* p){
printf("內層a:%d \n",*p);//讀取上一層引數的值
*p=1;//修改上一層引數的值
}
int main(){
int a=0;
test(&a);
printf("外層a:%d \n",a);
return 0;
}
二、應用
1.1使用指標交換兩個引數
#include<stdio.h> void swap(int* p1,int* p2){ int t; t=*p1;//取a的值付給t *p1=*p2;//b的值賦給a *p2=t;//將a的值賦給b } int main(){ int a=10; int b=50; printf("Before swap a:%d b:%d\n",a,b);// 10 50 swap(&a,&b); printf("After swap a:%d b:%d\n",a,b); //50 10 return 0; }
如上圖所示,a和p1指向同一個記憶體地址,b和p2指向同一個記憶體地址。
將p1和p2指向的記憶體地址的值交換,同時就改變了a、b指向的記憶體地址對應的值,因此成功實現了值交換。
1.2錯誤用例
#include<stdio.h> void swap(int* p1,int* p2){ int *p_temp; p_temp = p1; p1 = p2; p2 = p_temp; printf("After swap p1:%d p2:%d\n",p1,p2); } int main(){ int a=10; int b=50; printf("before swap a :%d b :%d\n",&a,&b); swap(&a,&b); printf("After swap a :%d b :%d\n",&a,&b); return 0; }
如上圖所示,a和p1指向同一個記憶體地址,b和p2指向同一個記憶體地址。
將p1和p2指向的記憶體地址交換,不改變a、b指向的記憶體地址對應的值,因此值交換失敗。
2傳遞陣列作為引數
2.1陣列名實質是一個指標型別,傳遞陣列,就是傳遞指標。
傳遞陣列時,總是要另外傳遞長度資訊。
int avg(int *p,int len){
}
或
int avg(int p[],int len){//等價,傳遞一個元素以上
}
把陣列資訊傳給一個函式:
(1)首地址:一片連續記憶體地址
(2)長度:這塊記憶體上儲存的物件的個數
2.1.1例項:計算指定長度的陣列元素平均值
#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[5]={1,2,3,4,5};
int ret=avg(arr,3);//傳遞arr[0]~arr[2]
printf("%d\n",ret);//2
return 0;
}
對於avg而言,不關心你是不是叫“陣列”,在它眼中,它只接收到一個記憶體地址而已。
3傳指標可以返回多個值
#include<stdio.h>
void max_min(int *p,int len,int* pmax,int* pmin){
int x=p[0];
int n=p[0];
for(int i=1;i<len;i++){
if(x<p[i])
x=p[i];
if(n>p[i])
n=p[i];
}
*pmax=x;
*pmin=n;
}
int main(){
int arr[10]={12,55,44,98,24,545,-12,0,-9,2};
int max;//定義為整數型別,而不是指標型別
int min;
max_min(arr,10,&max,&min);//一定不要忘了&
printf("%d %d",max,min);
return 0;
}
三、傳指標有什麼用?(效率問題)
傳值和傳地址 傳值和傳引用
傳值相當於傳遞一個拷貝,佔用空間,複製元素佔用時間,而傳地址,只需傳一次地址就可以了,可以直接訪問。
對於變數所佔空間大的適合傳地址。
四、總結
1學會把變數的地址傳給函式
2學會把陣列資訊傳遞給函式,傳陣列時必須要長度資訊
3用指標作為輸出引數,返回多個值
4明白“傳值”和“傳地址”的區別,及效率上的差異。