目录
数组指针
-
一维数组与指针
指针表示地址,数组名对应着数组的首地址,所以可以通过指针访问数组元素
数组通过数组名+下标的方式访问元素
数组的指针就是数组所在的存储区域的起始地址
数组元素的指针就是数组元素存储单元的地址
例:
#include<stdio.h>
int main()
{
int arr[5]={0,1,2,3,4},i,*p;
p=NULL;
printf("%d\n",p);//printf函数直接显示指针地址,运行结果为0
p=arr;
printf("%x *p=%d\n",p,*p);//%x 表示输出16进制,*p=0,这时p指向数组的首地址,输出的值就是数组首个元素的值
for(i=0;i<5;i++)
printf("%x *p=%d\n",p++,*p);
return 0;
}
运行结果如下:
数组名代表数组首地址,即数组这首个元素的地址
a与&a[0]等价:a是地址常量,是系统分配空间时返回的地址,不是变量不能给af赋值
如果能赋值就是重新指一段连续的空间了
如何用指针使用数组
1.指向数组首地址的指针变量的定义及赋值方式
(1)定义的同时进行初始化赋值
类型 *指针变量名=数组名或&数组名[0]
(2)先定义后赋值
类型 *指针变量名;
指针变量名=数组名或&数组名[0]
2.指向数组元素的指针变量的定义和赋值方式
(1)定义的同时进行初始化赋值
类型 *指针变量名=&数组名[下标];
(2)先定义后赋值
类型 *指针变量名
指针变量名=&数组名[下标]
注意:定义和赋值中的类型要与数组的基类型一致
定义指针类型一定与数组的类型相同
例子:
#include<stdio.h>
void f(int *x,int *y)//函数f的参数是指向整型数据的指针,传递的是地址
{
int t;
t=*x;
*x=*y;
*y=t;//这三个赋值语句是对指针所指单元的进行交换
}
main()
{
int a[8]={1,2,3,4,5,6,7,8},i,*p,*q;
p=a;q=&a[7];//指针变量p取a的首地址,q取a7的地址
while(p<q)//用指针比较,也就是地址的比较
{ //在数组中元素单元实际地址是(首地址 +下标 )*4
f(p,q);p++;q--;
}
for(i=0;i<8;i++)
printf("%d,",a[i]);
}
过程分析:
/函数f的功能是交换两个 参数变量的值
x,y作为形参,p、q为数组元素的地址作为实参 ,改变形参指针对应单元的值,实际就是修改实参变量单元的值
在函数中对数组的操作实际上是对主程序中的实参数组操作
main()函数中执行了4次循环 ,实现了a[0]与a[7]、a[1]和a[6]、a[2]和a[5]、a[3]和a[4]的交换
运行结果如下:
数组元素的引用方式
1.下标法
main()
{
int a[10],i;
for(i=0;i<10;i++)
scanf("%d",&a[i]);
printf("\n");
for(i=0;i<10;i++)
printf("%d",a[i]);
}
2.指针法
main()
{
int a[10],*p,i;
p=a;//取初始地址,数组首地址
for(i=0;i<10;i++)
scanf("%d",p++);
printf("\n");
for(p=a;p<(a+10);p++)//用数组+1,表示取下一个单元地址。 用数组-1,表示取上一个单元地址。不是地址值的加减1
printf("%d",*p);
}
-
二维数组与指针
例:输出两行三列的矩阵元素
#include<stdio.h>
int main()
{
int a[2] [3],*p,i,j;
for(i=0;i<2;i++)
for(j=0;j<3;j++)
{
p=&a[i][j];
scanf("%d",p);//p代表地址在输入函数中,实现输入数据到相应的存储单元
}
for(i=0;i<2;i++)
{
printf("\n");
for(j=0;j<3;j++)
{
p=&a[i][j];
printf("%4d",*p);//*p表示p指示相应存储单元的值
}
}
}
本例中,指针变量都是指向数组具体的某一个存储单元,和数组名是有区别的
1.指向二维数组首地址的指针变量
(1)定义的同时赋初始值
数据类型*指针变量=&二维数组名[0][0];
(2)先定义后赋值
数据类型*指针变量;
指针变量=&二维数组名[0][0];
注:定义时用首元素地址时,不是用数组名,也不能用。因为数组名在二维数组中代表首行地址。可以理解为二维数组是一维数组的推广,也就是N维数组也是一维数组。其元素有N-1维数组构成,也就是二维数组名代表首行地址。这与首元素地址有很大区别:表现在指针移动上。一维数组有X个元素。地址只能往后移动X-1次
例:使用指向二维数组首地址的指针变量
#include<stdio.h>
int main()
{
int a[2][3]={0,1,2,3,4,5},*p=a,i,j;
for(i=0;i<2;i++)
{
printf("\n");
printf("%x",p+i*3);
for(j=0;j<3;j++)
{
printf("%x ",p+i*3+j);
printf("%d ",*(p+i*3+j));
}
}
printf("\n");
return 0;
}
2.指向二维数组中某个一维数组的指针变量
(1)定义指针变量
数据类型(*指针变量)[m];
m:二维数组的列长,()不能丢。不能写成“*指针变量[m]”,因为[ ]运算符优先级高于*
(2)将指针变量指向二维数组的首地址
定义时赋初值
数据类型(*指针变量)[m]=二维数组名;
先定义,后赋值
数据类型(*指针变量)[m];
指针变量=二维数组名
(3)二维数组中第i行对应的一维数组首地址表示
*(指针变量+i)
(4)数组元素地址
*(指针变量+行下标)+列下标
(5)数组元素引用
*(*指针变量+行下标)+列下标)
例:
int a[2][3],(*p)[3]=a;
则有如下等价关系成立:a[i]等价于*(p+i)表示第i行地址
a[i][j]等价于*(*(p+i)+i表示第 i 行第j列元素
字符串与指针
1.将指针变量指向字符串常量
(1)
数据类型 *指针变量=字符常量;
例:char *p="abcd";
(2)
数据类型 *指针变量;
指针变量=字符串常量;
char *p;
p="abcd";
2.指向字符串常量指针变量的使用
输出字符串常量:
printf("%s",指针变量);
第i个字符的表示方法: *(指针变量+i);
注意:
对指向字符串常量的字符型指针进行再输入会出现错误
例如: char *p="1234";
scanf("%s",p); 是错误的,因为p已经指向了一个常量区域,就不能用输入改变常量的值了
定义的字符数组可以输入
例如:char a[10],*p=a;
scanf("%s",p);
例:字符串的复制
#include<stdio.h>
int main()
{
char a[]="Hava Fun",b[20];
int i;
for(i=0;*(a+i)!='\0';i++)//表示数组a的字符不是反斜杠0就继续,用的是指针访问数组a
*(b+i)=*(a+i);//把数组a的值一个一个赋给b
*(b+i)='\0';
printf("b:");//循环结束后,把反斜杠0送给b
for(i=0;b[i]!='\0';i++)
printf("%c",b[i]);//使用循环数组对数组b逐个字符输出
printf("\n");
return 0;
}
结构体指针
1.指向结构体变量的指针
定义:指向结构体变量的指针为结构体指针,它保存了结构体变量的存储首地址
结构体指针的定义形式:
struct 结构体类型名 *指针变量名;
例如: struct student stu,*p;
要引用结构体变量p,就要把已存在的结构体变量的地址赋给它
比如p=&stu;(p指向stu)
此时指针变量p的值就是结构体变量stu的起始地址
结构体成员变量的引用形式
- 结构体变量名.成员名;
- (*结构体指针).成员名
- 结构体指针->成员名;
例如:stu.age=20;
(*p).age=20;
p->age=20; 其中->为指向成员运算符
指针变量也可以用来指向结构体数组中的元素,只要改变指针变量的值就可以通过它访问结构体数组中的各个元素
例如:
struct person{
char name[10];
int age;};
struct person *p,s,boy[3]={"Zhang",18,"Wang",20,"Li",17};
p=boy;
定义了结构体数组boy和结构体指针变量p,p=boy,代表p指向数组boy的首地址
相当于p=&boy[0]
2.指向结构体数组的指针
例:使用指针变量输出boy数组中的元素
#include<stdio.h>
int main()
{
int i;
struct person{
char name[10];
int age;
}*p,boy[3]={"Zhang",18,"Wang",20,"Li",17};
for(p=boy,i=0;i<3;i++)
printf("%s %d\n",p[i].name,p[i].age);
}
运行结果如下:
3.用结构体变量作为函数参数
结构体变量作为函数参数,实现值传递
指向结构体的指针(或数组)作为函数参数,实现地址传递
#include<stdio.h>
struct stu
{
int num;
float score;
};
void f(struct stu *p)
{
struct stu s[2]={
{01,96},{02,89}
};
(*p).num=s[1].num;
(*p).score=s[1].score;
}
main()
{
struct stu s[2]={
{03,93},{04,96}
};
f(&s[0]);
printf("%d %3.0f\n",s[0].num,s[0].score);
}
运行结果如下: