C语言中的二级指针和二维数组问题
關(guān)于二級(jí)指針和二維數(shù)組兩者差別很大,不可以直接用二級(jí)指針傳遞二維數(shù)組
首先來看看二維數(shù)組在內(nèi)存中是如何組織的呢?
一維數(shù)組 T arr1 = new T[9]? 二維數(shù)組T arr2 = new T[3][3]
實(shí)際上,不管是一維還是多維數(shù)組,都是內(nèi)存中一塊線性連續(xù)空間,因此在內(nèi)存級(jí)別上,其實(shí)都只是一維。但是不同的定義使得表現(xiàn)形式不一樣,從而有多維數(shù)組的概念。訪問數(shù)組元素其實(shí)非常簡單,原因就在于元素在內(nèi)存中的線性排列,這樣對(duì)一維數(shù)組的訪問只需要arr1[index] = *(arr1+index*sizeof(T));對(duì)二維數(shù)組的訪問
arr2[i][j]=*(arr2+(i*col+j)*sizeof(T)),因此連續(xù)線性的數(shù)組訪問效率很高。多維類似。
下面一個(gè)程序測(cè)試:
#include<cstdio>
/************************************************************************/
/* 數(shù)組和指針參數(shù)是如何被編譯器修改的?
? “數(shù)組名被改寫成一個(gè)指針參數(shù)”規(guī)則并不是遞歸定義的。數(shù)組的數(shù)組會(huì)被改寫成“數(shù)組的指針”,而不是“指針的指針”:
?
? 實(shí)參? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 所匹配的形參
?
數(shù)組的數(shù)組? ? ? ? ? ? char c[8][10];? ? ? ? ? ? ? ? char (*c)[10];? ? ? ? 數(shù)組指針
?
指針數(shù)組? ? ? ? ? ? ? char *c[10];? ? ? ? ? ? ? ? ? char **c;? ? ? ? ? ? ? 指針的指針
?
數(shù)組指針(行指針)? ? ? char (*c)[10];? ? ? ? ? ? ? ? char (*c)[10];? ? ? ? 不改變
? ?
指針的指針? ? ? ? ? ? char **c;? ? ? ? ? ? ? ? ? ? ? char **c;? ? ? ? ? ? ? 不改變? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? */
/************************************************************************/
/*二級(jí)指針**作為形參,可以接受二級(jí)指針**p、指針數(shù)組*p[]作為實(shí)參的參數(shù),從而傳遞二維數(shù)組*/
void print(int **p, int row, int col)
{
?int i=0,j=0;
?for(i=0;i<row;i++)
?{
? for(j=0;j<col;j++)
? {
? ?printf("%d\t",p[i][j]);
? }
?}
?printf("\n");
}
/*數(shù)組指針(*)[]作為形參,可以接受數(shù)組指針(*p)[3]作為實(shí)參的參數(shù),從而傳遞二維數(shù)組*/
void print(int (*p)[3], int row, int col)
{
?int i=0,j=0;
?for(i=0;i<row;i++)
?{
? for(j=0;j<3;j++)
? {
? ?printf("%d\t",p[i][j]);
? }
?}
?printf("\n");
}
/*function 'void __cdecl print(int ** ,int,int)' already has a body Error executing cl.exe.
/*同二級(jí)指針*/
/*
void print(int *p[], int row, int col)
{
?int i=0,j=0;
?for(i=0;i<row;i++)
?{
? for(j=0;j<col;j++)
? {
? ?printf("%d\t",p[i][j]);
? }
?}
?printf("\n");
}
*/
/******以上兩個(gè)函數(shù)無法重載overload,說明編譯器把*p[]和**p? 都當(dāng)成一種類型******************************************/
int main()
{
?int i = 0;
?int **pointer_to_pointer;
?//printf("%X\n",*pointer_to_pointer);//會(huì)錯(cuò)誤,因?yàn)閜ointer_to_pointer 還未初始化,是野二級(jí)指針
?
?int *pointer = new int[9];
?
?int *pointer_array[3]; //指針數(shù)組,即是一個(gè)存放指針元素的數(shù)組,定義后即會(huì)有含有三個(gè)指針元素的數(shù)組,但是每個(gè)指針元素并沒有初始化
?printf("%X\t%X\t%X\n",pointer_array,pointer_array+1,pointer_array+2);
?printf("%X\t%X\t%X\n",pointer_array[0],pointer_array[1],pointer_array[2]);
?
?int bi_array[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
?int (*array_pointer)[3] = bi_array;//數(shù)組指針,指向數(shù)組的指針,可用于函數(shù)傳遞二維數(shù)組
?int single_array[3] = {1,2,3};
? ?//pointer_to_pointer = bi_array;? //!!! 錯(cuò)誤,二級(jí)指針和二維數(shù)組首地址(實(shí)際內(nèi)存空間不管是N維數(shù)組,都是一片連續(xù)的線性空間,二維數(shù)組元素訪問a[i][j]是a+sizeof(type)*(C*i+j),因此a可以看成是一個(gè)指針而已)不是一個(gè)東西,二者不能相互賦值
? ? ? ? ? //cannot convert from 'int [3][3]' to 'int ** '
?//pointer_to_pointer = (int**)bi_array; // !!!慎用,因?yàn)殡m然沒有語法錯(cuò)誤,但是會(huì)出現(xiàn)內(nèi)存訪問錯(cuò)誤;
? ? //pointer_array = bi_array;//錯(cuò)誤cannot convert from 'int [3][3]' to 'int *[3]'
?
?
?//pointer_to_pointer = bi_array+1;//錯(cuò)誤cannot convert from 'int (*)[3]' to 'int ** '
?/*******************以上說明二維數(shù)組和二維指針不是等價(jià)的,不能相互賦值*************************************************/
?
?pointer_to_pointer = pointer_array;
?/*******以上這句說明指針數(shù)組*[]? 可以轉(zhuǎn)換為二級(jí)指針** 他們相互等價(jià)*****************************************************/
?
?//pointer = bi_array;//錯(cuò)誤cannot convert from 'int [3][3]' to 'int *'
?pointer = (int *)bi_array;
?for(i=0;i<9;i++)
?{
? printf("%d\t",pointer[i]);
?}
?printf("\n");
?
?
?//pointer = array_pointer;//錯(cuò)誤cannot convert from 'int (*)[3]' to 'int *'
?pointer = (int *)array_pointer;
?for(i=0;i<9;i++)
?{
? printf("%d\t",pointer[i]);
?}
?printf("\n");
?for(i=0;i<9;i++){pointer[i] = 9;}? ? //此時(shí)指向bi_array的array_pointer的元素被pointer修改為9
?array_pointer = (int(*)[3])pointer;
?print(array_pointer,3,3);
?/********以上說明二維數(shù)組名和數(shù)組指針雖然是一個(gè)指針,但編譯器并不理解,對(duì)他來說是數(shù)組類型的指針,但可以類型強(qiáng)制轉(zhuǎn)換*****/
?
?for(i=0;i<3;i++)
?{
? pointer_array[i] = bi_array[i];
?}
?printf("\n");
?print((int(*)[3])pointer,3,3);
?print(pointer_to_pointer, 3 ,3);
?print(pointer_array, 3, 3);
?return 0;
}
對(duì)二維數(shù)組做如下總結(jié):
1.二維數(shù)組和二維指針不是等價(jià)的,不能相互賦值
2.指針數(shù)組*[] 可以轉(zhuǎn)換為二級(jí)指針** 他們相互等價(jià)
3.二維數(shù)組名和數(shù)組指針雖然是一個(gè)指針,但編譯器并不理解,對(duì)他來說是數(shù)組類型的指針,但可以類型強(qiáng)制轉(zhuǎn)換
pointer = (int *)array_pointer;? ? array_pointer = (int(*)[3])pointer;? pointer = (int *)bi_array;
4.如果想用函數(shù)傳遞二維數(shù)組,一般形參用二級(jí)指針**p或指針數(shù)組*[],可以支持二級(jí)指針和指針數(shù)組的實(shí)參傳遞,特殊的還可以用(*p)[N]
------------------------------分割線------------------------------
C++ Primer Plus 第6版 中文版 清晰有書簽PDF+源代碼 http://www.linuxidc.com/Linux/2014-05/101227.htm
讀C++ Primer 之構(gòu)造函數(shù)陷阱 http://www.linuxidc.com/Linux/2011-08/40176.htm
讀C++ Primer 之智能指針 http://www.linuxidc.com/Linux/2011-08/40177.htm
讀C++ Primer 之句柄類 http://www.linuxidc.com/Linux/2011-08/40175.htm
將C語言梳理一下,分布在以下10個(gè)章節(jié)中:
本文永久更新鏈接地址:http://www.linuxidc.com/Linux/2015-03/115055.htm?
總結(jié)
以上是生活随笔為你收集整理的C语言中的二级指针和二维数组问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 男孩读计算机好还是铁路学校好,中专学计算
- 下一篇: android同步aar到jcenter