------- android培训、java培训、IOS培训、期待与您交流! ----------
1. 指针运算(指针部分最难掌握的地方)(五颗星)
int main()
{
// 指针的运算是指针难点的起源
// 指针的运算分为:
// 1>类型运算(强转)
// 将一个指针类型的变量强制类型转换为另外一个类型
// void *
// C89标准中才提出来的,是为了定义一个规范的指针类型
// 函数 malloc 就是一个void*函数,申请出来的地址让调用者自己强转
// 2>加减运算(没有乘除)
// 指针变量做加减只能加减一个固定的数字(1,2,3...)
// int *p; p+1; p++; //向后移动4个字节
// 指针变量加上一个数字,是指指针变量移动多少个"单位"的字节
// 3>关系运算
//指针向前表示向低地址方向
//1.p+1的含义是指向后移动一个单位的地址,如果p为int*指针,p=&num=0xff0a467 那么p+1=0xff0a46b
//访问了后面的4个字节
//向前移动和向后移动的概念?
//2.p++指向了后面的4个字节,同时修改了p的地址
int temp = 101;
int num = 10;//temp的地址比num高,从高地址往低地址存,大端储存(intel处理器,IBM的处理器才是从低到高的小端储存)
//具体数字存储,则是低位存低位,高位存高位
//1.在函数中定义的变量,如果没有static修饰,那么在内存分配中就是由高地址向低地址存放
int *p;
p = #
// printf("%d\n",*(p++));
// printf("%d\n",*p);
//3.*p+1
//(*p)+1
//将p中的值取出来,然后加一
//4.*(p)+1
//5.*(p+1)
//访问4个字节后的地址,并以int类型的形式读取
//6.*p++
//(重要)
//结合顺序等价于*(p++)
//访问当前指针指向的地址的数据
//同时让指针指向一个单位位置(4个字节之后)
//7.*(p++)
//8.(*p)++
//相当于将p指向的变量做++
//将里面的值自增1
//++*++p 相当于++(*(++p));
printf("%d\n",++*++p);
printf("%d\n",temp);
//*p和直接使用num的意义是完全一样的
return 0;
}
2. 指针作为函数参数
// 指针变量作为函数参数,就是将指针变量传给调用的函数
// 1.函数怎么定义(C语言是形式化的语言) 更改形参
// 返回类型函数名(指针指向类型 *指针变量名){
// 函数体
// }
// 2.把指针传过去有何用与传数值有何区别
// 在将变量作为函数参数的时候,函数外变量的值与函数内变量值一样,但是没有关系,无法修改操作
// 用指针变量的时候,可以修改指向的参数值
// 指针运算中有一个非常重要的运算,叫做取值运算(*)
int main()
{
int num =10;
int *p = #
int **m = &p;
//一个&就是一把锁,一个*就是一把钥匙
printf("%d\n",**m);
return 0;
}
3. 字符串指针
// 字符串的表示
// 1>char str[] ="12345";
// 2>char *str ="12345";
// 程序编译以后变成什么样子(数据的储存结构,了解)
// 程序的编译流程
// 源代码--> 编译器 -->目标文件(二进制)(.o文件,缺乏主函数,无法运行)-->连接器 --> 可执行文件(二进制)(a.out文件)
// 可执行文件也有具体的格式
// 程序运行开始的时候,加载的方式
// 在Mac下格式为Mach-O,windows使用的是PE格式,Linux使用的是EFL格式
// 维基百科准备吹牛逼资本的地方
// 对于应用程序
// 应用程序部分分别是格式文件,数据段(常量等)和代码段
// IDA软件静态反编译反编译成汇编语言(普通版) 可以直接反编译成OC(Pro版本)(7万左右)
// windows版本下有破解版,可以找昆昆要
// 栈是函数,堆是自己申请的内存
// 字符串指针的字符串()
// char *str ="1234";
// *str = 'A';
// 上面这两句话,在Mac下得到的是总线错误,在Linux下报段错误,windows下直接闪退
// 什么是栈区,函数的内存 什么是堆区,手动申请的内存
// 11-字符串指针与数组的使用
// char str[10] 那么在函数中,会分配指定长度的数据内存空间;
// char str[] = "字符串...",这样定义的数据都是储存在函数中(栈区), 这些数据可以随意修改
// 这个数组中储存的字符串可以随意修改,而数组名是一个常量,不允许修改
// 字符串指针就是一个char指针,利用就是数组储存连续和指针的+-运算的特点
// char *str ="12345";
// str 是一个指针类型的便利,里面储存的地址是可以改变的
// str 指向常量"12345"
//printf("%c\n","abc"); 打印的结果是a,此时的字符串是一个常量,储存在"数据段"(常量被编译到文件里去了)
//字符串指针是可以指向其他对象的, str = "abc",这是合法的
4. 指针部分应用,推箱子游戏(好玩的东西)
//程序设计伪代码思路
//int test()
//{
// while (1) {
// 打印地图()
// 判断赢了没有
//
// 提示用户输入wsad
// // w i -1
// // s i +1
// // a j -1
// // d j +1
// switch(input){
// case 'W':
// case 'w':
// 推箱子;
// if(下一步是不是 ''){
// 可以走;
// } else if(下一步是不是'#'){
// 走不动;
// } else if(下一步是不是'X'){
// if (箱子的下一步'#'){
// 推不动,没反应;
// } else if (' '){
// 先移动箱子;(交换)
// 再移动人;(交换)
// }
// }
// break;
// case 'S';
// ....
// }
//
// }
//
// return 0;
//}
//具体实现
#define kRows 11
#define kCols 11
void printMap(char arr[kRows][kCols],int rows,int cols);
int isSuccess(int i,int j);
void change(char arr[kRows][kCols],int curri,int currj,int nexti,int nextj);
char map[kRows][kCols] = {
"##########",
"#0 ###",
"# X ###",
"# ###",
"## ##",
"# ##",
"# ##",
"# ##",
"# ",
"##########",
};
int main()
{
char ch;
int personi = 1;
int personj = 1;
int boxi = 2;
int boxj = 2;
while(1){
system("clear");
printMap(map,kRows,kCols);
if(isSuccess(boxi, boxj))
{
printf("success!\n");
break;
}
printf("input:w s ad\n");
scanf("%c",&ch);
//中和掉多余的字符
while(getchar() !='\n');
switch (ch){
case 'W':case 'w':
//up
//1.是不是路
if (map[personi - 1][personj] == ' '){
//lu
change(map, personi, personj, personi-1, personj);
personi--;
} else if (map[personi - 1][personj] == '#'){
//qiang
} else if (map[personi - 1][personj] == 'X'){
//box
if (map[boxi -1][boxj] == ' ') {
change(map, boxi, boxj, boxi -1, boxj);
change(map, personi, personj, personi-1, personj);
boxi--;
personi--;
}
}
break;
case 'S':case 's':
//
if (map[personi + 1][personj] == ' '){
//lu
change(map, personi, personj, personi+1, personj);
personi++;
} else if (map[personi + 1][personj] == '#'){
//qiang
} else if (map[personi + 1][personj] == 'X'){
//box
if (map[boxi +1][boxj] == ' ') {
change(map, boxi, boxj, boxi +1, boxj);
change(map, personi, personj, personi+1, personj);
personi ++;
boxi++;
}
}
break;
case 'A':case 'a':
//
if (map[personi][personj -1] == ' '){
//lu
change(map, personi, personj, personi,personj -1);
personj--;
} else if (map[personi][personj -1] == '#'){
//qiang
} else if (map[personi][personj -1] == 'X'){
//box
if (map[boxi][boxj -1] == ' ') {
change(map, boxi, boxj, boxi, boxj -1);
change(map, personi, personj, personi,personj -1);
personj--;
boxj--;
}
}
break;
case 'D':case 'd':
//
if (map[personi][personj +1] == ' '){
//lu
change(map, personi, personj, personi,personj +1);
personj++;
} else if (map[personi][personj +1] == '#'){
//qiang
} else if (map[personi][personj +1] == 'X'){
//box
if (map[boxi][boxj +1] == ' ') {
change(map, boxi, boxj, boxi, boxj +1);
change(map, personi, personj, personi,personj +1);
personj++;
boxj++;
}
}
break;
}
}
return 0;
}
// 判断是否胜利
int isSuccess(int i,int j){
return i == 0 || i == kRows - 1 || j == 0 || j == kCols -2;
}
//写一个函数,交换两个位置
void change(char arr[kRows][kCols],int curri,int currj,int nexti,int nextj){
//即交换arr[curri][currj]与arr[nexti][nextj]
char temp = arr[curri][currj];
arr[curri][currj] = arr[nexti][nextj];
arr[nexti][nextj] = temp;
}
void printMap(char arr[kRows][kCols],int rows,int cols){
for (int i =0; i<kRows; i++) {
printf("%s\n",arr[i]);
}
}