C Programming FAQs: Frequently Asked Questions 笔记

// 使用qsort 和 strcmp int pstrcmp(const void *p1, const void *p2) { return strcmp(*(char * const *)p1, *(char * const *)p2); } int main(int argc, char **argv) { char *strings[NSTRING]; int nstrings; qsort(strings, nstrings, sizeof(char *), pstrcmp); }

 

// 同时输出到两个地方 #include <stdio.h> #include <stdarg.h> void f2printf(FILE *fp1, FILE *fp2, char *fmt, ...) { va_list argp; va_start(argp, fmt); vfprintf(fp1, fmt, argp); va_end(argp); va_start(argp, fmt); vfprintf(fp2, fmt, argp); va_end(argp); }

 

// convert integers to binary or hexadecimal char *baseconv(unsigned int num, int base) { static char retbuf[33]; char *p; if(base < 2 || base > 16) { return NULL; } p = &retbuf[sizeof(retbuf)-1]; *p = '/0'; do { *--p = "0123456789abcdef"[num % base]; num /= base; } while(num != 0); return p; } // determine whether a machine's byte order is big-endian or little-endian int isLE() { int x = 1; return (*(char *)&x == 1) ? 1 : 0; } // count the number of bits which are set in an integer int bitcount(unsigned int u) { const static int bitcounts[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4}; int n = 0; for(; u != 0; u >>= 4) { n += bitcounts[u & 0x0f]; } return n; } // 调换字节 void swap(char *ptr, int nwords) { char *p = ptr; while (nwords--) { char tmp = *p; *p = *(p+1); *(p+1) = tmp; p += 2; } }

 

// match for * ? int match(char *pat, char *str) { switch(*pat) { case '/0': return !*str; case '*': return match(pat+1, str) || *str && match(pat, str+1); case '?': return *str && match(pat+1, str+1); default: return *pat == *str && match(pat+1, str+1); } }

 

// match for * . ^ $ from beautiful code int matchstar(int c, char *regexp, char *text); // matchhere: search for regexp at beginning of text int matchhere(char *regexp, char *text) { if (regexp[0] == '/0') { return 1; } if (regexp[1] == '*') { return matchstar(regexp[0], regexp+2, text); } if (regexp[0] == '$' && regexp[1] == '/0') { return *text == '/0'; } if (*text!='/0' && (regexp[0]=='.' || regexp[0]==*text)) { return matchhere(regexp+1, text+1); } return 0; } // matchstar: search for c*regexp at beginning of text int matchstar(int c, char *regexp, char *text) { do { // a * matches zero or more instances if (matchhere(regexp, text)) { return 1; } } while (*text != '/0' && (*text++ == c || c == '.')); return 0; } // match: search for regexp anywhere in text int match(char *regexp, char *text) { if (regexp[0] == '^') { return matchhere(regexp+1, text); } do { // must look even if string is empty */ if (matchhere(regexp, text)) { return 1; } } while (*text++ != '/0'); return 0; }

 

// 0 = Sunday int dayofweek(int y, int m, int d) { static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}; y -= m < 3; return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7; }

char *commaprint(unsigned long n) { static int comma = '/0'; static char retbuf[30]; char *p = &retbuf[(4*sizeof(long)*CHAR_BIT+2)/3/3+1]; int i = 0; if(comma == '/0') { struct lconv *lcp = localeconv(); if(lcp != NULL) { comma = (lcp->thousands_sep != NULL && *lcp->thousands_sep != '/0') ? *lcp->thousands_sep : ','; } } *p = '/0'; do { if(i%3 == 0 && i != 0) { *--p = comma; } *--p = '0' + n % 10; n /= 10; i++; } while(n != 0); return p; }

 

// Here is a portable C implementation of the ``minimal standard'' generator proposed by Park and Miller: #define a 16807 #define m 2147483647 #define q (m / a) #define r (m % a) static long int seed = 1; long int PMrand() { long int hi = seed / q; long int lo = seed % q; long int test = a * lo - r * hi; seed = (test > 0) ? test : test + m; return seed; } #include <stdlib.h> (int)((double)rand() / ((double)RAND_MAX +1) * N) rand() / (RAND_MAX / N + 1) unsigned int x = (RAND_MAX + 1U) / N; unsigned int y = x * N; unsigned int r; do { r = rand(); } while (r >= y); return r / x; #include <time.h> srand((unsigned int )time((time_t *)NULL)); // [M,N]范围的随机整数 M + rand() / (RAND_MAX /(N - M + 1)+1)

 

// 怎样产生正态分布或高斯分布的随机数 // Exploit the Central Limit Theorem (``law of large numbers'') and add up several uniformly-distributed random numbers: // 中心极限定理(大数定律) #include <stdlib.h> #include <math.h> #define NSUM 25 double gaussrand() { double x = 0; for(int i = 0; i < NSUM; i++) { x += (double)rand() / RAND_MAX; } x -= NSUM / 2.0; x /= sqrt(NSUM / 12.0); return x; } // Use a method described by Abramowitz and Stegun: #include <stdlib.h> #include <math.h> #define PI 3.141592654 double gaussrand() { static double U, V; static int phase = 0; double Z; if(phase == 0) { U = (rand() + 1.) / (RAND_MAX + 2.); V = rand() / (RAND_MAX + 1.); Z = sqrt(-2 * log(U)) * sin(2 * PI * V); } else { Z = sqrt(-2 * log(U)) * cos(2 * PI * V); } phase = 1 - phase; return Z; } // Use a method discussed in Knuth and due originally to Marsaglia: #include <stdlib.h> #include <math.h> double gaussrand() { static double V1, V2, S; static int phase = 0; double X; if(phase == 0) { do { double U1 = (double)rand() / RAND_MAX; double U2 = (double)rand() / RAND_MAX; V1 = 2 * U1 - 1; V2 = 2 * U2 - 1; S = V1 * V1 + V2 * V2; } while(S >= 1 || S == 0); X = V1 * sqrt(-2 * log(S) / S); } else { X = V2 * sqrt(-2 * log(S) / S); } phase = 1 - phase; return X; }

 

// Here is a function which concatenates an arbitrary number of strings into malloc'ed memory: #include <stdlib.h> /* for malloc, NULL, size_t */ #include <stdarg.h> /* for va_ stuff */ #include <string.h> /* for strcat et al. */ char *vstrcat(const char *first, ...) { va_list argp; if(first == NULL) { return NULL; } size_t len = strlen(first); va_start(argp, first); while((char *p = va_arg(argp, char *)) != NULL) { len += strlen(p); } va_end(argp); char *retbuf = malloc(len + 1); /* +1 for trailing /0 */ if(retbuf == NULL) { return NULL; } (void)strcpy(retbuf, first); va_start(argp, first); /* restart; 2nd scan */ while((char *p = va_arg(argp, char *)) != NULL) { (void)strcat(retbuf, p); } va_end(argp); return retbuf; } // example : char *str = vstrcat("Hello, ", "world!", (char *)NULL);

 

// 输入一个百分比进度器 for(i = 0; i < lotsa; i++) { printf("/r%3d%%", (int)(100L * i / lotsa)); fflush(stdout); do_timeconsuming_work(); } printf("/ndone./n"); // 旋转棒 printf("working: "); for(i = 0; i < lotsa; i++) { printf("%c/b", "|/-//"[i%4]); fflush(stdout); do_timeconsuming_work(); } printf("done./n");

 

#include <limits.h> /* for CHAR_BIT */ #define BITMASK (b) (1 << ((b) % CHAR_BIT)) #define BITSLOT (b) ((b) / CHAR_BIT) #define BITSET (a, b) ((a)[BITSLOT(b)] |= BITMASK(b)) #define BITCLEAR (a, b) ((a)[BITSLOT(b)] &= ~BITMASK(b)) #define BITTEST (a, b) ((a)[BITSLOT(b)] & BITMASK(b)) #define BITNSLOTS(nb) ((nb + CHAR_BIT - 1) / CHAR_BIT) //#define XOR(a,b) (!!(a) ^ !!(b)) #define XOR(a,b) (!!(a)!=!!(b)) // 声明一个47位的"数组" char bitarray[BITNSLOTS(47)]; // 置第23位 BITSET(bitarray, 23); // 测试第35位 if(BITTEST(bitarray, 35)) ... // 计算两个位数组的并,再将结果放入另一个数组 for(i = 0; i < BITNSLOTS(47); i++) { array3[i] = array1[i] | array2[i]; } // 要计算交,使用 & 而不是 | /**** 功能 | 示例 | 位运算 ----------------------+--------------------- ----+-------------------- 去掉最后一位 | (101101->10110) | x >> 1 在最后加一个0 | (101101->1011010) | x < < 1 在最后加一个1 | (101101->1011011) | x < < 1+1 把最后一位变成1 | (101100->101101) | x | 1 把最后一位变成0 | (101101->101100) | x | 1-1 最后一位取反 | (101101->101100) | x ^ 1 把右数第k位变成1 | (101001->101101,k=3) | x | (1 < < (k-1)) 把右数第k位变成0 | (101101->101001,k=3) | x & ~ (1 < < (k-1)) 右数第k位取反 | (101001->101101,k=3) | x ^ (1 < < (k-1)) 取末三位 | (1101101->101) | x & 7 取末k位 | (1101101->1101,k=5) | x & ((1 < < k)-1) 取右数第k位 | (1101101->1,k=4) | x >> (k-1) & 1 把末k位变成1 | (101001->101111,k=4) | x | (1 < < k-1) 末k位取反 | (101001->100110,k=4) | x ^ (1 < < k-1) 把右边连续的1变成0 | (100101111->100100000) | x & (x+1) 把右起第一个0变成1 | (100101111->100111111) | x | (x+1) 把右边连续的0变成1 | (11011000->11011111) | x | (x-1) 取右边连续的1 | (100101111->1111) | (x ^ (x+1)) >> 1 去掉右起第一个1的左边 | (100101000->1000) | x & (x ^ (x-1)) 判断奇数 | | (x&1)==1 判断偶数 | | (x&1)==0 ***/ // 用筛选法(Sieve of Eratosthenes)来计算素数的快速实现 #include <stdio.h> #include <string.h> #define MAX 10000 int main() { char bitarray[BITNSLOTS(MAX)]; int i, j; memset(bitarray, 0, BITNSLOTS(MAX)); for(i = 2; i < MAX; i++) { if(!BITTEST(bitarray, i)) { printf("%d/n", i); for(j = i + i; j < MAX; j += i) { BITSET(bitarray, j); } } } return 0; }

 

 

你可能感兴趣的:(C Programming FAQs: Frequently Asked Questions 笔记)