迷宫问题&MakeFile
先看一个有意思的问题, 我们定义一个二维数组表示迷宫。

它表示一个迷宫, 其中的1表示墙壁,0表示可以走的路, 只能横着走或竖着走,不能斜着走,
我们要编程序找出从左上角到右下角的路线。其实这个问题可以用深度优先搜索的方法搞定的了。
这个算法中涉及到了几个知识:
1. 一个是栈,每走过一个点会把这个点会把这个点压入栈中。
2. 用一个新的数据结构保存走迷宫的路线,每个走过的点都有一个前趋(Predecessor)的点,表示是从哪儿走到
当前点的,比如predecessor[4][4]是座标为(3, 4)的点,就表示从(3, 4)走到了(4, 4),一开始predecessor的各元素
初始化为无效座标(-1, -1)。在迷宫中探索路线的同时就把路线保存在predecessor数组中。
3. 已经走过的点在maze数组中记为2防止重复走。 算法的伪代码如下 :

分为几个文件来分开实现 :
/* main.c */
/***********************************************************/
/* Copyright (C) SA14226214, USTC, 2014-2015 */
/* */
/* FILE NAME : main.c */
/* PRINCIPAL AUTHOR : GaoZhipeng */
/* SUBSYSTEM NAME : MakFile */
/* MODULE NAME : makefile */
/* LANGUAGE : C */
/* TARGET ENVIRONMENT : ANY */
/* DATE OF FIRST RELEASE : 2015/04/05 */
/* DESCRIPTION : This is a makefile program */
/***********************************************************/ /*
*Revision log:
*
*Ceated by GaoZhipeng, 2015/04/05
*
*/ #include<stdio.h>
#include"main.h"
#include"stack.h"
#include"maze.h" struct point predecessor[MAX_ROW][MAX_COL] = {
{{-,-}, {-,-}, {-,-}, {-,-}, {-,-}},
{{-,-}, {-,-}, {-,-}, {-,-}, {-,-}},
{{-,-}, {-,-}, {-,-}, {-,-}, {-,-}},
{{-,-}, {-,-}, {-,-}, {-,-}, {-,-}},
{{-,-}, {-,-}, {-,-}, {-,-}, {-,-}},
}; void visit(int row, int col, struct point pre)
{
struct point visit_point = {row, col};
maze[row][col] = ;
predecessor[row][col] = pre;
push(visit_point);
} int main(void)
{
struct point p = { , };
maze[p.row][p.col] = ;
push(p);
while (!is_empty()) {
p = pop();
if (p.row == MAX_ROW - /* goal */
&& p.col == MAX_COL - )
break;
if (p.col+ < MAX_COL
/* right */
&& maze[p.row][p.col+] == )
visit(p.row, p.col+, p);
if (p.row+ < MAX_ROW
/* down */
&& maze[p.row+][p.col] == )
visit(p.row+, p.col, p);
if (p.col- >=
/* left */
&& maze[p.row][p.col-] == )
visit(p.row, p.col-, p);
if (p.row- >=
/* up */
&& maze[p.row-][p.col] == )
visit(p.row-, p.col, p);
print_maze();
}
if (p.row == MAX_ROW - && p.col == MAX_COL - ) {
printf("(%d, %d)\n", p.row, p.col);
while (predecessor[p.row][p.col].row != -) {
p = predecessor[p.row][p.col];
printf("(%d, %d)\n", p.row, p.col);
}
} else
printf("No path!\n");
return ;
}
/* main.h */
/***********************************************************/
/* Copyright (C) SA14226214, USTC, 2014-2015 */
/* */
/* FILE NAME : main.h */
/* PRINCIPAL AUTHOR : GaoZhipeng */
/* SUBSYSTEM NAME : MakFile */
/* MODULE NAME : makefile */
/* LANGUAGE : C */
/* TARGET ENVIRONMENT : ANY */
/* DATE OF FIRST RELEASE : 2015/04/05 */
/* DESCRIPTION : This is a makefile program */
/***********************************************************/ /*
*Revision log:
*
*Ceated by GaoZhipeng, 2015/04/05
*
*/ #ifndef MAIN_H
#define MAIN_H typedef struct point{
int row, col;
} item_t; #define MAX_ROW 5
#define MAX_COL 5 #endif
/* maze.c */
/***********************************************************/
/* Copyright (C) SA14226214, USTC, 2014-2015 */
/* */
/* FILE NAME : maze.c */
/* PRINCIPAL AUTHOR : GaoZhipeng */
/* SUBSYSTEM NAME : MakFile */
/* MODULE NAME : makefile */
/* LANGUAGE : C */
/* TARGET ENVIRONMENT : ANY */
/* DATE OF FIRST RELEASE : 2015/04/05 */
/* DESCRIPTION : This is a makefile program */
/***********************************************************/ /*
*Revision log:
*
*Ceated by GaoZhipeng, 2015/04/05
*
*/ #include<stdio.h>
#include"maze.h" int maze[MAX_ROW][MAX_COL] = {
, , , , ,
, , , , ,
, , , , ,
, , , , ,
, , , , ,
}; void print_maze(void)
{
int i, j;
for(i=; i<MAX_ROW; i++)
{
for(j=; j<MAX_COL; j++)
{
printf("%d ", maze[i][j]);
}
putchar('\n');
} printf("*********\n");
}
/* maze.h */
/***********************************************************/
/* Copyright (C) SA14226214, USTC, 2014-2015 */
/* */
/* FILE NAME : maze.h */
/* PRINCIPAL AUTHOR : GaoZhipeng */
/* SUBSYSTEM NAME : MakFile */
/* MODULE NAME : makefile */
/* LANGUAGE : C */
/* TARGET ENVIRONMENT : ANY */
/* DATE OF FIRST RELEASE : 2015/04/05 */
/* DESCRIPTION : This is a makefile program */
/***********************************************************/ /*
*Revision log:
*
*Ceated by GaoZhipeng, 2015/04/05
*
*/ #ifndef MAZE_H
#define MAZE_H #include"main.h" extern int maze[MAX_ROW][MAX_COL];
void print_maze(void); #endif
/* stack.c */
/***********************************************************/
/* Copyright (C) SA14226214, USTC, 2014-2015 */
/* */
/* FILE NAME : stack.c */
/* PRINCIPAL AUTHOR : GaoZhipeng */
/* SUBSYSTEM NAME : MakFile */
/* MODULE NAME : makefile */
/* LANGUAGE : C */
/* TARGET ENVIRONMENT : ANY */
/* DATE OF FIRST RELEASE : 2015/04/05 */
/* DESCRIPTION : This is a makefile program */
/***********************************************************/ /*
*Revision log:
*
*Ceated by GaoZhipeng, 2015/04/05
*
*/ #include"stack.h" static item_t stack[];
static int top = ; void push(item_t p)
{
stack[top++] = p;
} item_t pop(void)
{
return stack[--top];
} int is_empty(void)
{
return top == ;
}
/* stack.h */
/***********************************************************/
/* Copyright (C) SA14226214, USTC, 2014-2015 */
/* */
/* FILE NAME : stack.h */
/* PRINCIPAL AUTHOR : GaoZhipeng */
/* SUBSYSTEM NAME : MakFile */
/* MODULE NAME : makefile */
/* LANGUAGE : C */
/* TARGET ENVIRONMENT : ANY */
/* DATE OF FIRST RELEASE : 2015/04/05 */
/* DESCRIPTION : This is a makefile program */
/***********************************************************/ /*
*Revision log:
*
*Ceated by GaoZhipeng, 2015/04/05
*
*/ #ifndef STACK_H
#define STACK_H #include "main.h" extern void push(item_t);
extern item_t pop(void);
extern int is_empty(void); #endif
然后我们要做的就是在Linux下对上述程序进行编译和运行。
对于程序的编译命令, 最原始的编译指令可以这样写: $ gcc main.c stack.c maze.c -o main
不过还有一个更加简便的操作, 那就是写一个Makefile文件和源代码放在同一个目录下面。下面是一个写好的Makefile
# This is an simple makefile main : main.o stack.o maze.o
gcc main.o stack.o maze.o -o main main.o : main.c main.h stack.h maze.h
gcc -c main.c -o main.o stack.o : stack.c stack.h main.h
gcc -c stack.c -o stack.o maze.o : maze.c maze.h main.h
gcc -c maze.c -o maze.o clean :
@echo "cleanning the project"
-rm main *.o
@echo "cleanning completed" .PHONY : clean
make 命令会自动读取当前目录下的Makefile 文件, 完成相应的编译步骤。Makefile由一组规则(Rule)组成,每条规则的格式是:
例如 : main: main.o stack.o maze.o
gcc main.o stack.o maze.o -o main
main 是这条规则的目标(Target),main.o、stack.o 和maze.o是这条规则的条件(Prerequisite)。目标和条件之间的关系是:欲更新目标,
必须首先更新它的所有条件;所有条件中只要有一个条件被更新了,目标也必须随之被更新。所谓“更新”就是执行一遍规则中的命令列表,
命令列表中的每条命令必须以一个Tab开头,注意不能是空格,Makefile的格式不像C语言的缩进那么随意,对于Makefile中的每个以Tab
开头的命令,make 会创建一个Shell进程去执行它。
Makefile中有一些常用的特殊变量 :
- $@ ,表示规则中的目标。
- $< ,表示规则中的第一个条件。
- $?,表示规则中所有比目标新的条件,组成一个列表,以空格分隔。
- $^ ,表示规则中的所有条件,组成一个列表,以空格分隔。
那么我们可以把Makefile进一步化简, 写成如下的形式:
#this is a makefile all : main main : main.o stack.o maze.o
gcc $^ -o $@ main.o : main.h stack.h maze.h
stack.o : stack.h main.h
maze.o : maze.h main.h clean :
-rm main *.o .PHONY: clean
把命令 gcc main.o stack.o maze.o -o main 改写成 gcc $^ -o $@。
这样即使以后又往条件里添加了新的目标文件,编译命令也不需要修改,减少了出错的可能。
迷宫问题&MakeFile的更多相关文章
- 十天学Linux内核之第十天---总结篇(kconfig和Makefile & 讲不出再见)
原文:十天学Linux内核之第十天---总结篇(kconfig和Makefile & 讲不出再见) 非常开心能够和大家一起分享这些,让我受益匪浅,感激之情也溢于言表,,code monkey的 ...
- 24小时学通Linux内核总结篇(kconfig和Makefile & 讲不出再见)
非常开心能够和大家一起分享这些,让我受益匪浅,感激之情也溢于言表,,code monkey的话少,没办法煽情了,,,,,,,冬天的风,吹得伤怀,倒叙往事,褪成空白~学校的人越来越少了,就像那年我们小年 ...
- Linux内核(1) - Kernel地图:Kconfig与Makefile
Makefile不是Make Love 从前在学校,混了四年,没有学到任何东西,每天就是逃课,上网,玩游戏,睡觉.毕业的时候,人家跟我说Makefile我完全不知,但是一说Make Love我就来劲了 ...
- 《Linux内核修炼之道》精华分享与讨论(5)——Kernel地图:Kconfig与Makefile
转自:http://blog.csdn.net/fudan_abc/article/details/5340408 Makefile不是Make Love 从前在学校,混了四年,没有学到任何东西,每天 ...
- 说说Makefile那些事儿
说说Makefile那些事儿 |扬说|透过现象看本质 工作至今,一直对Makefile半知半解.突然某天幡然醒悟,觉得此举极为不妥,只得洗心革面从头学来,以前许多不明觉厉之处顿时茅塞顿开,想想好记性不 ...
- C语言动态走迷宫
曾经用C语言做过的动态走迷宫程序,先分享代码如下: 代码如下: //头文件 #include<stdio.h> #include<windows.h>//Sleep(500)函 ...
- 编写一个通用的Makefile文件
1.1在这之前,我们需要了解程序的编译过程 a.预处理:检查语法错误,展开宏,包含头文件等 b.编译:*.c-->*.S c.汇编:*.S-->*.o d.链接:.o +库文件=*.exe ...
- 编写简单的Makefile文件
makefile中的编写内容如下: www:hello.c x.h gcc hello.c -o hello clean: rm hello www:hello.c x.h 表示生成www这个文件需 ...
- 简单编写Makefile
相信很多朋友都有过这样的经历,看着开源项目中好几页的makefile文件,不知所云.在日常学习和工作中,也有意无意的去回避makefile,能改就不写,能用ide就用ide.其实makefile并没有 ...
随机推荐
- 单台服务器最大tcp连接
如果对服务器进行压力测试,常常出现这种情况 tcp连接数过多 netstat -an windows查看tcp连接数 那么怎么增加单台服务器的最大连接数呢? 最简单的办法,增加内 ...
- 使用命令行创建Android工程报错:"Target id is not valid. Use 'android.bat list targets' to get the target ids"
D:\adt\sdk>cd tools D:\adt\sdk\tools> D:\adt\sdk\tools>android list targets Available Andro ...
- Spring事务的5种隔离级别
概述:isolation设定事务的隔离级别,事务管理器根据它来控制另外一个事务可以看到本事务内的哪些数据. 定义的5个不同的事务隔离级别: DEFAULT:默认的隔离级别,使用数据库默认的事务隔离级别 ...
- Appium基础五:appium相关API
1.获取信息类: 1.1 获取当前界面的组件: driver.currentActivity(); //获取当前界面的activity,可用于断言是否跳转到预期的activity 1.2 获取当前页面 ...
- 零基础逆向工程18_PE结构02_联合体_节表_PE加载过程
联合体 特点 1.联合体的成员是共享内存空间的 2.联合体的内存空间大小是联合体成员中对内存空间大小要求最大的空间大小 3.联合体最多只有一个成员有效 节表数据结构说明 PE 加载 过程 FileBu ...
- WebView全面学习(一)--常用类和方法
WebView全面学习(一)--常用类和方法 WebView本质上是一个View,他基于webkit引擎来展示web页面 在Android不同的版本webkit内核有所区别,从Android版本上看, ...
- ORACLE中能否找到未提交事务的SQL语句
在Oracle数据库中,我们能否找到未提交事务(uncommit transactin)的SQL语句或其他相关信息呢? 关于这个问题,我们先来看看实验测试吧.实践出真知. 首先,我们在会话1(S ...
- LibreOJ #515. 「LibreOJ β Round #2」贪心只能过样例
题目描述 一共有 nnn个数,第 iii 个数 xix_ixi 可以取 [ai,bi][a_i , b_i][ai,bi] 中任意值.设 S=∑xi2S = \sum{{x_i}^2 ...
- 不写画面的网页程序设计,Web API、Web Service、WCF Service
客户有一个系统,经常要连上我方,查询数据 以前的作法是给对方一个账号,让他可以连上我们的DB来查询. 所以,早期的同仁,真的给他们DB链接字符串 客户的Windows程序.网站就真的靠这么危险的方式, ...
- Java 集合框架_下
Map接口 特点: [1]Map接口称为键值对集合或者映射集合,其中的元素(entry)是以键值对(key-value)的形式存在. [2]Map 容器接口中提供了增.删.改.查的方式对集合进行操作. ...