1. 程式人生 > >指標作為函式傳參

指標作為函式傳參

 一、使用指標作為引數,可以實現兩種功能:

(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明白“傳值”和“傳地址”的區別,及效率上的差異。