黑马程序员—-C语言入门十重奏之八相念

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

当xcode不提示输入的关键字时,按esc

二维数组
可以看做是一个特殊的一维数组,这个一维数组的每个元素又是一个一维数组
数据类型 数组名[第一维的长度(行)][第二维的长度(列)]
理解方法:
1.  特殊的一维数组,一维数组有两个元素[行数][列数]
2.  定义了[行数][列数]的一个矩阵
#include <stdio.h>
#define x = 6//宏定义后不能加;
int main(int argc, const char * argv[]) {
    int a[2][3];
    /*!
     * 数组名不能和变量名同名
     数组的长度可以是常量表达式
     */
    int b[2][1+3];
    int m = 3,n = 4;
    int c[m][n];//Xcode特有的写法,其他编译器可能不支持
    int arr[m];//可以使用宏定义
    return 0;
}
二维数组初始化
//完全初始化和部分初始化


#include <stdio.h>

int main(int argc, const char * argv[]) {
    int arr[2][3] = {{0,1,2},{3,4,5}};//2行3列,分段初始化:几行就分几个一维数组
    //0 1 2
    //3 4 5
    int arr1[2][3] = {0,1,2,3,4,5};//计算机以3列的倍数进行截断
    int arr2[][3] = {{0,1,2},{3,4,5}};//可以省略第一维
    int arr3[][3] = {1,2,3,4,5,6};//计算机以3列的倍数进行截断
    //部分初始化
    int a[3][4] = {1};//后面11个全是0,一般情况下给数组初始化为全0
    int a1[3][4] = {{1},{2},{3}};//没写的全是0,这种写法第一维可以省略a1[][4]
    int a2[3][4] = {1,2,3,4};//第一行是1,2,3,4剩下全是0,这种写法第一维可以省略a2[][4]
    //二维数组中第一维可以省略,第二维不能省
    int a3[3][4];
    a3[0][0] = 1;
    a3[0][1] = 2;
    return 0;
}
二维数组遍历
二维数组的元素也称为双下标变量
#include <stdio.h>

int main(int argc, const char * argv[]) {
    int arr[4][3] = {1,2,3,4,5,6,2,3,4,4,3,2};
    printf("arr[4][3] = {");
    for (int i = 0; i < 4; i++) {//一维下标代表行数
        printf("{");
        for (int j = 0; j < 3; j++) {//二维下标代表列数,里层循环
            if (j == 2) {
                printf("%d",arr[i][j]);
            }else
            printf("%d,",arr[i][j]);
        }
        if (i == 3) {
            printf("}");
        }else
        printf("},");

    }
    printf("}");
    return 0;
}
二维数组存储
int m=3;
int a[m];
其他编译器里不允许,在其他编译器里只是给m先分了个4字节的内存空间,m的值再运行的时候才会查看到,所以编译不过去
xcode底层做了优化可以

存储方式:
1.  计算机给二维数组分配一块连续的存储空间
2.  数组名代表数组的首地址
3.  每一行存储方式从首地址还是一次存储
4.  每个元素占用相同的字节数
5.  并且数组中元素之间的地址是连续的
int a[2][2] = {1,2,3,4};
内存地址    内存单元        
0x01    00000001    a[0][0]=1   a[0]
0x02    00000000        
0x03    00000000        
0x04    00000000        
0x05    00000010    a[0][1]=2   
0x06    00000000        
0x07    00000000        
0x08    00000000        
0x09    00000011    a[1][0]=3   a[1]
0x0a    00000000        
0x0b    00000000        
0x0c    00000000        
0x0d    00000100    a[1][1]=4   
0x0e    00000000        
0x0f    00000000        
0x10    00000000        
数组的首地址=第一行的地址=数组名=0x01=&a[0][0]
第二行的首地址=第二行第一个元素的地址=0x09=&a[1][0]
行间相差地址=列数*字节数

二维数组作为函数参数
1.  二维数组元素作为函数参数
score[1][2]此为变量,同变量作为函数参数,值传递
如:sum(score[1][0],score[2][3])都是变量作为函数参数
2.  二维数组名作为函数参数
score作为函数参数,同一维数组名作为函数参数,地址传递
print_arr(score)此时score是一个常量,保存的是数组的首地址
在函数里还是不能计算sizeof(score)的总长度,仍旧是计算的是8
#include <stdio.h>
void print_arr(int score[5][3]){
    int len = sizeof(score);//仍旧和一维数组一样是8
    printf("%d",len);
}

int main(int argc, const char * argv[]) {
    int arr[5][3] = {{80,75,92},{61,65,71},{59,63,70},{85,87,90},{76,77,85}};
    print_arr(arr);
    return 0;
}

思考题:
从键盘上接收两个参数分别存放到m,n中,使用m和n构成数组:
1. 定义一个函数使用i*j初始化a[i][j]
2. 定义一个函数打印二维数组的每一个值

迷宫
伪代码的实现:

######
#  ##
##   #
# #  #
# # ##
######
 1. 定义变量
 2. 初始化地图
 3. 提示游戏玩法
 4. 获取用户输入的方向数据
 ---要进行循环控制
 5. 判断小人输入的方向
 6. 判断小人是否能走
    1.  如果是空,和小人位置互换,重新记录小人当前位置
    2.  如果是墙小人不动
 7.  如果y==5提示胜利
#include <stdio.h>
#define col 6//定义列
#define row 6//定义行
/*!
 * @brief  打印地图
 * @param map 地图的数组名
 */
void printMap(int map[row][col]){
    for (int i = 0; i < row; i++) {
        for (int j = 0; j < col; j++) {
            printf("%c",map[i][j]);
        }
        printf("\n");
    }
}

/*!
 * @brief  实现了小人的移动
 *
 * @param map  地图数组
 * @param oldX 小人位置原来X坐标
 * @param oldY 小人位置原来Y坐标
 * @param newX 小人将要走到的X坐标
 * @param newY 小人将要走到的Y坐标
 *
 */
void walk(int map[row][col],int oldX,int oldY,int newX,int newY){
    char temp;
    temp = map[oldX][oldY];
    map[oldX][oldY] = map[newX][newY];
    map[newX][newY] = temp;
}

int main(int argc, const char * argv[]) {
    //    1.    定义变量
    int map[row][col] = {
        {'#','#','#','#','#','#'},
        {'#','O','#','#',' ',' '},
        {'#',' ','#','#',' ','#'},
        {'#',' ',' ','#',' ','#'},
        {'#','#',' ',' ',' ','#'},
        {'#','#','#','#','#','#'},
    };
    char direction;//保存用户输入方向
    int currentX = 1;
    int currentY = 1;
    char street = ' ';
    //    2.    初始化地图

    printMap(map);

    //    3.    提示游戏玩法
    printf("请控制小人移动:w、W上;s、S下;a、A左;d、D右;q退出\n");
    //    4.    获取用户输入的方向数据
    //    ---要进行循环控制
    while (1) {
        scanf("%c",&direction);
        getchar();//从缓冲区获取一个字符
        //    5. 判断小人输入的方向
        switch (direction) {
            case 'w':
            case 'W':
                //    6.    判断小人是否能走
                //    1.    如果是空,和小人位置互换,
                if (map[currentX-1][currentY] == street) {
                    walk(map,currentX,currentY,currentX-1,currentY);
                    //重新记录小人当前位置
                    //如果能够移动,小人值一定变
                    currentX--;
                }//    2.  如果是墙小人不动
                break;
            case 's':
            case 'S':
                //    6.    判断小人是否能走
                //    1.    如果是空,和小人位置互换,
                if (map[currentX+1][currentY] == street) {
                    walk(map,currentX,currentY,currentX+1,currentY);

                    //重新记录小人当前位置
                    //如果能够移动,小人值一定变
                    currentX++;
                }//    2.  如果是墙小人不动
                break;
            case 'a':
            case 'A':
                //    6.    判断小人是否能走
                //    1.    如果是空,和小人位置互换,
                if (map[currentX][currentY-1] == street) {
                    walk(map,currentX,currentY,currentX,currentY-1);

                    //重新记录小人当前位置
                    //如果能够移动,小人值一定变
                    currentY--;
                }//    2.  如果是墙小人不动
                break;
            case 'd':
            case 'D':
                //    6.    判断小人是否能走
                //    1.    如果是空,和小人位置互换,
                if (map[currentX][currentY+1] == street) {
                    walk(map,currentX,currentY,currentX,currentY+1);

                    //重新记录小人当前位置
                    //如果能够移动,小人值一定变
                    currentY++;
                }//    2.  如果是墙小人不动
                break;
            case 'q':
            case 'Q':
                return 0;
                break;

            default:
                break;
        }

        //重绘地图
        printMap(map);

        //    7.  如果y==5提示胜利
        if(currentY == 5){
            printf("WoW!You Win!\n");
            break;
        }
    }   
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值