Няшная / Говнокод #28320 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
// Heap memory allocate function (must not be used!)
caddr_t _sbrk(int incr) {
    <...>
    void some_bastard_called_sbrk();
    some_bastard_called_sbrk(); // Produce linker error in case it is used
}

_ATTRIBUTE ((__format__ (__printf__, 1, 2)))
int	printf (const char *__restrict format, ...)
{
    <маленький трехколесный велосипед>
}

int	putchar(int c) 
{
    <...> 
}
int	puts(const char *s) 
{
    <...> 
}

_ATTRIBUTE ((__format__ (__printf__, 2, 3)))
int	sprintf (char *__restrict s, const char *__restrict format, ...)
{
    <...> 
}

STM32. Я просто хочу использовать printf для вывода в последовательный порт и не течь. Ведь для этого нужно только реализовать int _write(int file, char *data, int len) и всё. Ой, а почему иногда программа падает где-то в кишках рантайма?

Может, стек переполняется? Да нет, проверил, значения в норме...

Просто стандартная библиотека от ST - это не курсовая ардуинщика, тут все системно, хендлы потоков, дескрипторы устройств и управляющие структуры. При первом обращении printf (и sprintf тоже!) выделяет себе в куче около 400 байт. Замечательное решение, помогающее сэкономить память, если мы не используем стандартный вывод! А куча тут - это просто последовательно заполняемая область памяти, размеры которой задаются в linker script (я вообще 0 указал, я ведь не использую malloc). Проверять выход за пределы кучи мы, конечно, не будем - зачем, когда рядом такая замечательная, никому не нужная область стека.
Да, и если забыть отключить буферизацию setvbuf(stdin/stdout/stderr, NULL, _IONBF, 0); , то он выделит не 400 байт, а килобайт (на контроллере с 8K RAM).

В общем, ах, оставьте меня, сам все напишу.
Только надо еще putchar и puts реализовать, а то компилятор любит printf'ы оптимизировать. И не забыть, что puts добавляет перевод строки. Уф, вроде все.

Steve_Brown Steve_Brown, (Updated )

Комментарии (21, +21)

Няшная / Говнокод #28309 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47
  48. 48
  49. 49
  50. 50
  51. 51
  52. 52
  53. 53
  54. 54
  55. 55
  56. 56
  57. 57
  58. 58
  59. 59
  60. 60
  61. 61
  62. 62
  63. 63
  64. 64
  65. 65
  66. 66
  67. 67
  68. 68
  69. 69
  70. 70
  71. 71
  72. 72
  73. 73
  74. 74
  75. 75
  76. 76
  77. 77
  78. 78
  79. 79
  80. 80
  81. 81
  82. 82
  83. 83
  84. 84
  85. 85
  86. 86
  87. 87
  88. 88
  89. 89
  90. 90
  91. 91
  92. 92
  93. 93
  94. 94
  95. 95
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

void swap(uint8_t *x, uint8_t *y)
{
    uint8_t tmp;
    tmp = *x;
    *x = *y;
    *y = tmp;
}

// эту хуйню тоже можно нагенерировать
uint64_t cmp_bits(uint8_t a[restrict 9])
{
  return 
  ((uint64_t)(a[0] < a[1]) << 0) |
  ((uint64_t)(a[0] < a[2]) << 1) |
  ((uint64_t)(a[0] < a[3]) << 2) |
  ((uint64_t)(a[0] < a[4]) << 3) |
  ((uint64_t)(a[0] < a[5]) << 4) |
  ((uint64_t)(a[0] < a[6]) << 5) |
  ((uint64_t)(a[0] < a[7]) << 6) |
  ((uint64_t)(a[0] < a[8]) << 7) |

  ((uint64_t)(a[1] < a[2]) << 8)  |
  ((uint64_t)(a[1] < a[3]) << 9)  |
  ((uint64_t)(a[1] < a[4]) << 10) |
  ((uint64_t)(a[1] < a[5]) << 11) |
  ((uint64_t)(a[1] < a[6]) << 12) |
  ((uint64_t)(a[1] < a[7]) << 13) |
  ((uint64_t)(a[1] < a[8]) << 14) |

  ((uint64_t)(a[2] < a[3]) << 15) |
  ((uint64_t)(a[2] < a[4]) << 16) |
  ((uint64_t)(a[2] < a[5]) << 17) |
  ((uint64_t)(a[2] < a[6]) << 18) |
  ((uint64_t)(a[2] < a[7]) << 19) |
  ((uint64_t)(a[2] < a[8]) << 20) |

  ((uint64_t)(a[3] < a[4]) << 21) |
  ((uint64_t)(a[3] < a[5]) << 22) |
  ((uint64_t)(a[3] < a[6]) << 23) |
  ((uint64_t)(a[3] < a[7]) << 24) |
  ((uint64_t)(a[3] < a[8]) << 25) |

  ((uint64_t)(a[4] < a[5]) << 26) |
  ((uint64_t)(a[4] < a[6]) << 27) |
  ((uint64_t)(a[4] < a[7]) << 28) |
  ((uint64_t)(a[4] < a[8]) << 29) |

  ((uint64_t)(a[5] < a[6]) << 30) |
  ((uint64_t)(a[5] < a[7]) << 31) |
  ((uint64_t)(a[5] < a[8]) << 32) |

  ((uint64_t)(a[6] < a[7]) << 33) |
  ((uint64_t)(a[6] < a[8]) << 34) |

  ((uint64_t)(a[7] < a[8]) << 35);
}

void printshit(uint8_t a[restrict 9])
{
  size_t i = 0;
  while(*a != 4)
  {
    a++;
    i++;
  }
  printf("arr[%" PRIu64 "] = %zu\n", cmp_bits(a), i);
}

void permute(char *a, size_t l, size_t r)
{
  size_t i;
  if (l == r)
    printshit(a);
  else
  {
    for (i = l; i <= r; i++)
    {
      swap((a+l), (a+i));
      permute(a, l+1, r);
      swap((a+l), (a+i));
    }
  }
}

int main()
{
    uint8_t a[] = {0,1,2,3,4,5,6,7,8};
    size_t n = 9;
    permute(a, 0, n-1);
    return 0;
}

https://govnokod.ru/24496#comment782476

Построение таблицы поиска для быстрого нахождения медианы. Там эту хуйню конечно можно улучшить, например запаковывать число от 0 до 8 в хуйни по 4 бита

j123123 j123123, (Updated )

Комментарии (55, +55)

Няшная / Говнокод #28292 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47
  48. 48
  49. 49
  50. 50
  51. 51
  52. 52
  53. 53
  54. 54
  55. 55
  56. 56
  57. 57
  58. 58
  59. 59
  60. 60
  61. 61
  62. 62
  63. 63
  64. 64
  65. 65
  66. 66
  67. 67
  68. 68
  69. 69
  70. 70
  71. 71
  72. 72
  73. 73
  74. 74
  75. 75
  76. 76
  77. 77
  78. 78
  79. 79
  80. 80
  81. 81
  82. 82
  83. 83
  84. 84
  85. 85
  86. 86
  87. 87
  88. 88
  89. 89
  90. 90
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define NUMARGS(type,...)  (sizeof((type[]){__VA_ARGS__})/sizeof(type))
#define xDEF(type) typedef struct {size_t size; type* arr;  }  xARR(type)
#define xARR(type) jArr_ ## type

#define A(type, ...) (xARR(type)) {NUMARGS(type,__VA_ARGS__), (type[]){__VA_ARGS__}}

#define _FOR(type, item, Arr) type item=Arr.arr[0]; for(size_t I = 0; I < Arr.size; item=Arr.arr[++I] ) 
// MSVC
#define xFOR(type, item, array) do{  _FOR(type, item, array) {
// GCC, Clang
#define FOR(item, array)        do{ __auto_type Arr=array; _FOR(__auto_type, item, Arr) {
    
#define NEXT }} while(0);

#define OfArray(type,arr) (xARR(type)){sizeof(arr)/sizeof(type), arr }

typedef struct {
    char *name;
    int     id;
} Entry;


typedef struct {const char *name;} Str;
typedef struct {int x[2]; } Pair;

xDEF(Entry);
xDEF(Str);
xDEF(Pair);
xDEF(int);

void printEntry(xARR(Entry) entries)
{
    xFOR(Entry, e, entries)
        printf("%s %d \n", e.name, e.id);
    NEXT
}

void printSquares(xARR(int) ints)
{
    FOR(v, ints)
        printf("%d²=%d\n", v,(int) pow(v,2.));
    NEXT
}

int main(void)
{
    xARR(Entry) e = A(Entry, {"one",1}, {"two",2}, {"three",3});
    printEntry(e);
    
    puts("_______________________________________");
    
    // можно передавать в метод непосредственно аргуметом
    printSquares( A(int, 3, 7, 5, 4) );
    puts("_______________________________________");    
    
    int nums[]={4,3,2,1};
    // можно использовать ранее объявленный массив
    printSquares(OfArray(int,nums));
    
    // можно итерироватьcя по ранее объявленному массиву
    FOR(i, OfArray(int, nums))
        printf("%d-",i);
    NEXT
    
    puts("\n_______________________________________");
    
    //вложенные циклы:
    for (int k=1;k<3;k++)
        FOR(i, A(Str, "kakoi", "bagor"))    
            FOR(j, A(int, 1111,2222,3333))
                printf("%d %s %d\n", k, i.name, j);
            NEXT
        NEXT
    
    puts("_______________________________________");
    
    FOR(v, A(Pair, {1,2}, {11,12}, {20,21}))
        printf("%d,%d\n", v.x[0], v.x[1]);
    NEXT
    puts("_______________________________________");    
    //проблема пустого варарга
    FOR(j, A(int))
        printf("%d\n", j);
    NEXT    
    return(0);
}

https://godbolt.org/z/o9Tv9EvGx

Довёл for~each до ума.

3.14159265 3.14159265, (Updated )

Комментарии (26, +26)

Няшная / Говнокод #28289 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
#define BITS 8

typedef union
{
    int v;
    struct 
    {
        #define FIELD(x,_) int b##x:1;        
        EVAL(REPEAT(BITS, FIELD, ~))
        #undef FIELD
    };
} Num;

Num shl(Num n, int carry)
{
    #define SHIFTL(x,_) CAT(n.b, CAT(x = n.b, CAT(DEC_,x)));    
    EVAL(RREPEAT(BITS, SHIFTL, ~))
    #undef SHIFTL
    n.b0 = carry;
}

Num shr(Num n, int carry)
{
    #define SHIFTR(x,_) CAT(n.b, CAT(CAT(DEC_,x) = n.b, x));
    EVAL(REPEAT(BITS, SHIFTR, ~))
    #undef SHIFTR
    CAT(n.b, CAT(DEC_,BITS)) = carry;
}


int main()
{
    for (int i=0; i<33; ++i){
        Num n   = {i};
        Num n1 = shl(n,0);
        Num n2 = shr(n,0);        
        printf("%d %d %d\n",n ,n1 , n2);
    }
}

https://godbolt.org/z/48h6EWacY

Двунаправленный сдвиговый регистр на препроцессоре.
Сделан без использования арифметических действий.

3.14159265 3.14159265, (Updated )

Комментарии (6, +6)

Няшная / Говнокод #28185 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
#include <stdio.h> //Нужная библиотека, как обычно;

int main(){ //Типа начало программы;
    FILE *in,*out; //Входной и выходной файлы;
    unsigned long int h,i; //Высота изображения и итератор цикла;
    unsigned char px,s; //Прочитанный пиксель и насчитанный сэмпл аудио;
    in=fopen("1.bmp","rb"); //Открываем файл на чтение;
    out=fopen("1.pcm","wb"); //Открываем файл на запись;
    fseek(in,22,SEEK_SET); //Позиционируемся в то место заголовка, где записана высота изображения
    fread(&h,4,1,in); //Считываем высоту изображения (4 байта);
    for(i=0;i<h;i++){ //Цикл - пробег по строкам;
        fseek(in,0x436+i*256,SEEK_SET); //Позиционируемся на начало i-ой строки
        s=0; //Инициализируем счётчик (значение сэмпла);
        do{ //Подсчёт нечёрных пикселей;
            fread(&px,1,1,in); //Считываем цвет пикселя;
            s+=1; //Увеличиваем счётчик на единицу;
        }while(px); //И так, пока не встретится чёрный пиксель;
        fwrite(&s,1,1,out); //Записываем получившийся результат в выходной файл;
    }
    fclose(in); //Закрываем входной файл;
    fclose(out); //Закрываем выходной файл;
    return 0; //Типа конец программы;
}

https://habr.com/ru/post/419527/

kcalbCube kcalbCube, (Updated )

Комментарии (0)