K08 Δομές Δεδομένων και Τεχνικές Προγραμματισμού
Κώστας Χατζηκοκολάκης
.c
file is not practical
module.h
stdio.h
, string.h
, …stats.h
module with two functions// stats.h - Απλά στατιστικά στοιχεία για πίνακες
#include <limits.h> // INT_MIN, INT_MAX
// Επιστρέφει το μικρότερο στοιχείο του array (ΙΝΤ_ΜΑΧ αν size == 0)
int stats_find_min(int array[], int size);
// Επιστρέφει το μεγαλύτερο στοιχείο του array (ΙΝΤ_MIN αν size == 0)
int stats_find_max(int array[], int size);
stats_
is a good practice (why?)#include "module.h"
// minmax.c - Το βασικό αρχείο του προγράμματος
#include <stdio.h>
#include "stats.h"
int main() {
int array[] = { 4, 35, -2, 1 };
printf("min: %d\n", stats_find_min(array, 4));
printf("max: %d\n", stats_find_max(array, 4));
}
module.c
module.c
contains the definitions of all functions declared in module.h
// stats.c - Υλοποίηση του stats module
#include "stats.h"
int stats_find_min(int array[], int size) {
int min = INT_MAX; // "default" τιμή, μεγαλύτερη από όλες
for(int i = 0; i < size; i++)
if(array[i] < min)
min = array[i]; // βρέθηκε νέο ελάχιστο
return min;
}
minmax.c
together with module.c
worksgcc minmax.c stats.c -o minmax
.c
files?.c
file separately to create an .o
file.o
files together to create the executablegcc -c minmax.c -o minmax.o
gcc -c stats.c -o stats.o
gcc minmax.o stats.o -o minmax
minmax.c
, we only need to recompile that file and relink
Makefile
s make this very easymodule.h
can be implemented in different ways// stats_alt.c - Εναλλακτική υλοποίηση του stats module
#include "stats.h"
// Επιστρέφει 1 αν value <= array[i] για κάθε i
int smaller_than_all(int value, int array[], int size) {
for(int i = 0; i < size; i++)
if(value > array[i])
return 0;
return 1;
}
int stats_find_min(int array[], int size) {
for(int i = 0; i < size; i++)
if(smaller_than_all(array[i], array, size))
return array[i];
return INT_MAX; // εδώ φτάνουμε μόνο σε περίπτωση κενού array
}
minmax.c
is compiled without knowing how stats.h
is implemented
gcc -c minmax.c -o minmax.o
# use the first implementation
gcc -c stats.c -o stats.o
gcc minmax.o stats.o -o minmax
# OR the second
gcc -c stats_alt.c -o stats_alt.o
gcc minmax.o stats_alt.o -o minmax
stats.h
would you choose?gcc ...
commands 100 timesMakefile
# Ένα απλό Makefile (με αρκετά προβλήματα)
# Προσοχή στα tabs!
minmax:
gcc -c minmax.c -o minmax.o
gcc -c stats.c -o stats.o
gcc minmax.o stats.o -o minmax
minmax
run these commandsmake minmax
make
to compile the first target in the Makefile
minmax.c
, but make refuses to rebuild minmax
$ make minmax
make: 'minmax' is up to date.
minmax: minmax.c stats.c
gcc -c minmax.c -o minmax.o
gcc -c stats.c -o stats.o
gcc minmax.o stats.o -o minmax
minmax
depends on minmax.c
, stats.c
minmax
itself, the commands are run again!minmax.c
, but make
recompiles everythingminmax.o: minmax.c
gcc -c minmax.c -o minmax.o
stats.o: stats.c
gcc -c stats.c -o stats.o
minmax: minmax.o stats.o
gcc minmax.o stats.o -o minmax
minmax
we need to build minmax.o
, stats.o
minmax.o
depends on minmax.c
which is newer, so make
recompilesstats.o
depends on stats.c
which is older, so no need to recompilemake
knows how to make foo.o
if a file foo.c
exists, by running
gcc -c foo.c -o foo.o
.o
files!minmax: minmax.o stats.o
gcc minmax.o stats.o -o minmax
Makefile
VAR = ...
$(VAR)
anywhere in the Makefile
Makefile
# Αρχεία .o (αλλάζουμε απλά σε stats_alt.o για τη δεύτερη υλοποίηση!)
OBJS = minmax.o stats.o
# Το εκτελέσιμο πρόγραμμα
EXEC = minmax
$(EXEC): $(OBJS)
gcc $(OBJS) -o $(EXEC)
.o
file using an implicit ruleCFLAGS = -Wall -Werror -g
make clean
to delete all files the compiler builtclean:
rm -f $(OBJS) $(EXEC)
make run
to compile and execute the program with predefined argumentsARGS = arg1 arg2 arg3
run: $(EXEC)
./$(EXEC) $(ARGS)
Directory | Content |
---|---|
include |
shared modules, used by multiple programs |
modules |
module implementations |
programs |
executable programs |
tests |
unit tests (we'll talk about these later) |
lib |
libraries (we'll talk about these later) |
# paths
MODULES = ../../modules
INCLUDE = ../../include
# Compile options. Το -I<dir> χρειάζεται για να βρει ο gcc τα αρχεία .h
CFLAGS = -Wall -Werror -g -I$(INCLUDE)
# Αρχεία .o, εκτελέσιμο πρόγραμμα και παράμετροι
OBJS = minmax.o $(MODULES)/stats.o
EXEC = minmax
ARGS =
$(EXEC): $(OBJS)
gcc $(OBJS) -o $(EXEC)
clean:
rm -f $(OBJS) $(EXEC)
run: $(EXEC)
./$(EXEC) $(ARGS)
Old-school editors: vim, emacs, …
IDEs: Visual Studio, Eclipse, NetBeans, CLion, …
Modern code-editors: VS Code, Sublime Text, Atom, …
.vscode
dir provided in the lecture code
.vscode/settings.json
{
"c_project": {
// Directory στο οποίο βρίσκεται το πρόγραμμα
"dir": "programs/minmax",
// Όνομα του εκτελέσιμου προγράμματος
"program": "minmax",
// Ορίσματα του προγράμματος.
"arg1": "-4",
"arg2": "35",
...
},
}
Terminal / Run Task
Make: compile
executes
make <program>
Errors are nicely displayed
Make: compile and run
executes
make <program>
./<program> <arg1> <arg2> ...
Ctrl-Shift-B
executes the default taskF9
)F5
to start debuggingCtrl-P
: quickly open fileCtrl-Shift-O
: find functionCtrl-/
: toggle commentCtrl-Shift-F
: search/replace in all filesCtrl-`
: move between code and terminalF8
: go to next compilation errorAlt-up
, Alt-down
: move line(s)github.com
, a popular Git hosting siteclone
a repository, creating a local copycommit
changes to the local repositorypush
the changes to the remote repositoryFor multiple developers/machines:
pull
changes from a different local repository copygit config --global user.email "you@example.com"
git config --global user.name "Your Name"
github.com
test-repo
on github.com
https://github.com/<username>/test-repo
git clone https://github.com/<username>/test-repo
test-repo
containing a local repository copyREADME.md
is presentgit status
inside test-repo
Modify README.md
Run git status
README.md
appears as modifiedTo commit the changes:
git commit -a -m "Change README"
-a
: commit all modified files
-m "..."
: assign a message to the commit
foo.c
git status
foo.c
appears as untrackedgit add foo.c
git commit -m "Add foo.c"
git status
again
Your branch is ahead of 'origin/master' by 2 commits.
https://github.com/<username>/test-repo
git push
git pull
.gitignore
special file are ignored by Git (blacklist).gitignore
(whitelist)# Αγνοούμε όλα τα αρχεία (όχι τα directories)
*
!*/
# Εκτός από τα παρακάτω
!*.c
!*.h
!*.mk
!Makefile
!.gitignore
!README.md
!.vscode/*.json
make
manual, Chapter 2