This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
fuss:c [2017/02/22 18:30] – external edit 127.0.0.1 | fuss:c [2022/04/19 08:28] (current) – external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== Random 32-Long Hex String ====== | ||
+ | <code c> | ||
+ | char* wasRandom32Hex(void) { | ||
+ | static const char am[] = " | ||
+ | char* s = (char*) malloc(32); | ||
+ | srand(time(NULL)); | ||
+ | for (int i=0; i<32; ++i) { | ||
+ | s[i] = am[rand()%(sizeof(am)-1)]; | ||
+ | } | ||
+ | return s; | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | ====== Generate Random Floating Point Number ====== | ||
+ | |||
+ | Using the formula to generate a random number $r \in [0..m]$: | ||
+ | \begin{eqnarray*} | ||
+ | r &=& m * \frac{N}{M} | ||
+ | \end{eqnarray*} | ||
+ | |||
+ | where: | ||
+ | |||
+ | * $N$ is a generated random number. | ||
+ | * $M$ is the maximal random number ('' | ||
+ | |||
+ | we can write the macro '' | ||
+ | |||
+ | <code c> | ||
+ | #define RAND_F(x) (float)rand()/ | ||
+ | </ | ||
+ | |||
+ | that, when called, will generate a random number $r \in [0..x]$. | ||
+ | |||
+ | |||
+ | ====== Flush File Descriptors ====== | ||
+ | |||
+ | Instead of flushing '' | ||
+ | |||
+ | <code c> | ||
+ | setvbuf(stdout, | ||
+ | </ | ||
+ | |||
+ | which sets the terminal to unbuffered mode (data will be printed as soon as it is pushed). | ||
+ | |||
+ | ====== Moon Activity Spinner ====== | ||
+ | |||
+ | Works well under OS X, Lion and above because the terminal seems to display pictures for many UTF-8 characters. This snippet starts with the [[http:// | ||
+ | |||
+ | <code c> | ||
+ | / | ||
+ | /* Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 */ | ||
+ | / | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | int main(void) { | ||
+ | setvbuf(stdout, | ||
+ | char *m = " | ||
+ | char i; | ||
+ | cycle: | ||
+ | // 0x91 - new moon | ||
+ | i = 145; | ||
+ | do { | ||
+ | printf(" | ||
+ | usleep(100000); | ||
+ | printf(" | ||
+ | } while(++i< | ||
+ | goto cycle; | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | ====== Create a Formatted Date and Time ====== | ||
+ | |||
+ | This can be accomplished using '' | ||
+ | <code c> | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | int main(void) { | ||
+ | time_t rawtime; | ||
+ | struct tm* timeinfo; | ||
+ | char *now = (char *) malloc(17); | ||
+ | time ( & | ||
+ | timeinfo = localtime ( & | ||
+ | if(timeinfo == NULL) { | ||
+ | printf(" | ||
+ | return 1; | ||
+ | } | ||
+ | /* from strftime(3): | ||
+ | if(strftime(now, | ||
+ | printf(" | ||
+ | return 1; | ||
+ | } | ||
+ | /* print the string */ | ||
+ | printf(" | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | more information on the possible escape characters can be found in '' | ||
+ | |||
+ | ====== Number of Milliseconds to Hour ====== | ||
+ | |||
+ | '' | ||
+ | |||
+ | <code c> | ||
+ | / | ||
+ | /* Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 */ | ||
+ | / | ||
+ | int wasMillisecondsToClock(int min, int sec, int mil) { | ||
+ | return ( | ||
+ | 3600000 - ( | ||
+ | sec % 60 | ||
+ | ) * 1000 - ( | ||
+ | min % 60 | ||
+ | ) * 60 * 1000 - mil | ||
+ | ) % 3600000; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | For example, suppose that the hour is '' | ||
+ | <code c> | ||
+ | wasMillisecondsToClock(1, | ||
+ | </ | ||
+ | |||
+ | which returns '' | ||
+ | |||
+ | ====== Queue Implementations ====== | ||
+ | |||
+ | {{indexmenu> | ||
+ | |||
+ | ====== Combine two Paths ====== | ||
+ | |||
+ | The '' | ||
+ | - /home/test | ||
+ | - file.c | ||
+ | and combines the two paths together, returning a pointer to the combined path. In this example, the pointer will point to the string ''/ | ||
+ | |||
+ | <code c> | ||
+ | / | ||
+ | /* Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 */ | ||
+ | / | ||
+ | /* Concatenates two filesystem paths a and b together. | ||
+ | / | ||
+ | char *pathCombine(char *a, char *b) { | ||
+ | size_t sa = strlen(a); | ||
+ | size_t sb = strlen(b); | ||
+ | char *rt = (char*)calloc(sa + sb + 1, sizeof(char *)); | ||
+ | memcpy(rt, a, sa); | ||
+ | switch (a[sa - 1]) { | ||
+ | case '/': | ||
+ | break; | ||
+ | default: | ||
+ | rt = (char*)realloc(rt, | ||
+ | rt[sa] = '/'; | ||
+ | break; | ||
+ | } | ||
+ | memcpy(rt + strlen(rt), b, sb + 1); | ||
+ | return rt; | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | The '' | ||
+ | |||
+ | ====== Stack Implementations ====== | ||
+ | |||
+ | {{indexmenu> | ||
+ | |||
+ | ====== QuickSort ====== | ||
+ | |||
+ | <code c> | ||
+ | / | ||
+ | /* Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 */ | ||
+ | / | ||
+ | void QuickSort(int *a, int n) { | ||
+ | int p, i, j, t; | ||
+ | if (n < 2) return; | ||
+ | p = a[ n / 2 ]; | ||
+ | i = -1; | ||
+ | j = n; | ||
+ | do { | ||
+ | while (a[++i] < p); | ||
+ | while (p < a[--j]); | ||
+ | if (j > i) { | ||
+ | t = a[i]; | ||
+ | a[i] = a[j]; | ||
+ | a[j] = t; | ||
+ | } | ||
+ | } while (j > i); | ||
+ | QuickSort(a, | ||
+ | QuickSort(a + i, n - i); | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | ====== Double Linked Lists Implementation ====== | ||
+ | |||
+ | {{indexmenu> | ||
+ | |||
+ | ====== Two-Dimensional Array to Uni-Dimensional Array ====== | ||
+ | |||
+ | The '' | ||
+ | |||
+ | <code c> | ||
+ | int array[SIZE_X * SIZE_Y]; | ||
+ | void set(int x, int y, int v) { | ||
+ | array[SIZE_X * x + y] = v; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | the converse function '' | ||
+ | <code c> | ||
+ | int array[SIZE_X * SIZE_Y]; | ||
+ | int get(int x, int y) { | ||
+ | return array[SIZE_X * x + y]; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | returns the value stored in the 2D array at indices $x$ and $y$; | ||
+ | |||
+ | This follows the row-major order convention, if column-major order is desired, then the formula '' | ||
+ | |||
+ | ====== Determine if The System is Big Endian ====== | ||
+ | |||
+ | This can be done with a macro: | ||
+ | <code c> | ||
+ | #define IS_BIG_ENDIAN (*(uint16_t *)" | ||
+ | </ | ||
+ | |||
+ | ====== Merge Two Sorted Arrays by Preserving Sort Order ====== | ||
+ | |||
+ | This is an interview question at Quora: "Given two lists of sorted integers, develop an algorithm to sort these numbers into a single list efficiently." | ||
+ | |||
+ | The '' | ||
+ | |||
+ | <code c> | ||
+ | / | ||
+ | /* Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 */ | ||
+ | / | ||
+ | int *wasMergeSortedArrays(int *a, int size_a, int *b, int size_b) { | ||
+ | |||
+ | int s = size_a + size_b; | ||
+ | int *c = (int *)calloc(s, sizeof(int)); | ||
+ | | ||
+ | int a_i = 0; | ||
+ | int b_i = 0; | ||
+ | int c_i = 0; | ||
+ | do { | ||
+ | | ||
+ | if(a_i >= size_a) { | ||
+ | if(b_i < size_b) { | ||
+ | *c++ = *b++; | ||
+ | ++b_i; | ||
+ | continue; | ||
+ | } | ||
+ | continue; | ||
+ | } | ||
+ | | ||
+ | if(b_i >= size_b) { | ||
+ | if(a_i < size_a) { | ||
+ | *c++ = *a++; | ||
+ | ++a_i; | ||
+ | continue; | ||
+ | } | ||
+ | continue; | ||
+ | } | ||
+ | | ||
+ | if(*a < *b) { | ||
+ | *c++ = *a++; | ||
+ | ++a_i; | ||
+ | continue; | ||
+ | } | ||
+ | *c++ = *b++; | ||
+ | ++b_i; | ||
+ | | ||
+ | } while(++c_i < s); | ||
+ | | ||
+ | return c - s; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | and the example call would be: | ||
+ | <code c> | ||
+ | int main(void) { | ||
+ | int a[5] = { 1, 2, 5, 8, 77 }; | ||
+ | int b[7] = { 4, 9, 48, 99, 204, 500, 1024 }; | ||
+ | | ||
+ | int *c = wasMergeSortedArrays(a, | ||
+ | printf(" | ||
+ | int i = 0; | ||
+ | do { | ||
+ | printf(" | ||
+ | } while(++i < 12); | ||
+ | printf(" | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | ====== Weighted Selection Algorithm ====== | ||
+ | |||
+ | Given a list of elements each with an attributed weight, every time the '' | ||
+ | |||
+ | <code c> | ||
+ | / | ||
+ | /* Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 */ | ||
+ | / | ||
+ | float wasWeightedSelect(float *s, float *p, float size) { | ||
+ | float t = 0, c, f; | ||
+ | |||
+ | srand(time(NULL)); | ||
+ | do { | ||
+ | c = *p++; | ||
+ | t += c; | ||
+ | if ((float)rand() / (float)(RAND_MAX / t) < c) | ||
+ | f = *s; | ||
+ | s++; | ||
+ | } while(--size > 0); | ||
+ | |||
+ | return f; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | An example call would be: | ||
+ | <code c> | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | int main(void) { | ||
+ | float a[4] = { 1, 9, 7, 5 }; | ||
+ | float b[4] = { 12.5, 12.5, 25, 50 }; | ||
+ | |||
+ | float p = wasWeightedSelect(a, | ||
+ | |||
+ | printf(" | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ====== Get the Length of an Array ====== | ||
+ | |||
+ | The array length can roughly be seen as the size of the array divided by the size of the type that the array contains. These macros should be avoided at all costs and instead the length of the array should be passed along with the function call. Nevertheless, | ||
+ | |||
+ | <code c> | ||
+ | #define SIZE(array, type) (sizeof(array) / (sizeof(type)) | ||
+ | #define length(array) (sizeof(array)/ | ||
+ | #define ARRAY_LENGTH(array) (sizeof((array))/ | ||
+ | </ | ||
+ | |||
+ | Google Chromium defines '' | ||
+ | <code c> | ||
+ | #define COUNT_OF(x) ((sizeof(x)/ | ||
+ | </ | ||
+ | and it does cause a division by zero that may be caught by some compilers. | ||
+ | |||
+ | ====== Overloading Functions ====== | ||
+ | |||
+ | Given a function that creates a new stack structure such as: | ||
+ | <code c> | ||
+ | /* | ||
+ | * Creates a new stringStack with a given size. | ||
+ | */ | ||
+ | stringStack* stringStackCreate(int size) { | ||
+ | | ||
+ | if ((s-> | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | it is preferable to have an overload that automatically sets the size to '' | ||
+ | |||
+ | The function can be renamed to '' | ||
+ | <code c> | ||
+ | // Zero or one arguments for StackCreate_Internal. | ||
+ | #define stringStackCreate_0() stringStackCreate_Internal(1) | ||
+ | #define stringStackCreate_1(x) stringStackCreate_Internal(x) | ||
+ | #define _FUNC_OVERRIDE(_1, | ||
+ | #define stringStackCreate(...) _FUNC_OVERRIDE(stringStackCreate_1(__VA_ARGS__), | ||
+ | </ | ||
+ | |||
+ | This can then be generalised to any number of arguments (in this case, up to 4 overloads of '' | ||
+ | <code c> | ||
+ | // Zero or one arguments for StackCreate_Internal. | ||
+ | #define stringStackCreate_0() stringStackCreate_Internal(1) | ||
+ | #define stringStackCreate_1(x) stringStackCreate_Internal(x) | ||
+ | #define stringStackCreate_2(x, | ||
+ | #define stringStackCreate_3(x, | ||
+ | #define _FUNC_OVERRIDE(_1, | ||
+ | #define stringStackCreate(...) _FUNC_OVERRIDE(stringStackCreate_3(__VA_ARGS__), | ||
+ | </ |