1. 程式人生 > >C語言中陣列指標 作為形參

C語言中陣列指標 作為形參

2015 0605

在修改程式的過程中,看到兩種將陣列作為形參的方法,於是搜了一下,找了一下比較全面地介紹陣列指標的文章。

先寫下我遇到的兩種方式:

方式1:

void filter_c(long double *,long double *,float *,int);//函式宣告

filter_c(NAFF_b,NAFF_a,RealTimeSignal_filter,len_new);//函式應用

void filter_c(long double b[ ],long double a[ ],float x[ ],int number)//函式定義

{.............................}

方式2:

void select_sort(float *, int);//函式宣告

select_sort(Buff_Flow, MaxSize);//函式應用

void select_sort(float *x, int n)//函式定義

{..............................}

原文地址:http://blog.sina.com.cn/s/blog_90832a850100wksp.html

陣列元素     陣列元素可以用作函式實參,但不能用作形參。因為形參是在函式被呼叫時臨時分配儲存單元的,不可能為一個數組元素單獨分配儲存單元。 在用陣列元素作函式實參時,把實參的值傳給形參,是單向的“值傳遞”過程。 陣列名
陣列名作函式實參時,向形參(陣列名或指標變數)傳遞的是陣列首元素的地址。形引數組可以不指定大小,在定義陣列時在陣列後面跟一個空的方括號形引數組名實際上是一個指標變數,並不是真正的開闢一個數組空間。相應的,定義實引數組時必須要指定陣列大小,因為要開闢相應的儲存空間。 例如: #include <stdio.h> int main() { void fun(int arr[],int n); void output_fun(int * arr,int n); int array[10]; fun(array,10); output_fun(array,10); return 0; } void fun(int arr[],int n) { int i; for(i=0;i<n;i++) scanf_s("%d",&arr[i]); } void output_fun(int * arr,int n) { int i; for(i=0;i<n;i++,arr++) printf("%-2d",* arr); } //void fun(int arr[],int n)和void fun(int * arr,int n)等價。
//這裡就是程式中遇到的兩種方式。 指標與指標變數 一個變數的地址稱為該變數的指標。 如果有一個變數是專門用來存放另一個變數的地址(即指標),則它稱為指標變數。 指標變數就是地址變數,指標變數的值就是地址。 指標變數作為函式引數 主調函式的實參是指標變數,在函式呼叫時,將實參變數的值傳遞給形參變數,這裡依然是單向的值傳遞,但是傳遞的內容是實參的地址。這就與陣列名的傳遞是一樣的道理。 不能通過執行呼叫函式來改變實參指標變數的值,但可以改變實參指標變數所指變數的值。 歸納:陣列名與指標變數 (1)形參和實參都用陣列名; (2)實參用陣列名,形參用指標變數; (3)實參和形參都用指標變數; (4)實參為指標變數,形參用陣列名。 值得注意的是:如果用指標變數作為實參,必須先使指標變數有確定值,指向一個已定義的物件。 陣列元素的指標 引用陣列元素可以用下標法(如a[i]),也可以用指標法(如*(a+i)或*(p+i))。下面這幾種寫法等價,都是使指標變數p指向陣列a的首地址。其中a為已定義的陣列名。 (1)int * p=&a[0]; (2)int * p=a; (3)int * p;p=a; (4)int * p;p=&a[0]; 在指標指向陣列元素時,可以對指標進行以下運算: 加一個整數(+或+=); 減一個整數(-或-=); 自加運算; 自減運算; 兩個指標相減,如p1-p2(只有p1和p2都指向同一陣列中的元素時才有意義)。 指標就是地址,兩個指標相減可知道它們所指向元素的相對距離。地址不能相加,如p1+p2是無實際意義的。 二維陣列a[][] 二維陣列名(如a)是指向行的。因此a+1中的“1”代表一行中全部元素所佔的位元組數。 一維陣列名(如a[0],a[1])是指向列元素的。a[0]+1中的1代表一個a元素所佔的位元組數。 在指向行的指標前面加一個*,就轉換為指向列的指標。如,*a和*(a+1),分別指向a陣列的0行0列的元素和1行0列的元素。 在指向列的指標前面加&,就成為指向行的指標。如,a[0]指向的是0行0列元素的指標,在前面加一個&之後,由於a[0]與*(a+0)等價,因此&a[0]與&*a等價,也就是與a等價,它指向二維陣列的0行。 指向多維陣列的指標變數 (1)指向陣列元素的指標變數 舉個例子,指向二維陣列元素的指標變數 #include <stdio.h> int main(void) { void input_output_array_fun(int *); int a[3][4]; int * pointer; pointer=a[0]; //這裡使指標變數pointer指向0行0列元素地址。 input_output_array_fun(pointer); return 0; } void input_output_array_fun(int * p) { int i; for(i=0;i<12;i++) scanf_s("%d",p+i); for(i=0;i<12;i++) { printf("%-5d",*(p+i)); if((i+1)%4==0)printf("\n"); }//for } (2)指向由m個元素組成的一維陣列的指標變數 如int (* p)[4],p的型別是int(*)[4],p被定義為指向一維整型陣列的指標變數,一維陣列有4個元素,因此p的基型別是一維陣列,其長度為16位元組。 #include <stdio.h> int main(void){ void input_output_array_fun(int (* p) [4]); int a[3][4]; int (* pointer)[4]; pointer=a; //這裡使指標變數pointer指向0行。 input_output_array_fun(pointer); return 0; } void input_output_array_fun(int (* p)[4]){ int i,j; for(i=0;i<3;i++) for(j=0;j<4;j++) scanf_s("%d",*(p+i)+j); for(i=0;i<3;i++) for(j=0;j<4;j++) { printf("%-5d",*(*(p+i)+j)); if(j==3)printf("\n"); }//for(i=0;) } 通過指標引用字串 通過字元陣列名或者字元指標變數可以輸出一個字串,而對一個數值型陣列,是不能企圖用陣列名輸出它的全部元素的,只能逐個輸入。 字元陣列從鍵盤輸入的時候呼叫gets_s()函式; 數值型陣列從鍵盤輸入的時候呼叫scanf_s()函式。 字元指標變數和字元陣列的比較 (1)字元指標變數中存放的是地址。字元陣列由若干個元素組成,每個元素中存放一個字元。 (2)可以對字元指標變數賦值。不能對字元陣列名賦值。如: char *a; a="I care."; //合法 char str[10]; str="I care."; //非法 str[0]="I";//合法。一旦字元陣列沒有在初始化時賦值,只能逐個賦值。 (3)初始化。 字元指標變數: char *a="I care."; 等價於 char *a; a="I care."; 字元陣列: char str[10]="I care."; //合法 不等價於 char str[10]; str[]="I care.";//不能用賦值語句對字元陣列中全部元素整體賦值。 (4)字元指標變數在編譯時,只分配一個儲存單元(用來存放字串的起始地址)。字元陣列在編譯時會分配若干儲存單元,以存放各元素的值。 (5)指標變數的值是可以改變的。陣列名代表一個固定的值(陣列首元素的地址),不可改變。 (6)字元指標變數所指向的字元常量中的內容是不可以被取代的(不能對它們再賦值),字元陣列中各元素的值是可以改變的。如: char a[]="you."; char *b="you."; a[1]='a'; //合法 b[1]='a'; //非法 (7)引用陣列元素時,字元陣列可以用下標法引用一個數組元素(如a[2]),也可以用地址法(如*(a+2)引用陣列元素a[2])。如果定義了字元指標變數p,並使它指向了陣列a的首元素,則可以用指標變數帶下標的形式引用陣列元素(如p[5]),同樣可以用地址法(如*(p+5))引用陣列元素a[5]。 (8)用指標變數指向一個格式字串,能輕鬆實現可變格式輸出函式。如: char *p; p="a=%d,b=%f\n"; printf(p,a,b); 相當於 printf("a=%d,b=%f\n",a,b); 使用字元陣列也能達到這一目的,但只能在定義陣列時初始化或逐個對元素賦值的方法。顯然指標變數指向字串的方式更為方便。