这里使用走迷宫深度优先搜索,把它写成一个项目。
项目的目录树如下:
目录树:
├── include
│ ├── main_tmp.h
│ ├── maze.h
│ └── stack.h
├── lib
│ ├── maze.c
│ └── stack.c
└── src
└── main.c
内容:
//main_tmp.h
#ifndef MAIN_TMP_H
#define MAIN_TMP_H
typedef struct point { int row, col; } item_t;
#define MAX_ROW 5
#define MAX_COL 5
#endif
//maze.h
#ifndef MAZE_H
#define MAZE_H
#include "main_tmp.h"
extern int maze[MAX_ROW][MAX_COL];
void print_maze(void);
#endif
//stack.h
#ifndef STACK_H
#define STACK_H
#include "main_tmp.h" /* provides definition for item_t */
extern void push(item_t);
extern item_t pop(void);
extern int is_empty(void);
#endif
//maze.h
#include <stdio.h>
#include "maze.h"
int maze[MAX_ROW][MAX_COL] = {
0,1,0,0,0,
0,1,0,1,0,
0,0,0,0,0,
0,1,1,1,0,
0,0,0,1,0
};
void print_maze(void){
int i, j;
for (i = 0; i < MAX_ROW; i++) {
for (j = 0; j < MAX_COL; j++)
printf("%d ", maze[i][j]);
putchar('\n');
}
printf("*********\n");
}
//maze.c
#include "stack.h"
static item_t stack[512];
static int top = 0;
void push(item_t p){
stack[top++] = p;
}
item_t pop(void){
return stack[--top];
}
int is_empty(void){
return top == 0;
}
//stack.c
#include "stack.h"
static item_t stack[512];
static int top = 0;
void push(item_t p){
stack[top++] = p;
}
item_t pop(void){
return stack[--top];
}
int is_empty(void){
return top == 0;
}
// main.c
#include <stdio.h>
#include "main_tmp.h"
#include "stack.h"
#include "maze.h"
struct point predecessor[MAX_ROW][MAX_COL] = {
{{-1,-1}, {-1,-1}, {-1,-1}, {-1,-1}, {-1,-1}},
{{-1,-1}, {-1,-1}, {-1,-1}, {-1,-1}, {-1,-1}},
{{-1,-1}, {-1,-1}, {-1,-1}, {-1,-1}, {-1,-1}},
{{-1,-1}, {-1,-1}, {-1,-1}, {-1,-1}, {-1,-1}},
{{-1,-1}, {-1,-1}, {-1,-1}, {-1,-1}, {-1,-1}},
};
void visit(int row, int col, struct point pre){
struct point visit_point = { row, col };
maze[row][col] = 2;
predecessor[row][col] = pre;
push(visit_point);
}
int main(void){
struct point p = { 0, 0 };
maze[p.row][p.col] = 2;
push(p);
while (!is_empty()) {
p = pop();
if (p.row == MAX_ROW - 1 && p.col == MAX_COL - 1)
break;
if (p.col+1 < MAX_COL && maze[p.row][p.col+1] == 0)
visit(p.row, p.col+1, p);
if (p.row+1 < MAX_ROW && maze[p.row+1][p.col] == 0)
visit(p.row+1, p.col, p);
if (p.col-1 >= 0 && maze[p.row][p.col-1] == 0)
visit(p.row, p.col-1, p);
if (p.row-1 >= 0 && maze[p.row-1][p.col] == 0)
visit(p.row-1, p.col, p);
print_maze();
}
if (p.row == MAX_ROW - 1 && p.col == MAX_COL - 1) {
printf("(%d, %d)\n", p.row, p.col);
while (predecessor[p.row][p.col].row != -1) {
p = predecessor[p.row][p.col];
printf("(%d, %d)\n", p.row, p.col);
}
}
else
printf("No path!\n");return 0;
}
目录树
├── include
│ ├── main_tmp.h
│ ├── maze.h
│ └── stack.h
├── lib
│ ├── Makefile.am
│ ├── maze.c
│ └── stack.c
├── Makefile.am
└── src
├── main.c
└── Makefile.am
写 Makefile.am
在顶级目录
和lib
、src
下添加Makefile.am
文件
# Makefile.am
SUBDIRS = lib src
include_HEADERS = include/main_tmp.h include/maze.h include/stack.h
# lib/Makefile.am
lib_LIBRARIES = libaname.a
libaname_a_SOURCES = maze.c stack.c
libaname_a_CPPFLAGS = -I../include
AM_V_AR = ar
RANLIB = ranlib
# src/Makefile.am
bin_PROGRAMS = main
main_SOURCES = main.c main_tmp.h maze.h stack.h maze.c stack.c
main_CPPFLAGS = -I$(srcdir)/../include
main_LDADD = $(srcdir)/../lib/libaname.a
main_LDFLAGS = -L$(srcdir)/../lib -laname
顶级目录下:
autoscan
生成autoscan.log
和configure.scan
两个文件
├── autoscan.log
├── configure.scan
├── include
│ ├── main_tmp.h
│ ├── maze.h
│ └── stack.h
├── lib
│ ├── Makefile.am
│ ├── maze.c
│ └── stack.c
├── Makefile.am
└── src
├── main.c
└── Makefile.am
configure.scan
内容如下:
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.69])
AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
AC_CONFIG_SRCDIR([lib/maze.c])
AC_CONFIG_HEADERS([config.h])
# Checks for programs.
AC_PROG_CC
# Checks for libraries.
# FIXME: Replace `main' with a function in `-laname':
AC_CHECK_LIB([aname], [main])
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_CONFIG_FILES([Makefile
lib/Makefile
src/Makefile])
AC_OUTPUT
修改并且重命名成configure.ac
,内容如下:
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.69])
AC_INIT([main], [1.0], [1228685814@qq.com])
AM_INIT_AUTOMAKE([foreign -Wall -Werror])
AC_CONFIG_SRCDIR([src/main.c])
AC_CONFIG_HEADERS([config.h])
# Checks for programs.
AC_PROG_CC
# Checks for libraries.
# FIXME: Replace `main' with a function in `-laname':
AC_CHECK_LIB([aname], [maze])
AC_CHECK_LIB([aname], [stack])
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_CONFIG_FILES([Makefile
lib/Makefile
src/Makefile])
AC_OUTPUT
AM_PROG_AR
AC_PROG_RANLIB
目前为止:
├── autoscan.log
├── configure.ac
├── include
│ ├── main_tmp.h
│ ├── maze.h
│ └── stack.h
├── lib
│ ├── Makefile.am
│ ├── maze.c
│ └── stack.c
├── Makefile.am
└── src
├── main.c
└── Makefile.am
autoreconf
相当于依次使用aclocal、autoconf、autoheader、automake --add-missing
autoreconf --install
输出:
configure.ac:28: installing './ar-lib'
configure.ac:10: installing './compile'
configure.ac:5: installing './install-sh'
configure.ac:5: installing './missing'
lib/Makefile.am: installing './depcomp'
变成:
├── aclocal.m4
├── ar-lib
├── autom4te.cache
│ ├── output.0
│ ├── output.1
│ ├── requests
│ ├── traces.0
│ └── traces.1
├── autoscan.log
├── compile
├── config.h.in
├── configure
├── configure.ac
├── depcomp
├── include
│ ├── main_tmp.h
│ ├── maze.h
│ └── stack.h
├── install-sh
├── lib
│ ├── Makefile.am
│ ├── Makefile.in
│ ├── maze.c
│ └── stack.c
├── Makefile.am
├── Makefile.in
├── missing
└── src
├── main.c
├── Makefile.am
└── Makefile.in
执行 configure 生成 Makefile
./configure
输出:
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking whether gcc understands -c and -o together... yes
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
checking for maze in -laname... no
checking for stack in -laname... no
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating lib/Makefile
config.status: creating src/Makefile
config.status: creating config.h
config.status: executing depfiles commands
checking for ar... ar
checking the archiver (ar) interface... ar
checking for ranlib... ranlib
目前为止:
├── aclocal.m4
├── ar-lib
├── autom4te.cache
│ ├── output.0
│ ├── output.1
│ ├── requests
│ ├── traces.0
│ └── traces.1
├── autoscan.log
├── compile
├── config.h
├── config.h.in
├── config.h.in~
├── config.log
├── config.status
├── configure
├── configure.ac
├── depcomp
├── include
│ ├── main_tmp.h
│ ├── maze.h
│ └── stack.h
├── install-sh
├── lib
│ ├── Makefile
│ ├── Makefile.am
│ ├── Makefile.in
│ ├── maze.c
│ └── stack.c
├── Makefile
├── Makefile.am
├── Makefile.in
├── missing
├── src
│ ├── main.c
│ ├── Makefile
│ ├── Makefile.am
│ └── Makefile.in
└── stamp-h1
编译:
make
执行:
./src/main
安装
make install
这样 /usr/local/include
就有项目的头文件, /usr/local/bin
就有main可执行文件。
任何目录下,直接
main
即可执行。