一、指针与数组(一维)
a+k = &a[k]
*(a+k) = a[k]
如果将数组的起始地址赋给某个指针变量,那么该指针变量就是指向数组的指针变量.
int a[10],*p=a;(或*p=&a[0])
*(p+i)、*8(a+i)和p[i]就是数组元素a[i]
p+i和a+i、&p[i]都是数组a[i]的地址
p+1指向数组的下一个元素,而不是简单地使指针变量p的值+1。其实际变化为p+1size(size为一个元素占用的字节数)。例如,假设指针变量p的当前值为2000,则p+1为2000+12=2002,而不是2001。
p[k] = ’A’+k
相当于 *(p+k) = ’A’+k
*p++ = ’A’+k
相当于
*p = ’A’+k;
p++;
二、多维数组
1)二维数组的行地址与列地址
1、一般指针变量
当二维数组的首地址赋给指针变量p以后,则访问某个元素a[i][j]可用以下几种方式来代替:(p+in+j)、p[in+j]、(a[0]+i*n+j)
2、行指针变量
a[i][j]可用以下几种方式来代替:
*(a[i]+j)、*(*(a+i)+j)、(*(a+i))[j]
3、对于二维数组int a[3][4],有
a -------------------- 二维数组的首地址,即第0行的首地址
a+i ------------------ 第i行的首地址
a[i] 、(a+i)-----------第i行第0列的元素地址
a[i]+j、(a+i)+j --------第i行第j列的元素地址
*(a[i]+j) = *(*(a+i)+j) = a[i][j]
a+i = &a[i] = a[i] = (a+i) = &a[i][0],值相等,含义不同
a+i、&a[i],表示第i行首地址,指向行
a[i]、(a+i)、&a[i][0],表示第i行第0列元素地址,指向列
4、指针指向变量对二维数组的引用
初始化:p=a;或p=&a[0];
a[i][j] 可用以下几种方式来代替:
p[i][j],*(p[i]+j),*(*(p+i)+j),(*(p+i))[j]
对指向二维数组的指针变量进行赋值一般形式为:
(1) 二维数组名+整型常数n,如:p = a + 1; 或
(2) &二维数组名[整型常量n],如:p = &a[1]。
不可用数组单元地址对其赋值。
如:p = a[0];或p = &a[0][0]都是错误的。
2) 通过二维数组的行指针来访问二维数组
int a[2][3];
int (*p)[3]; (V)
int *p[3]; (X)
int (*p)[2]; (X)
int (*p)[3]; //定义一个数组指针,该指针指向含3个元素的一维数组(数组中每个元素是int型)。
int *p[3]; //定义一个指针数组,该数组中每个元素是一个指针,每个指针指向哪里就需要程序中后续再定义了。
区分int *p[n]; 和int (*p)[n]; 就要看运算符的优先级了。
int p[n]; 中,运算符[ ]优先级高,先与p结合成为一个数组,再由int说明这是一个整型指针数组。
int (*p)[n]; 中( )优先级高,首先说明p是一个指针,指向一个整型的一维数组。
//指针数组对键盘输入的五个值用冒泡从小到大排序
int main()
{
int i, j, t;
int a, b, c, d, e;
//将a,b,c,d,e的内存地址分别赋给p[0]...p[4]
int *p[5] = {&a, &b, &c, &d, &e};
//对a,b,c,d,e赋值
scanf ("%d,%d,%d,%d,%d", p[0], p[1], p[2], p[3], p[4]);
for (i = 0; i < 4; i++) //利用冒泡法排序
for (j = i + 1; j < 5; j++)
if (*p[i] > *p[j]) //交换p[i]、p[j]所指向的变量值
{
t = *p[i];
*p[i] = *p[j];
*p[j] = t;
}
for (i = 0; i < 5; i++) //显示排序后的结果
printf("%d ", *p[i]);
}
该方法是将a,b,c,d,e所对应的内存单元的值进行交换,而指针数组并无变化