C语言之数组和指针
2017-07-23 10:53
281 查看
C语言之数组和指针
数组指针
const数组及指针
数组
一维数组多维数组
变长数组
数组字面量
数组是C语言中一种复合数据类型,数组是同一类型的序列,C中的数组在建立后其大小维度就不能变化(边长数组除外)。数组分为一维数组、二维数组、多维数组(二维及以上),数组中的元素下标都是以0开始。
一维数组
如下便定义了一个一维数组: int arry[10]; 该数组的维度为1,大小为10,包含了10个元素,从arry[0]~arry[9]共10个数据元素,每个数据元素都是int类型,类似的可以定义其他数据类型的数组,访问数组时,可以通过值在0~9的下标i访问数组中的第i+1个数据元素。 一维数组在初始化时,用花括号的方式将初始化元素包含在内即可,未被初始化的元素其值被默认置为0。c99之前,若要初始化第i个元素,则必须要求初始化i个元素之前的元素,如,若要初始化数组arry中的第5个数据元素,则必须要初始化第5个数据元素之前的所有元素,即: int arry[10]={1,2,3,4,5}; 未被初始化的剩余元素全部置为0。C99引入了指定初始化器,可以对数组中的特定元素进行初始化,而不必像上面那样必须初始化之前的元素,同上面的例子,如要初始化第5个数据元素,可以采用下面的方式: int arry[10]={[4]=5}; 进行这样的初始化之后,其余元素都被置为了默认值0。 在访问数组元素时,C语言对于访问下标越界的数组元素的行为是未定义的,若访问arry[10]或arry[-1],有的编译器可能不会报错,这源于C语言对程序员的信任,认为程序员有责任确保数组不越界,所以不会报错,但这样可能会修改存储空间中其他元素的值,造成意想不到的后果。另外只有在定义数组并进行初始化时才可以用“{ }”进行初始化,否则不能用“{ }”进行初始化。
二维数组
如下便定义了一个二维数组: int arry[2][2]; 该数组的维度为2,大小为2x2,即2行2列的数组,包含了4个元素,从arry[0][0]、arry[0][1]、arry[1][0]、arry[1][1],每个数据元素都是int类型,类似的可以定义其他数据类型的数组,访问数组时,可以通过值在0~1的行下标i,和列下标j访问数组中的第i+1行,第j+1列的数据元素。 对于二维数组arry[m] (m和n分别代表行数和列数),在初始化时,可以将每个arry[i](0<i<m-1)作为一个包含n个元素的一维数组,然后分别进行初始化,比如在初始化arry[2][2]时,可以采用下面的方式: int arry[2][2]={ {1,1},{2,2}}; 其他类型的二维数组可以采用类似的初始化方式进行初始化。
变长数组
C为了适应科学计算的需要,从C99开始,数组的维度大小可以进行变化,形成了边长数组(VLA)。在定义边长数组时,要先定义数组的维度变量,再定义数组: int rows,cols; rows=5; cols=2; int arry[rows][cols]; 这样就定义了一个5行2列的变长数组。 在对变长数组进行初始化时,只能先定义数组然后再进行初始化,不能再定义数组的同时进行初始化,这点事变长数组与一般数组不同的地方:
//vla_init---变长数组的初始化 #include <stdio.h> int main(void) { int rows,cols; //定义变长数组的维度大小 rows=2; cols=3; int arry[rows][cols]; //只能先定义再初始化,不能定义的同时初始化 for (int i=0; i<rows; i++) //初始化数组 { for (int j=0; j<cols; j++) arry[i][j]=i+j; } printf("%d",arry[1][2]); 4000 //输出数组 return 0; }
另外在使用变长数组作为函数形参时,必须先定义数组的维度大小变量再定义数组,若要省略函数形参,可以直接用*号代替数组维度变量,然后把后续数组的维度变量替换为*即可。
//vla.c---变长数组 #include <stdio.h> int main(void) { void showarry(int,int,int arry[*][*]); int arry1[4][2]={{0,1},{2,3},{4,5},{6,7}}; //静态数组,一般数组 int arry2[2][3]={{1,2,3},{4,5,6}}; showarry(4,2,arry1); //输出一般数组 showarry(2,3,arry2); //输出一般数组 return 0; } void showarry(int rows,int cols,int arry[rows][cols]) //该函数由于采用了边长数组,因此可以处理一切大小的数组 { int i,j; printf("rows\tcols\tarry[i][j]\n"); for(i=0;i<rows;i++) for(j=0;j<cols;j++) printf("%d\t%d\t%d\n",i,j,arry[i][j]); }
数组字面量
C99为了程序调试的方便,引入了数组字面量的概念,在C99之前,字面量仅局限于C的内置类型,C99之后将这一概念扩展到了复合类型。 使用数组字面量得到的是一个无名空间,需要用一个指向该无名空间的指针才能使用该数组字面量,数组字面量可以作为函数形参,也可以作为一般的变量使用。 int *p1=(int []){1,2}; int *p2=(int [][2]){{1,1},{2,2},{3,3}}; 这样就创建了一个长度为2的数组字面量和3x2大小的数组字面量,并可以通过P1、p2指针引用他们。
指针
定义数组的指针表示法
指向一维数组和二维数组的指针
定义
指针就是变量对象在内存空间中的地址,C中可以定义指针变量来访问某个变量,这样的访问方式称之为间接访问,指针变量中的值是所指向变量的地址,通过&可以取得某个变量的地址,通过*可以获得某个变量地址上这个变量的值。每个指针变量都有类型,都指向特定类型的变量。 int n=3; int *p=&n; *p=2; 定义了一个值为3的变量和一个指向整型变量的指针,通过&使得p指针指向了变量n,然后通过*p获得该变量的值。这里的p指针变量是一个指向int类型的指针,若换成其他类型的指针,则会报错。
数组的指针表示法
数组和指针实际上是等价的,数组名相当于数组的起始地址,可以通过数组本身带下标的方式或者指针方式来对数组元素进行访问。 在使用数组的指针表示法时,若是一维数组可以采用*(arry+i)的方式访问arry[i],若是二维数组,可以采用*(*(arry+i)+j)的方式访问arry[i][j]。
指向一维数组和二维数组的指针
定义指向一维数组的指针时,可以采用 type *p的方式进行定义,但在定义二维数组的指针时,要指明数组第二维的维度,采用type (*p)[cols]的方式定义二维数组指针。 在定义高维数组指针时,类似的需要指明除第一维外其余维度的维度信息。采用type (*p)[ ][dim2][dim3]...[dimn]。
const数组及指针
C为了防止更改数组或者指针指向的元素,使用const限定符防止此类事情的发生。 const数组: const type arry[dim1][dim2]...[dimn]={....}; const指针: const type *p; 以上定义了一个const数组和一个const指针,const数组中的元素不能进行更改,且在定义的时候必须初始化。const指针表明不能通过指针改变所指向元素的值,但可以改变指针的指向,如果采用下面的定义方式: type *const p; 则不能改变p指针的指向,但可以改变指针所指元素的值。
相关文章推荐
- 浅谈C语言 extern 指针与数组
- C语言之数组,字符串,指针
- 关于C语言字符数组、字符串和指针的相关问题
- C语言数组指针(指向数组的指针)
- C语言中字符数组和字符串指针分析
- C编译器剖析_1.5 结合C语言来学汇编_指针、数组和结构体
- C语言--- 高级指针2(结构体指针,数组作为函数参数)
- C语言编程(练习5:数组与指针)
- C语言数组名和指针
- C语言指针数组
- 【转】C语言->数组名与指针
- C语言-指针数组_大小写字母转换
- C语言多维数组与多级指针
- day_13 C语言数组和指针
- 关于C语言中的数组指针、指针数组以及二级指针
- c语言学习,指针函数、函数指针、指针的指针、指向指针数组的指针
- C语言 复杂指针的申明问题 数组指针 指针数组 函数指针 指针函数一览无遗! C/C++求职面试必备考点(四)
- 再谈C语言中数组和指针之间的互操作
- 使用python向C语言的链接库传递数组、结构体、指针类型的数据
- C语言一级指针、二级指针、数组作为参数传递需要注意的若干问题