1.定义指向数组元素的指针变量:
inta[10];
int* p;
p= &a[0];
把a[0]元素的地址赋给指针变量p。也就是使p指向a数组的第0个元素。
C语言规定,数组名代表该数组中首元素的地址。因此,下面两个语句等价:
p= &a[0];
p= a;
在定义指针变量时可以对它赋予初值:例:
int* p = &a[0];
它等效于下面两句:
int* p;
p= &a[0];
也可以在定义时写成:
int* p = a; (将a数组首元素阿地址赋值给指针变量p)
2. C语言规定: 如果指针变量已指向数组中的一个元素,则指针变量+1指向同一数组中的下一个元素,而不是将p的值(地址)简单的+1例如:
voidmain() {
inta[] = {1,2,3,4,5,6};
int* p1 = a;
printf("%d\n", *p1);
p1= p1 + 1; /*也可以写成:p1= a + 1;*/
printf("%d\n",*p1);
}
输出:1 2
如果p1的初值为&a[0],则:
a)p1 + i或者a+ i,就是a[i]的地址。
b)*(p+i)或*(a+i)表示p+i或a+i所指向的数组元素,即a[i]。
3.引用一个数组元素:
a)下标法,如a[i]形式
b)指针法,如*(a+i)或*(p+i)。其中a是数组名,p是指向数组元素的指针变量。
4.用3中方法输出数组中的全部元素。
a)for循环
b) *(p+i)方式
voidmain() {
int*p,i;
inta[] = {0,1,2,3,4,5,6,7,8,9};
p= &a[0];
for(i= 0; i < 10; i++) {
printf("%d",*(p+i));
}
}
c)* p方式
voidmain() {
int*p,i;
inta[] = {0,1,2,3,4,5,6,7,8,9};
for(p= a; p < (a+10); p++) {
printf("%d",*p);
}
}
5.使用指针变量指向数组元素时,需要注意:
a)可以通过改变指针变量的值指向不同的元素。例如,上面3种遍历数组方法中的第三种c)* p方式就是用指针变量p来指向元素,用p++使p的值不断改变从而指向不同的元素。如果不用p而使数组名a变化是不行的。例如:
for(p= a; a < (p + 10); a++) {
printf(“%d”,*a);
}
因为数组名a代表数组首元素的地址,是一个指针常量,它的值在程序运行期间是不变的。因此a++无法实现。
b)要注意指针变量的当前值。
c)在定义数组时,虽然指定了数组的长度,但是实际上指针变量可以指向数组长度后面的元素,例如:
voidmain() {
int*p,i;
inta[] = {0,1,2,3,4,5,6,7,8,9};
p= a;
printf("%d",*(p + 10)); /*指向数组的第11个元素,但是a数组只有10个元素*/
}
编译运行并不出错,输出:-1076023500
应该避免出现这样的情况。在使用指针变量指向数组元素时,应该保证指针指向数组中有效的元素。
d)注意指针变量的运算。 如果p指向数组a的首元素(p= a),则:
1)p++ (或p+=1).使p指向下一个元素,即a[1]。若再执行*p,则得到下一个元素a[1]的值。
2)* p ++,由于++和*同优先级,所以结合方向自右而左,因此它等价于*(p++)。作用是先输出*p的值,然后再p+1,例如:
voidmain() {
int*p,i;
inta[] = {0,1,2,3,4,5,6,7,8,9};
p= a;
printf("%d",*p++);
}
输出:0
voidmain() {
int*p,i;
inta[] = {0,1,2,3,4,5,6,7,8,9};
p= a;
printf("%d",*++p);
}
输出:1
3)*p++和*++p作用不同。前者是先取得*p的值,再加1,后者是先加1,再取得*p的值。如果p初值为a(即p=&a[0]),则*p++为a[0],*++p为a[1]。
6.当用数组名作为参数时,如果形参数组中各元素的值发生变化,实参数组元素的值也会改变。
7.实参数组名代表该数组的首元素。而形参用来接受从实参传递过来的首元素地址。因此,形参一个是一个指针变量(只有指针变量才能存放地址)。实际上C编译都是将形参数组名作为指针变量来处理的。例如:
swap(intarr[],int n)
在编译时将arr作为指针变量处理,相当于:
swap(int* arr,int n)
8.多维数组与指针
a)多维数组元素的地址
int a[][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
从二维数组的角度看,a代表二维数组首元素的地址,现在首元素是一个由4个整形元素的组成的一维数组,因此a代表的是第0行的首地址。a+1代表第1行首地址,a+1的含义是a[1]的地址。
a[0],a[1],a[2]是一维数组名,在C语言中规定数组名代表数组首元素地址,因此a[0]代表一维数组a[0]中第0列元素的地址,即&a[0][0]。a[1]的值是&a[1][0],a[2]的值是&a[2][0]。
a[0]为一维数组,应该用a[0]+1来表示0行1列元素的地址。正如有一个一维数组x,x+1是其第一个元素x[1]的地址一样。a[0]+0,a[0]+a分别是a[0][0]和a[0][a]元素的地址。
a[0]和*(a+0)等价(因为a是一个二维数组,所以*(a+0)内容是一个一维数组的地址),a[1]和*(a+1)等价,a[i]和*(a+i)等价。因此a[0]+1,和*(a+0)+1都是&a[0][1]。a[1][2]和*(a+1)+2的值都是&a[1][2]。
既然a[0]+1和*(a+0)+1是a[0][1]的地址,那么*(a[0]+1)就是a[0][1]的值了。同理*(*(a+0)+1)或者*(*a+1)也是a[0][1]的值。
对a[i]的性质作进一步说明:a[i]从形式上看是a数组中的第i个元素。
如果a是一维数组名,则a[i]代表a数组序列号为i的元素所占内存的内容。a[i]是有物理地址的,是占内存的。
但是如果a是二维数组名,则a[i]代表一维数组名。它只是一个地址,并不代表某一元素的值(如同一维数组名只是一个指针)。a,a+i,a[i],*(a+i),*(a+i)+j,a[i]+j都是地址。而*(a[i]+j)或者*(*(a+i)+j)是二维数组元素a[i][j]的值。
9.例,输出二维数组有关的值。
#include<stdio.h>
#defineFORMAT "%d,%d \n"
voidmain() {
inta[][3] = {{1,2,3},{4,5,6},{7,8,9}};
printf(FORMAT,a,*a);//0行首地址和0行0列元素地址
printf(FORMAT,a[0],*(a+0));//0行0列元素地址
printf(FORMAT,&a[0],&a[0][0]);//0行首地址和0行0列元素地址
printf(FORMAT,a[1],a+1);//1行0列元素地址和1行首地址
printf(FORMAT,&a[1][0],*(a+1)+0);//1行0列元素地址
printf(FORMAT,a[2],*(a+2));//2行0列元素地址
printf(FORMAT,&a[2],a+2);//2行首地址
printf(FORMAT,a[1][0],*(*(a+1)+0));//1行0列元素的值
}
输出:
-1076350692,-1076350692
-1076350692,-1076350692
-1076350692,-1076350692
-1076350680,-1076350680
-1076350680,-1076350680
-1076350668,-1076350668
-1076350668,-1076350668
4,4
9.用指针变量输出二维数组元素的值
#include<stdio.h>
void main() {
int a[][4] = {{0,1,2,3},{4,5,6,7},{8,9,10,11}};
int * p;
for(p= a[0]; p < a[0] + 12; p++) {
if((p- a[0]) % 4 == 0) {
printf("\n");
}
printf("%4d",*p);
}
printf("\n");
}
输出:
0 1 2 3
4 5 6 7
8 9 10 11
10.如果要输出某个指定的数值元素(例如a[1][2]),则应事先计算该元素在数组中的相对位置(即相对于数组起始位置的相对位移量)。计算a[i][j]在数组中的相对位置的计算公式为:
i* m + j
其中m为二维元素的列数。例如,3x4的二维数组,它的2行3列元素a[2][3]对a[0][0]的相对位移量为2*4+3=11字节。如果开始时使用指针变量p指向a[0][0],为了得到a[2][3]的值,可以用*(p+2*4+3)表示,(p+11)是a[2][3]的地址。a[i][j]的地址为&a[0][0]+i*m+j。
例子:输出二维数组任意一行任意一列元素的值。
#include<stdio.h>
void main() {
int a [][4] = {{0,1,2,3},{4,5,6,7},{8,9,10,11}};int num1,num2;num1 = 1;
num2 = 2;
int (*p)[4];
p = a;printf("%d\n",*(*(p+num1)+num2));
}
输出:6
程序中有 int(*p)[4]; 表示p是一个指针变量,指向包含4个整形元素的一维数组。
1)int a[4]; a有4个元素,每个元素为整形
2)int (*p)[4]; *p有4个元素,每个元素是整形。p是指向一维数组的指针。
11.用指向数组的指针作函数参数。用指针变量做形参有两种方法:a)用指向变量的指针变量 b)用指向一维数组的指针变量.
例子:有3个学生,4门成绩,计算宗总平均分和第n个学生的成绩。
#include<stdio.h>
voidmain() {
int a [][4] = {{76,76,58,67},{88,79,87,69},{98,78,78,97}};
void average(int * p,int n);
void search(int (*p)[4],int n);
average(a[0],12);
search(a,2);
}
void average(int * p,int n) {
int* p_end;
int sum = 0,aver;
p_end= p + n - 1;
for(;p <= p_end; p++) {
sum= sum + (*p);
}
aver= sum / n;
printf("average= %d \n",aver);
}
voidsearch(int (*p)[4], int n) { // p指向一个具有4个元素的一维数组
int i;
for(i= 0; i < 4; i++) {
printf("%d",*(*(p+n)+i));
}
printf("\n");
}
输出:
average= 79
9878 78 97
例子:在上例基础上,找到一门课程不及格的学生,输出他的全部成绩。
#include<stdio.h>
voidmain() {
int a[][4] = {{76,76,58,67},{88,79,87,69},{98,78,78,97}};
void search(int (*p)[4],int n);
search(a,3);
}
void search(int (*p)[4], int n) {
int i,j,flag;
for(j= 0; j < n; j++) {
flag= 0;
for(i= 0; i < 4; i++) {
if(*(*(p+j)+i)< 60)
flag= 1;
}
if(flag== 1) {
printf("No:%dstudent \n",j+1);
for(i= 0; i < 4; i++) {
printf("%d",*(*(p+j)+i));
}
printf("\n");
}
}
}
输出:
No:1student
7676 58 67
文章链接:http://blog.csdn.net/murongshusheng/article/details/8690295