數組做爲函數的參數

《c和指針》》上有一段:

指針和數組並非相等的,ios

當聲明一個數組時,它同時也分配了一寫內存空間,用於存儲數組元素,c++

但當聲明一個指針時,它只分配了用於容納指針的空間(32位中4個字節的大小)。程序員

如:面試

int a[5];
int *p;
a和p都具備指針值,均可以進行間接訪問和下標引用操做。可是他們仍是存在很大區別:
聲明一個數組時,編譯器將根據聲明所指定的元素數量維數組保存內存空間,而後再建立數組名。他的值是一個常量,指向這段空間的起始位置。
聲明一個指針變量時,編譯器只爲指針自己保留內存空間。並且指針變量並未初始化爲任何現有的內存空間。
 
所以上述聲明以後,*a是徹底合法的,*p將會訪問內存中某個不肯定的位置。另外表達式p++能夠經過編譯,但a++卻不能夠,緣由是a的值是一常量 p是一個變量;
 
一維數組訪問
       如下標方式  array[i]      
       以指針方式  *(array+i);
 
   數組名是隱含意義的常指針(直接地址)        其關聯類型是數組元素的類型

站在c++編譯器的角度, *p 至關於咱們程序員手工(顯示)利用間接賦值,去操做內存編程

"[]"是c++編譯器幫咱們程序員作了一個*p的操做數組

當一個數組名做爲函數參數時,數組名的值就是指向數組第一個元素的指針,因此此時傳遞給函數的是指針的拷貝。函數

#include <iostream.h>
int  sum ( int  ap[ ] ,  int  n )
{
   int  m = 0 ;
   for ( int  i = 0 ;  i < n ;  i ++ )
    { 
       m += * ap ; 
       ap ++ ;
    }
    return m;
}
void main()
{   
    int  a [ 10 ] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } ;
    cout << "sum = " << sum ( a , 10 ) << endl ;
}

 

int  sum(int  ap[], int  n)  和int  sum(int  *ap, int  n)效果同樣的spa

指針做爲函數形參和數組做爲函數形參是同樣的.

 

二維數組名一樣表明數組首元素的地址指針

//int b[2][5]===>b的類型爲int(*)[5]不是char**code

 多維數組名的本質:數組指針即指向一個數組的指針

int a[3][5]

(a+i) 表明是整個第i行的地址  

*(a+i)就表示第i行首元素的地址

*(a+i) + j  ===> &  a[i][j]

*( *(a+i) + j) ===>a[i][j]元素的值

 

 

 

 

 

一級指針作函數參數:

int array(char buf[60]);會退化爲指針
int array(char buf[])
int array(char * buf)
二級指針作函數參數
int array2(char array[10][30])//10無做用 30肯定其步長
int array(char array[][30])
int array(char (*array)[30])//數組指針的

 

二維數組能夠看作是一維數組

二維數組中的每一個元素是一維數組

二維數組參數中第一維的參數能夠省略

void f(int a[5])     ====》void f(int a[]);      ===》 void f(int* a);

void g(int a[3][3])====》 void g(int a[][3]); ====》 void g(int (*a)[3]); 

 

 實參   ( 數組參數     ) 所匹配的形參(等效指針參數)
一維數組 char a[30]   指針 char*   (可直接char* p=a;下面的相似)
指針數組 char *a[30]     指針的指針 char **a 指針的指針([30]數組作函數參數退化爲指針 , 何況又是個指針數組因此**)
二維數組 char a[10][30]       數組的指針 char(*a)[30](數組指針
數組指針(行指針)char(*c)[10]      char(*c)[10]    不改變
指針的指針  char**c(二重指針)  char**c            不改變

 

int    printfArr23_1(char myArray[10][30], int iNum)
{
    int i = 0;
    for (i=0; i<iNum; i++)
    {
        printf("%s \n", myArray[i]);
    }
    return 0;
}
int printf2Array_2(char myArray[][30], int iNum)
{
    int i = 0;
    for (i=0; i<iNum; i++)
    {
        printf("%s \n", myArray[i]);
    }
    return 0;
}
int printf2Array_3(char (*myArray)[30],int iNum)
{
    int i = 0;
    for (i=0; i<iNum; i++)
    {
        printf("%s \n", myArray[i]);
    }
    return 0;
}
void main()
{
    int i = 0;
    char myArray[10][30] =  {"ccccc", "aaaa", "bbbb","11111"}; //
    printf2Array_2(myArray, 4);
    printf2Array_3(myArray, 4);
    system("pause");
}

多維數組名本質就是一個數組指針

 

二重指針的用法

(1)二重指針指向一重指針的地址

(2)二重指針指向指針數組的

(3)實踐編程中二重指針用的比較少,大部分時候就是和指針數組糾結起來用的。

(4)實踐編程中有時在函數傳參時爲了經過函數內部改變外部的一個指針變量,會傳這個指針變量的地址(也就是二重指針)進去。

 

 

 

int main()
{
    char* str[] = {"abcde","aqw","ulk"};
    char **str1 = str;// { "abcde", "aqw", "ulk" };不能夠直接定義 **str1 =  { "abcde", "aqw", "ulk" };指針數組指針
    cout << "sizeof(str)" << sizeof(str) << endl;
    cout << "sizeof(str[1])" << sizeof(str[1]) << endl;
    cout << "sizeof(str[0])" << sizeof(str[0]) << endl;
    for (int i = 0; i < sizeof(str) / sizeof(str[0]);i++)
    {
        printf("%s\n", str1[i]);
    }system("pause");
    return 0;
}
char* str[] 與char **str1相等只適用於形參 或者char **str1指向char* str[]
 

華爲的面試題:

如有函數聲明voidf(char** p),則使得函數調用f(var)不正確的var定義是———?

A   char var[10][10];                                 B   char *var[10]

C   void* var=NULL;                                 D   char* v=NULL,**var=&v;

 

解析:

1.char var[10][10];var的類型是 char (*)[10] 類型(不理解的話須要好好看看課本)
2.char *var[10]; var數組是存放char *類型的數組,數組名var是數組var元素的首地址,因此var的
類型是char**類型
3.void * 是定義沒有指針類型的指針,void *能夠指向任何類型的數據。在c99中舉個例子int *p = malloc(sizeof(int)); 能夠不寫強制類型轉換,由於malloc返回一個void *類型的指針,

char**p = malloc(100);  這樣定義同樣能夠經過
4.v是char*類型的,那麼取v的地址確定是char**類型的,因此var是char**類型的。

 

結構體變量做爲函數形參的時候,實際上和普通變量(相似於int之類的)傳參時表現同樣的。因此說結構體變量其實也是普通變量。

用結構體變量做實參時,採起的是「值傳遞」的方式

相關文章
相關標籤/搜索