C语言之数组专题:数组指针、指针数组、数组做函数参数退化、数组名、数组类型

来源:互联网 发布:科盟网络 编辑:程序博客网 时间:2024/05/16 07:33

转自:http://blog.csdn.net/wu5215080/article/details/38989381




1、数组初始化:

数组元素的个数可以显示或隐式指定

int main()

{

int a[10] = {1,2};//其他没初始化元素,编译器默认帮你初始化为0

        int b[] = {1, 2};//编译器隐式指定长度为两个元素

        int c[20] = {0};

        for (i=0; i<10; i++)

        {

                  printf("%d ", a[i]);

        }

        memset(a, 0, sizeof(a));

        getchar();

}

 

2、数组名理解难点

int a[10]={1,2};

   printf("&a:%d,a:%d\n",&a,a);

   printf("&a+1:%d,a+1:%d\n", &a+1, a+1);

  1. 数组首元素地址与数组地址:数组名a代表元素首地址,&a代表数组地址。

  2. 数组首元素地址=数组地址即:a=&a

  3. &a+1代表的是加一个数组长度sizeof(a)a+1代表的是加一个数组元素长度sizeof(a[0])

  4. 一维数组名是一个指针常量

  5. 二维数组名是一个数组指针,多维数组名也是一个数组指针,是指向一个低维数组的指针

char array[10][30];

        (array+i)          //相当于i行的首地址      //二级指针

        *(array+i)    //一维数组的首地址          //一级指针

        *(array+i)+j    //相当于第i行第j列的地址  &array[i][j]

        *(*(array+i)+j)  //相当于第i行第j列的地址  array[i][j]

6、多维数组在物理内存中是线性存储的,只是编译器帮我们优化了

 

 

 

2、初学者数组类型三大难题

数组类型

数组指针:数组是一个指针,该指针是指向一个数组的指针(数组类型和数组指针的关系)

指针数组:指针是数组元素,也就是数组元素中存储的都是指针

 

1、       数组类型

C语言中的数组有自己特定的类型,数组的类型由元素类型和数组大小共同决定

1、定义一个数组类型:用数组定义变量

void main12()

{

        int i = 0;

        //定义一个数组类型

        typedef int MyArrayType[5];    //int

        MyArrayType myArray;        //int myArray[5];

        for (i=0; i<5; i++)

        {

                  myArray[i] = i +1;

        }

        for (i=0; i<5; i++)

        {

                  printf("%d \n", myArray[i]);

        }

        system("pause");

}

2、定义一个数组类型,用数组顶一个数组类型的指针

void main13()

{

        int i = 0;   

        typedef int MyArrayType[5];   //定义一个数组类型 

MyArrayType *pArray = NULL; //定义了一个数组类型的指针

Int a[5]={0};

pArray = &a;

for (i=0; i<5; i++)          //我通过数组指针的方式来操作a[5]这块内存

        {

                  (*pArray)[i] = i+1;       //a[i] = i+1;

        }

        for (i=0; i<5; i++)

        {

                  printf("%d \n", (*pArray)[i]);

        }       

        system("pause");

}

 

2、       数组指针

定义数组指针

int i = 0;

        //这个是定义了一个类型,这个类型是数组类型

        typedef int MyArrayType[5]; //int

//这个是定义了一个类型,定义了一个指针类型,定义了一个指向数组的指针类型。。。。

        typedef int (*MyPArrType)[5] ; //数组指针

        MyPArrType myPoint;        //

int b[5]; 

myPoint = &b;             //变量取地址给指针赋值

        for (i=0; i<5; i++)

        {

                  (*myPoint)[i] = i+1;

        }

        for (i=0; i<5; i++)

        {

                  printf("%d  ", (*myPoint)[i]);

        }       

        system("pause");

}

 

        1):typedef int MyArrayType[5];    //定义一个数组类型

                  MyArrayType *pArray = NULL;   //定义了一个数组类型的指针

//这个是定义了一个类型,定义了一个指针类型,定义了一个指向数组的指针类型

        2):typedef int (*MyPArrType)[5] ; //数组指针

                  MyPArrType myPoint; //int b[5];

        3):int (*myArrayPoint)[5] ;   //告诉编译给我开辟四个字节内存

 

5、指针数组

1、指针数组与数组指针容易混淆

Char *p1[] = {“123”,”456”,”789”};

[]优先级高,先与p结合成为一个数组,再由char*说明这是一个字符型指针数组

//这是一个指针数组、数组3*4、三个一维数组的首地址存放在以指针作为元素的数组

Char (*p2)[] = {“123”,”456”,”789”};

//编译器只分配4个字节,是一个指针,编译不通过、错误的方式

2、指针数组做函数参数退化

int printfArray(char *buf [30]);

int printfArray(char *buf[]);

int printfArray(char **buf);

  1. 指针数组的两种用途

    菜单

          命令行

  2. 指针数组自我结束的三种方法

  char*   c_keyword[] = {   "while", "case","static","do",'\0'};

char*  c_keyword[] = {"while", "case","static","do",0};

char*  c_keyword[] = {"while", "case","static","do",NULL};

 

 

 

6、当多维数组当做函数参数的话的时候会退化为指针

退化原因的本质是因为程序员眼中的二维内存,在物理内存上是线性存储

//总结:函数调用的时候,把数组首地址和有效数据长度传给被调用函数才是最正确的做法

一维数组做函数参数退化过程

//int a[10] -=-->int a[] ---->int *a

//数组做函数形参的时候,如果在形参中定义int a[10]语句,

//c/c++编译器会做优化,技术推演如下

//int a[10] -=-->int a[] ---->int *a

 

一维数组做函数参数退化过程

char buf[10][30])—char buf[][30])----char (*buf)[30])

 

int printfArray(char buf[10][30]);

int printfArray(char buf[][30]);

int printfArray(char (*buf)[30]);

这三者效果是一样的,也就验证了数组做函数参数退化为指针

第一种做法

int printfArray(int a[])

{

        int i = 0;

        printf("排序之前\n ");

        for (i=0; i<10; i++)

        {

                  printf("%d ", a[i]);

        }

        return 0;

}

第二种写法

int printfArray04(int *a, int num)

{

 

        int i = 0;

        printf("排序之前\n ");

        for (i=0; i<num; i++)

        {

                  printf("%d ", a[i]);

        }

        return 0;

}                                                              

 

1、 C语言中只会以机械式的值拷贝的方式传递参数(实参把值传给形参)

int fun(char a[20], size_t b)
{
   printf("%d\t%d",b,sizeof(a));
}

原因1:高效

原因2
C
语言处理a[n]的时候,它没有办法知道n是几,它只知道&a[0]是多少,它的值作为参数传递进去了
虽然c语言可以做到直接int fun(char a[20]),然后函数能得到20这个数字,但是,C没有这么做。

2、二维数组参数同样存在退化的问题

二维数组可以看做是一维数组

二维数组中的每个元素是一维数组

二维数组参数中第一维的参数可以省略

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]);

3、等价关系

        

        数组参数                                              等效的指针参数

        

一维数组 char a[30]                                  指针 char*

指针数组 char *a[30]                               指针的指针 char **a

二维数组 char a[10][30]                          数组的指针 char(*a)[30]

 

 

 

7、数组操作基础以及中括号本质

//c语言里面没有字符串这种类型。通过字符数组来模拟字符串

//C风格字符串是以零结尾的字符串

//操作数组的方法:下标法和指针法

 

void main()

{

        int i = 0;

        char *p = NULL;

        //通过字符串初始化字符数组并且追加\0

        char buf4[] = "abcd";       

        for (i=0; i<strlen(buf4); i++)

        {

                  printf("%c", buf4[i]); //p[]

        }       

        //[] *的本质到底是什么?

        //*p 是我们程序员手工的(显示)去利用间接赋值

        //[] 只不过是,c/c++编译器帮我们做了一个*p的操作。。。。。。

        // buf4[i]======> buf4[0+i] ====>  *(buf4+i)

        //===*(buf4+i)   --> bu4[i];

        printf("\n");

        p = buf4;

        for (i=0; i<strlen(buf4); i++)

        {

                  printf("%c", *(p+i)); //*p

        }

        system("pause");

}

void main12()

{

        //字符数组初始化

        //指定长度如果定义的长度剩余部分补充0

        char buf1[100] = {'a', 'b', 'c'};

        //不指定长度

        char buf2[] = {'a', 'b', 'c'};

        char buf3[] = {'a', 'b', 'c','\0'};

        //通过字符串初始化字符数组并且追加\0

        char buf4[] = "abcd";

        printf("%s\n", buf4 );

        printf("sizeof(buf4): %d\n ", sizeof(buf4));

//注意sizeof是对数据类型进行大小测量也就是数组类型包括了\0

        printf("strlen(buf4): %d \n", strlen(buf4));//strlen是求字符串的长度不包括\0

 

        system("pause");

}



0 0
原创粉丝点击