------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
1. 数组指针
1) 数组名只是代表数组的首地址,不代表整个数组
2) 指向数组元素的指针称为数组指针int *p = &a[0]或int *p = a;
3) 使用数组指针间接访问数组的元素
4) 误区:数组指针p为数组首元素的地址,p+1为下一个元素的地址,而不是首地址+1
2. 逆序数组
void nixuArr(int arr[],int len){
//定义变量和指针
int *p,temp;
//指针指向数组
p = arr;
//设置头尾
int i = 0,j = len-1;
//数组元素进行交换
while (i<j) {
temp = *(p+i);
*(p+i) = *(p+j);
*(p+j) = temp;
i++,j--;
}
}
3. 一维指针数组:
存放指针的数组,数组元素都是指针,定义为int *a[5];
4. 指针变量之间的运算
1) 减法运算
① 直接把两个地址进行减法运算意义不大
② 常用方法:两个指针变量都指向同一个数组
i. 判断两个指针变量指向的元素是否连续
ii. 判断两个指针变量之间相隔几个元素
iii. 如果两个指针指向同一个元素,相减的结果为0,相邻元素的指针变量的相减结果为|1|
2) 关系运算
p1>p 结果为1,表示p1在高位,结果为0,表示p在高位或者两个指针指向同一个元素
5. 用数组名访问数组元素
1)列指针:a[0] a[0]+1 a[0]+2
2)行指针:a---->&a[0],a+1------->&a[1],a+2------>&a[2]
3) *(a[i]+j)=a[i][j]=*(*(a+i)+j)表示任意一个元素
6. 用普通指针来访问数组
int a[3][3]={1,2,3,4,5,6,7,8,9};int *p = a;*(p+i)可表示整个数组元素
7. 二维数组指针
1) 行指针:用来指向二维数组的每一行,存放的是行的首地址
2) 定义格式:数据类型 (*行指针变量)[数组第二维长度] int (*p)[4];
3) 二维数组指针初始化
① int a[3][3]={1,2,3,4,5,6,7,8,9,};int (*p)[3]=a;p可代替a使用
8. 指针数组和二维数组指针的区别
二维数组指针变量是单个的变量,指针数组表示有多个指针
int (*p)[3]表示一个指向二维数组的指针变量,该二维数组的列数为3或分解为一位数组的长度为3
Int *p[3]表示p是一个指针数组,有三个下表变量p[0]p[1] p[2]均为指针变量
9. 推箱子游戏
#include <stdio.h>
#define ROW 10
#define COL 10
//交换位置
void move1(char map[ROW][COL],int oldX,intoldY,int newX,int newY){
char temp;
temp = map[oldX][oldY];
map[oldX][oldY] = map[newX][newY];
map[newX][newY] = temp;
}
//打印地图
void printMap(char map[ROW][COL]){
for (int i=0; i<ROW; i++) {
printf("%s\n",map[i]);
}
}
int main(int argc, const char * argv[]){
//定义变量、保存地图、位置信息
//定义地图
char map[ROW][COL]=
{"#########",
"#o ### #",
"# X #",
"##### #",
"# #",
"### #",
"# #####",
"# ",
"#########"};
//定义小人当前位置信息
int personX=1;
int personY=1;
//定义小人要移动的下一个位置信息
int personNextX=1;
int personNextY=1;
//定义箱子位置
int boxX=2;
int boxY=2;
//定义箱子的下一个位置
int boxNextX=2;
int boxNextY=2;
//接收用户输入的方向
char direction;
char way = ' ';
char box = 'X';
//打印地图
printMap(map);
//提示玩法
printf("请输入方向键控制小人移动:a.左 d.右 w.上 s.下 q.退出\n");
//编写程序控制
while (1) {
//接收玩家输入的方向数据
scanf("%c",&direction);
getchar();
//防止穿墙
personNextX = personX;
personNextY = personY;
//判断小人移动的方向
switch (direction) {
case 'w':
case 'W':
personNextX--;
break;
case 'a':
case 'A':
personNextY--;
break;
case 's':
case 'S':
personNextX++;
break;
case 'd':
case 'D':
personNextY++;
break;
case 'q':
case 'Q':
printf("程序退出!\n");
return 0;
}
//判断小人将要移动的位置是否是路
//如果是路,则移动小人:让小人和路进行交换
if (map[personNextX][personNextY] == way) {
move1(map,personX,personY,personNextX,personNextY);
personX = personNextX;
personY = personNextY;
}
//如果不是路,则判断将要移动的位置是否是箱子
//如果是箱子,则计算箱子的下一步位置
else if(map[personNextX][personNextY] == box){
boxNextX = boxX + (boxX - personX);
boxNextY = boxY + (boxY - personY);
// 在判断箱子的下一个位置是否是路
if (map[boxNextX][boxNextY] == way) {
//如果是路,则小人可以推着箱子走
//箱子和箱子的下一个位置交换
move1(map,boxX,boxY,boxNextX,boxNextY);
//小人和箱子原来的位置进行交换
move1(map,personX,personY,boxX,boxY);
//重新调整小人的位置和箱子的位置
personX = personNextX;
personY = personNextY;
boxX = boxNextX;
boxY = boxNextY;
}
}
//如果不是箱子,什么也不做
//重绘地图
printMap(map);
//判断是否出来
if(boxY == COL-2){
printf("哇哦,你出来了!\n");
break;
}
}
return 0;
}
注意:
1)定义地图时,因为是字符串形式,所以列数要多一个,不要忘了‘\0’的存在
2)穿墙问题不要忘记解决
3)存在的bug:连续输入多个方向时会发生小人不动的情况,打个比方:假如小人有分身术,小人的右边是墙,连续按下4个d时,小人不会移动,但是他的分身却向右走了两步(是两步不是四步),所以只有再按下4个a让分身回来,才能继续输入方向让小人移动
10. 字符串指针
1) 用来存放一个字符串 char *p = ”fdsff”;
2) 字符串为常量,在内存中的常量区中,不可以改变,字符串指针只保存字符串的首地址
3) char *str;没初始化没有内存空间,不能直接赋值,为野指针,需要分配内存空间后才可以进行赋值
11. 二维字符数组
1) 定义:char str[3][4]={{‘a’,’b’,’c’},{‘d’,’e’},{‘f’}};
或者char str[3][4]={“abc”,”def”,”ddd”};第二种定义形式要注意不要超出定义的长度,要记得把’\0’计算在内
2)
12. char类型的指针数组
1) char *p[3]={“abc”,”def”,”kkk”};p数组中存放的是各个字符串常量的地址
2)
13. 字符串指针和字符数组的区别
1) 字符串指针:char *s=”abc”;
① S为指针变量,可以改变指向,s=”aaa”;可以改写为char *s;s=”abc”;
2) 字符数组:char str[]=”abc”;
① Str为常量,不能改变,不能定义为char str[10];str={“abc”}