目录
二维数组
定义方式
<数据类型><数据名> [行号][ 列号]
初始化
int a[3][2]={0}; //所有数组元素均为0
int a[3][2]={1,2,3,4,5,6}; //常规的赋值方法
int a[3][2]={{1,2},{3,4},{5,6}}; //分行的赋值方法
int a[3][2]={{1,2},{0},{3}}; //部分赋值方法,第一行为1,2;第二行都是0;第三行3,0
int a[][3] = {1, 2, 3, 4, 5 , 6, 7, 8}; //有缺省的初始化
int a[3][2];/先定义
for(i=0;i<=3;i++) //用双重for循环赋值,i,j表示二维数组下标
for(j=0;j<=2;j++)
scanf("%d",&a[i][j]);
二维数组的理解
实际上,不管是一维还是多维数组,都是内存中一块线性连续空间,因此在内存级别上,其实都是一维的。 请看实例:
#include <stdio.h>
#define X 3
#define Y 4
int main()
{
int a[X][Y] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
int ** p;
int i, j;
p = (int**)a;
for (i = 0; i < X*Y; i++)
{
printf("%d ", *p);
p++;
}
while (1);
}
通常我们认为数组名是一个指针常量(例如,int a[10]; 那么a是一个int * const),这种理解是不全面的,正确的理解如下:
作为右值(例如,赋值语句右边)时数组名可视为指针常量(系统自动转换),例如,上面的代码不可以这样写:
int main()
{
int a[X][Y] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
int i, j;
for (i = 0; i < X*Y; i++)
{
printf("%d ", *a);
a++;//因为此时为一个常量
}
while (1);
}
作为左值,例如取地址,sizeof,则不能视为指针:
#include <stdio.h>
int main()
{
int a[X][Y] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
printf("%d\n", &a); //此时a为变量,因为常量不可以进行取地址运算
while (1);
}
二级指针
指向一级指针的指针变量。
定义方式:
int a;
int* p = &a;
int** q = &p;
例子:
#include <stdio.h>
int main()
{
int a = 0;
int *p = &a;
int **pp = &p;
printf("%d\n", *p);
printf("%d\n", *(*pp));
while (1);
}
数组指针
定义: <数据类型> (*<指针变量>)[列号];
int (*p)[3]; //数组指针
int *p[3]; //指针数组
[3]代表 p+1 的偏移量为:3*sizeof(int); 实质上,p 为一个特殊的二级指针;实际上:* 和 [] 有同质的关系;请看实例:
#include<stdio.h>
#include<string.h>
#define X 2
#define Y 3
void main(void)
{
int a[X][Y];
int(*p)[Y] = a;
int i, j, sum = 0;
for (i = 0; i<X; i++)
{
for (j = 0; j<Y; j++)
{
scanf_s("%d", *(p + i) + j);
sum += *(*(p + i) + j);
}
}
printf("%-4d\n", sum);
while(1);
}