Programowanie w systemie UNIX/preprocesor
Wygląd
opcje kompilatora
[edytuj]Opcja -E - powoduje wygenerowanie kodu programu ze zmianami, wprowadzonymi przez preprocesor, np.:
gcc m.c -E -o t.c
Efektem jest: [1]
- rozwinięcie dyrektyw #define
- rozwiązanie dyrektyw #include
- włączenie deklaracji wszystkich funkcji do kodu źródłowego
- usunięcie komentarzy
Można również użyć bezpośrednio prepocesora cpp: [2]
cpp m.c > add.i
gcc -S t.c
powoduje zapisanie pliku t.s zawierającego efekt działania preprocesora
Jak z pliku wygenerowanego przez preprocesor odtworzyć plik z kodem w C?
[edytuj]- przechodzimy do końca pliku
- odnajdujemy kod w c
- idziemy do góry (początku pliku)
- usuwamy linie ze znakiem # na początku, oprócz poleceń OpenMP (pragma)
- kiedy dochodzimy do linii z "dziwnym" kodem, np.:
}
# 163 "g:\\progra~1\\dev-c++\\mingw64\\x86_64-w64-mingw32\\include\\malloc.h" 3
static __inline void __attribute__((__cdecl__)) _freea(void *_Memory) {
unsigned int _Marker;
if(_Memory) {
_Memory = (char*)_Memory - 16;
_Marker = *(unsigned int *)_Memory;
if(_Marker==0xDDDD) {
free(_Memory);
}
}
}
# 209 "g:\\progra~1\\dev-c++\\mingw64\\x86_64-w64-mingw32\\include\\malloc.h" 3
#pragma pack(pop)
# 669 "g:\\progra~1\\dev-c++\\mingw64\\x86_64-w64-mingw32\\include\\stdlib.h" 2 3
# 3 "test.c" 2
to usuwamy wszystkie linii aż do początku pliku
- dodajemy wymagane biblioteki (include)
Jest to przydatne gdy programista używa preprocesora do tworzenia różnych wersji procedur. Przykładowo z kodu:[3]
FTYPE FNAME(cabs2)(complex FTYPE z) {
return FNAME(creal)(z) * FNAME(creal)(z) + FNAME(cimag)(z) * FNAME(cimag)(z);
}
complex FTYPE FNAME(coordinate)(int i, int j, int width, int height, complex FTYPE center, FTYPE radius) {
FTYPE x = (i - width /FNAME(2.0)) / (height/FNAME(2.0));
FTYPE y = (j - height/FNAME(2.0)) / (height/FNAME(2.0));
complex FTYPE c = center + radius * (x - I * y);
return c;
}
int FNAME(calculate)(complex FTYPE c, int maximum_iterations, FTYPE escape_radius2) {
complex FTYPE z = 0;
int final_n = 0;
for (int n = 1; n < maximum_iterations; ++n) {
z = z * z + c;
if (FNAME(cabs2)(z) > escape_radius2) {
final_n = n;
break;
}
}
return final_n;
}
void FNAME(render)(int width, int height, complex FTYPE center, FTYPE radius, int maximum_iterations, FTYPE escape_radius2) {
printf("P5\n%d %d\n255\n", width, height);
for (int j = 0; j < height; ++j) {
for (int i = 0; i < width; ++i) {
complex FTYPE c = FNAME(coordinate)(i, j, width, height, center, radius);
int final_n = FNAME(calculate)(c, maximum_iterations, escape_radius2);
putchar(final_n);
}
}
}
otrzymujemy:
float pif = 3.14159265358979323846264338327950288419716939937510f;
float cabs2f(_Complex float z) {
return crealf(z) * crealf(z) + cimagf(z) * cimagf(z);
}
_Complex float coordinatef(int i, int j, int width, int height, _Complex float center, float radius) {
float x = (i - width /2.0f) / (height/2.0f);
float y = (j - height/2.0f) / (height/2.0f);
_Complex float c = center + radius * (x - (__extension__ 1.0iF) * y);
return c;
}
void calculatef(struct pixel *out, _Complex float c, int maximum_iterations, float escape_radius2) {
out->final_n = 0;
out->final_z = 0;
_Complex float z = 0;
for (int n = 1; n < maximum_iterations; ++n) {
z = z * z + c;
if (cabs2f(z) > escape_radius2) {
out->final_n = n;
out->final_z = z;
break;
}
}
}
void renderf(struct image *img, _Complex float center, float radius, int maximum_iterations, float escape_radius2) {
#pragma omp parallel for
for (int j = 0; j < img->height; ++j) {
for (int i = 0; i < img->width; ++i) {
_Complex float c = coordinatef(i, j, img->width, img->height, center, radius);
calculatef(&img->pixels[j * img->width + i], c, maximum_iterations, escape_radius2);
}
}
}
double pi = 3.14159265358979323846264338327950288419716939937510;
double cabs2(_Complex double z) {
return creal(z) * creal(z) + cimag(z) * cimag(z);
}
_Complex double coordinate(int i, int j, int width, int height, _Complex double center, double radius) {
double x = (i - width /2.0) / (height/2.0);
double y = (j - height/2.0) / (height/2.0);
_Complex double c = center + radius * (x - (__extension__ 1.0iF) * y);
return c;
}
void calculate(struct pixel *out, _Complex double c, int maximum_iterations, double escape_radius2) {
out->final_n = 0;
out->final_z = 0;
_Complex double z = 0;
for (int n = 1; n < maximum_iterations; ++n) {
z = z * z + c;
if (cabs2(z) > escape_radius2) {
out->final_n = n;
out->final_z = z;
break;
}
}
}
void render(struct image *img, _Complex double center, double radius, int maximum_iterations, double escape_radius2) {
#pragma omp parallel for
for (int j = 0; j < img->height; ++j) {
for (int i = 0; i < img->width; ++i) {
_Complex double c = coordinate(i, j, img->width, img->height, center, radius);
calculate(&img->pixels[j * img->width + i], c, maximum_iterations, escape_radius2);
}
}
}
long double pil = 3.14159265358979323846264338327950288419716939937510l;
long double cabs2l(_Complex long double z) {
return creall(z) * creall(z) + cimagl(z) * cimagl(z);
}
_Complex long double coordinatel(int i, int j, int width, int height, _Complex long double center, long double radius) {
long double x = (i - width /2.0l) / (height/2.0l);
long double y = (j - height/2.0l) / (height/2.0l);
_Complex long double c = center + radius * (x - (__extension__ 1.0iF) * y);
return c;
}
void calculatel(struct pixel *out, _Complex long double c, int maximum_iterations, long double escape_radius2) {
out->final_n = 0;
out->final_z = 0;
_Complex long double z = 0;
for (int n = 1; n < maximum_iterations; ++n) {
z = z * z + c;
if (cabs2l(z) > escape_radius2) {
out->final_n = n;
out->final_z = z;
break;
}
}
}
void renderl(struct image *img, _Complex long double center, long double radius, int maximum_iterations, long double escape_radius2) {
#pragma omp parallel for
for (int j = 0; j < img->height; ++j) {
for (int i = 0; i < img->width; ++i) {
_Complex long double c = coordinatel(i, j, img->width, img->height, center, radius);
calculatel(&img->pixels[j * img->width + i], c, maximum_iterations, escape_radius2);
}
}
}