数组做为函数的参数

《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之类的)传参时表现同样的。因此说结构体变量其实也是普通变量。

用结构体变量做实参时,采起的是“值传递”的方式

相关文章
相关标签/搜索