Хакерский путь - передать первый элемент и выполнить вычисления массива вручную.
В этом длинном примере используется макрос для полуавтоматического извлечения измерений массива для использования в вызове.
struct font { int disp, trig; };
struct font font3[3][3];
#define dim(x) (sizeof(x)/sizeof*(x))
#define font_and_dims(x) (struct font *)x, dim(x), dim(*x)
int print(char *s, struct font *font, int dimy, int dimx) { ... }
main(){ ... print(*av, font_and_dims(font3)); ... }
Вызываемая функция обращается к массиву трудным путем.
print(){ ... font[row*dimx+col] ... }
Не бойтесь прокрутить вниз: хорошие вещи находятся внизу!Эта уродливая педантичная функция в верхней части обеспечивает максимальную переносимость кодировки;но это это бельмо на глазу, я признаю.
#include <stdio.h>
#include <string.h>
int ao(int c) {
switch(c) {
case '0':return 0;
case '1':return 1;
case '2':return 2;
case '3':return 3;
case '4':return 4;
case '5':return 5;
case '6':return 6;
case '7':return 7;
case '8':return 8;
case '9':return 9;
case 'A':case 'a':return 10;
case 'B':case 'b':return 11;
case 'C':case 'c':return 12;
case 'D':case 'd':return 13;
case 'E':case 'e':return 14;
case 'F':case 'f':return 15;
default:return -1;
}
}
enum {
A = 1 << 0,
B = 1 << 1,
C = 1 << 2,
D = 1 << 3,
E = 1 << 4,
F = 1 << 5,
G = 1 << 6,
H = 1 << 7 };
int seg[] = {
/*0*/ A|B|C|D|E|F,
/*1*/ B|C,
/*2*/ A|B| D|E| G,
/*3*/ A|B|C|D| G,
/*4*/ B|C| F|G,
/*5*/ A| C|D| F|G,
/*6*/ A| C|D|E|F|G,
/*7*/ A|B|C,
/*8*/ A|B|C|D|E|F|G,
/*9*/ A|B|C| F|G,
/*A*/ A|B|C|D|E| G, /*A|B|C| E|F|G,*/
/*b*/ C|D|E|F|G,
/*C*/ D|E| G, /*A| D|E|F,*/
/*d*/ B|C|D|E| G,
/*E*/ A|B| D|E|F|G, /*A| D|E|F|G,*/
/*F*/ A| E|F|G,
};
struct font {
int disp, trig;
};
/* _
|_|
|_|
*/
struct font font3[3][3] = {
{ { 0,0}, {'_',A}, { 0,0} },
{ {'|',F}, {'_',G}, {'|',B} },
{ {'|',E}, {'_',D}, {'|',C} },
};
/* ___
| |
|___|
| |
|___|
*/
struct font font5[5][5] = {
{ { 0,0}, {'_',A}, {'_',A}, {'_',A}, { 0,0} },
{ {'|',F}, { 0,0}, { 0,0}, { 0,0}, {'|',B} },
{ {'|',F}, {'_',G}, {'_',G}, {'_',G}, {'|',B} },
{ {'|',E}, { 0,0}, { 0,0}, { 0,0}, {'|',C} },
{ {'|',E}, {'_',D}, {'_',D}, {'_',D}, {'|',C} }
};
/* ____
| |
| |
| |
|____|
| |
| |
| |
|____|
*/
struct font font9[9][7] = {
{ { 0,0}, {'_',A}, {'_',A}, {'_',A}, {'_',A}, { 0,0}, {0,0} },
{ {'|',F}, { 0,0}, { 0,0}, { 0,0}, { 0,0}, {'|',B}, {0,0} },
{ {'|',F}, { 0,0}, { 0,0}, { 0,0}, { 0,0}, {'|',B}, {0,0} },
{ {'|',F}, { 0,0}, { 0,0}, { 0,0}, { 0,0}, {'|',B}, {0,0} },
{ {'|',F}, {'_',G}, {'_',G}, {'_',G}, {'_',G}, {'|',B}, {0,0} },
{ {'|',E}, { 0,0}, { 0,0}, { 0,0}, { 0,0}, {'|',C}, {0,0} },
{ {'|',E}, { 0,0}, { 0,0}, { 0,0}, { 0,0}, {'|',C}, {0,0} },
{ {'|',E}, { 0,0}, { 0,0}, { 0,0}, { 0,0}, {'|',C}, {0,0} },
{ {'|',E}, {'_',D}, {'_',D}, {'_',D}, {'_',D}, {'|',C}, {0,0} },
};
#define dim(x) (sizeof(x)/sizeof*(x))
#define font_and_dims(x) (struct font *)x, dim(x), dim(*x)
int print(char *s, struct font *font, int dimy, int dimx) {
int row, col;
char *sp;
for (row = 0; row < dimy; row++) {
for (sp = s; *sp; sp++) {
for (col = 0; col < dimx; col++) {
putchar( seg[ao(*sp)] & font[row*dimx+col].trig ?
font[row*dimx+col].disp : ' ');
}
}
putchar('\n');
}
}
int main(int ac, char **av) {
enum { F1, F2, F3 } fz = F1;
for (++av,--ac;ac;ac--,av++) {
if (av[0][0] == '-') {
switch (av[0][1]) {
case '1': fz=F1; continue;
case '2': fz=F2; continue;
case '3': fz=F3; continue;
default: fprintf(stderr, "Unrecognized Option!\n");
}
}
if (strspn(*av, "0123456789abcdefABCDEF") != strlen(*av))
fprintf(stderr, "Hex only!\n");
else
switch(fz) {
case F1: print(*av, font_and_dims(font3)); break;
case F2: print(*av, font_and_dims(font5)); break;
case F3: print(*av, font_and_dims(font9)); break;
default: fprintf(stderr, "Invalid Font!\n");
}
}
return 0;
}