黑马程序员--C语言自学笔记---11数组、指针、推箱子小游戏

------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”}

 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bright1st

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值