16.1 整型函数
16.1.1 算术<stdlib.h>
int abs( int value );long int labs( long int value );div_t div( int numerator, int denominator );ldiv_t ldiv( long int number, long int denom );abs函数返回它的参数的绝对值.如果其结果不能用一个整数表示,这个行为是未定义的.labs用于执行相同的任务,但它的作用对象是长整数.
div函数把它的第二个参数(分母)除第一个参数(分子),产生商和余数,用一个div_t结构返回.这个结构包含以下两个字段:
int quote;int rem;
#include程序输出:#include int main(void){ div_t dt; printf("%d\n", abs( -123 ) ); dt = div( 123, 12 ); printf("%d---%d\n", dt.quot, dt.rem ); return 0;}
16.1.2 随机数<stdlib.h>
int rand( void );void srand( unsigned int seed );通常通过rand+srand来产生随机数:通过srand初始化随机数发生器,通过rand来获得随机数.
#include16.1.3 字符串转换<stdlib.h>#include #define TRUE 1#define FALSE 0void shuffle( int *deck, int n_cards ){ int i; static int first_time = TRUE; /* *如果尚未初始化,用当天的当前时间作为随机数发生器 */ if ( first_time ){ first_time = FALSE; srand( ( unsigned int )time( NULL ) ); } /* *通过交换随机对的牌进行"洗牌" */ for ( i = n_cards - 1; i > 0; i-- ){ int where; int temp; where = rand() % i; temp = deck[ where ]; deck[ where ] = deck[ i ]; deck[ i ] = temp; }}
int atoi( char const *string );long int atol( char const *string );long int strtol( char const *string, char **unused, int base );unsigned long int strtoul( char const *string, char **unused, int base );strtol保存一个指向转换值后面第一个字符的指针.如果函数的第二个参数并非为NULL,这个指针便保存在第二个参数所指向的位置.这个指针允许字符串的剩余部分进行处理而无需推测转换在字符串的哪个位置终止.
16.2 浮点型函数
头文件math.h包含了函数库中剩余的数学函数的声明.这些函数的返回值以及绝大多数参数都是double类型.
16.2.1 三角函数<math.h>
double sin( double angle );double cos( double angle );double tan( double angle );double asin( double value );double acos( double value );double atan( double value );double atans( double x, double y );备注:angle是弧度.
16.2.2 双曲函数<math.h>
double sinh( double angle );double cosh( double angle );double tanh( double angle );
16.2.3 对数和指数函数<math.h>
double exp( double value );double log( double value );double log10( double value );16.2.5 幂<math.h>
double pow( double x, double y );double sqrt( double x );16.2.6 底数,顶数,绝对值和余数
double floor( double x );double ceil( double x );double fabs( double x );double fmod( double x, double y );floor返回不大于其参数的最大整数值.ceil返回不小于其参数的最大整数值.
fabs返回其参数的绝对值,fmod返回参数x除y得到的余数.
16.2.7 字符串转换<stdlib.h>
double atof( char const *string );double strtod( char const *string, char **unused );
16.3 日期和时间函数
16.3.1 处理器时间<time.h>
clock函数返回从程序开始执行处理器所消耗的时间:
clock_t clock( void );如果要显示秒,则初一CLOCKS_PER_SEC即可.
#include程序输出:#include int main(void){ clock_t t1 = clock(); clock_t t2; int i = 0; for ( i = 0; i < 100000000; i++ ) ; t2 = clock(); printf("%d---%d---%d\n", t1, t2, t2 - t1 ); printf("%d\n", CLOCKS_PER_SEC ); return 0;}
16.3.2 当天时间<time.h>
time函数返回当前的日期和时间
time_t time( time_t *return_value );如果参数是一个非空的指针,时间值也将通过这个指针进行存储.
#include但是,返回值貌似不太对哦,不同的运行,显示不同的答案.#include #include int main(void){ time_t *tt = malloc( sizeof( time_t ) ); time( tt ); printf("%d\n", tt ); free( tt ); return 0;}
于是,我对代码进行了修改(书上明显介绍有误,不知道是不是翻译的问题):
#include现在,程序正常输出了:#include #include int main(void){ time_t tt; tt = time( NULL ); printf("%d\n", tt ); return 0;}
转换到年:
日期和时间的转换
char *ctime( time_t const *time_value );double difftime( time_t time1, time_t time2 );接下来的两个函数把一个time_t值转换为一个tm结构,后者允许我们很方便地访问日期和时间的各个组成部分:
struct tm *gmtime( time_t const *time_value );struct tm *localtime( time_t const *time_value );备注:tm结构中月份是从0开始的,而年是从1900开始的.
#include程序输出:#include #include int main(void){ time_t tt1; time_t tt2; time_t *ptt = &tt1; struct tm *tm1; int i = 0; int j = 0; tt1 = time( NULL ); for ( i = 0; i < 100000000; i++ ) for ( j = 0; j < 10; j++ ) ; tt2 = time( NULL ); printf("%s\n", ctime( ptt ) ); printf("%d----%d\n", tt1, tt2 ); printf("the time waste %d\n", difftime( tt2, tt1 ) ); tm1 = gmtime( ptt ); printf("%d---%d", tm1->tm_mon + 1, tm1->tm_year + 1900 ); return 0;}
我不理解的是:为什么tt2的时间居然是0???
唉,把%d改为%d吧.
而mktime函数把一个tm结构转换为一个time_t值.
time_t mktime( struct tm *tm_ptr );16.4 非本地跳转
setjmp和longjmp函数提供了一种类似goto语句的机制,但它并不局限于一个函数的作用域之内.这些函数常用于深层嵌套的函数调用链.如果在某个低层的函数中检测到一个错误,你可以立即返回到顶层函数,不必向调用链中的每个中间层返回一个错误标志.
#include你声明一个jmp_buf变量,并调用setjmp函数对它进行初始化,setjmp的返回值为0.setjmp把程序的状态信息保存到跳转缓冲区.你调用setjmp时所处的函数便成为你的"顶层"函数.int setjmp( jmp_buf state );void longjmp( jump_buf state, int value );
以后,在顶层函数或其他任何它所调用的函数内的任何地方调用longjmp函数,将导致这个被保存的状态重新恢复.longjmp的效果就是使执行流通过再次从setjmp函数返回,从而立即跳回到顶层函数中.
备注:具体参考<UNIX高级环境编程>一书.
16.7 执行环境
16.7.1 终止执行<stdlib.h>
void abort( void );void atexit( void (func)( void ) );void exit( int status );abort函数用于不正常地终止一个正在执行的程序.由于这个函数将引发SIGABRT信号,你可以在程序中为这个信号设置一个信号处理函数,在程序终止之前采取任何你想采取的动作,甚至可以不终止程序.
atexit函数可以把一些函数注册为推出函数.当程序将要正常终止时,退出函数将被调用.退出函数不能接受任何参数.
当exit函数被调用时,所有被atexit函数注册为退出函数的函数将按照它们所注册的顺序被反序依次调用.然后,所有用于流的缓冲区被刷新,所有打开的文件被关闭.用tmpfile函数创建的文件被删除.然后,退出状态返回给宿主环境,程序停止执行.
16.7.2 断言<assert.h>
断言就是声明某种东西应该为真.
void assert( int expression );当它被执行时,这个宏对表达式参数进行测试.如果它的值为假,它就向标准错误打印一条诊断信息并终止程序.
增加:
#define NDEBUG后,消除所有的断言.
16.7.5 排序和查找<stdlib.h>
void qsort( void *base, size_t n_elements, size_t el_size, int ( *compare )( void const *, void const * ) );
#includebsearch用于二叉树查找:#include typedef struct { char key[10]; int other_data;} Record;int r_compare( void const *a, void const *b ){ return strcmp( ( ( Record* )a)->key, ( ( Record* )b)->key );}int main(void){ Record array[50]; qsort( array, 50, sizeof( Record ), r_compare ); return EXIT_SUCCESS;}
void *bsearch( void const *key, void const *base, size_t n_elements, size_t el_size, int ( *compare )( void const *, void const * ) );
#include#include typedef struct { char key[10]; int other_data;} Record;int r_compare( void const *a, void const *b ){ return strcmp( ( ( Record* )a )->key, ( ( Record* )b )->key );}int main(void){ Record array[50]; Record key; Record *ans; strcpy( key.key, "value" ); ans = bsearch( &key, array, 50, sizeof( Record ), r_compare ); return EXIT_SUCCESS;}
习题:
1.
#include#include #include int func( int value ){ return ceil( ( value - 9) / 2 );}int main( int ac, char **av ){ printf("%d\n", func( 41 ) ); printf("%d\n", func( 45 ) ); printf("%d\n", func( 34 ) ); return 0;}
程序输出:
2.
#include#include #include int main( int ac, char **av ){ int i = 0; srand( ( unsigned int )time( NULL ) ); for ( i = 1; i <= 18; i++ ){ printf("%d ", rand() % 6 ); if ( !( i % 6 ) ){ printf("\n"); } } return 0;}
程序输出:
4.
#include#include #include int main( int ac, char **av ){ struct tm tm1; tm1.tm_year = 2013 - 1900; tm1.tm_mon = 9 - 1; tm1.tm_mday = 24; tm1.tm_hour = 0; tm1.tm_isdst = 0; tm1.tm_min = 0; tm1.tm_sec = 0; tm1.tm_yday = 0; mktime( &tm1 ); printf("%d", tm1.tm_wday ); return 0;}
程序输出:
5.
#include程序输出:#include #include #include #define A 10.45#define B 10.00#define C -1.0#define X 1.78816double wind_chill( double temp, double velocity ){ double V = velocity; double t = 33 - temp; return 33 - ( A + B * sqrt( V ) + C * V ) * t / ( A + B * sqrt( X ) + C * X ); //书上并未说要用33减,可能是翻译的问题!!}int main( int ac, char **av ){ printf("%f\n", wind_chill( -5, 10 ) ); return 0;}
6.
#include程序输出:#include #include #include double payment( double amount, double interest, int year ){ double A = amount; double N = year * 12; double I = interest * 1.0 / 12 / 100; return A * I / ( 1 - pow( 1 + I, -N ) );}int main( int ac, char **av ){ printf("%f\n", payment( 100000, 8, 20 ) ); return 0;}
7.
1)
#include程序输出:#include #include void func( int arr[], int randValue ){ int i = 0; for ( i = 0; i < 10; i++ ){ arr[i] = 0; } for ( i = 0; i < 10000; i++ ){ arr[ rand() % randValue ]++; }}void printArr( int arr[], int len ){ int i = 0; for ( i = 0; i < len; i++ ){ printf("%d ", arr[i] ); } printf("\n");}int main(void){ int temp[10]; int i = 0; for ( i = 0; i < 10; i++ ){ temp[i] = 0; } srand( ( unsigned int )time( NULL ) ); for ( i = 2; i <= 10; i++ ){ func( temp, i ); printArr( temp, i ); } return 0;}
2)
#include#include #include void func( int arr[][10], int randValue ){ int i = 0; int j = 0; int preValue = 0; for ( i = 0; i < 10; i++ ){ for ( j = 0; j < 10; j++ ){ arr[i][j] = 0; } } for ( i = 0; i < 10000; i++ ){ preValue = rand() % randValue; arr[ preValue ][ rand() % randValue ]++; }}void printArr( int arr[][10], int len ){ int i = 0; int j = 0; for ( i = 0; i < len; i++ ){ for ( j = 0; j < len; j++ ){ printf("%3d ", arr[i][j]); } printf("\n"); } printf("\n---------------------\n");}int main(void){ int temp[10][10]; int i = 0; int j = 0; for ( i = 0; i < 10; i++ ){ for ( j = 0; j < 10; j++ ){ temp[i][j] = 0; } } srand( ( unsigned int )time( NULL ) ); for ( i = 2; i <= 10; i++ ){ func( temp, i ); printArr( temp, i ); } return 0;}
程序输出过长,截取一半:
8.之前写过,略过.
9. 概率很怪,有时候100%,有时候0%,也有时候13.4%
#include程序输出:#include #include void init( int arr[] ){ int i = 0; for ( i = 0; i < 365; i++ ){ arr[i] = 0; }}void func( int arr[] ){ int i = 0; init( arr ); srand( ( unsigned int )time( NULL ) ); for ( i = 0; i < 30; i++ ){ arr[ rand() % 365 ]++; }}int isHave( int arr[] ){ int i = 0; for ( i = 0;i < 365; i++ ){ if ( arr[i] > 1 ){ return 1; } } return 0;}int main(void){ int i = 0; int j = 0; int arr[365]; double count = 0; for ( i = 0; i < 10000; i++ ){ func( arr ); if ( isHave( arr ) ){ count++; } init( arr ); } printf("%.2f%%", count * 100.0 / 10000 ); return 0;}
2)概率不稳啊!!!
#include程序输出:#include #include void init( int arr[] ){ int i = 0; for ( i = 0; i < 365; i++ ){ arr[i] = 0; }}void func( int arr[], int num ){ int i = 0; init( arr ); srand( ( unsigned int )time( NULL ) ); for ( i = 0; i < num; i++ ){ arr[ rand() % 365 ]++; }}int isHave( int arr[] ){ int i = 0; for ( i = 0;i < 365; i++ ){ if ( arr[i] > 1 ){ return 1; } } return 0;}int main(void){ int i = 0; int j = 0; int arr[365]; double count = 0; int peopleNum = 0; for ( i = 1; i < 100; i++){ for ( j = 0; j < 10000; j++ ){ func( arr, i ); if ( isHave( arr ) ){ count++; } init( arr ); } if ( count * 100.0 / 10000 >= 50){ peopleNum = i; break; } count = 0; } printf("%d\n", peopleNum ); return 0;}
10.
#include#include void moveArr( int arr[], int len, int maxLen ){ int i = 0; for ( i = maxLen; i > len; i-- ){ arr[i + 1] = arr[i]; }}void insert_sort( int arr[], int value ){ static int maxLen = 0; int i = 0; maxLen++; if ( 1 == maxLen ) { arr[0] = value; return; } for ( i = 0; i < maxLen - 1; i++ ){ if ( arr[i] > value ){ moveArr( arr, i - 1, maxLen - 1 ); arr[i] = value; break; } } if ( i == maxLen - 1 ){ arr[i] = value; }}int main(void){ int arr[11]; //请多分配一个空间,用于移位 int i = 0; for ( i = 0; i < 10; i++ ){ arr[i] = 0; } insert_sort( arr, 1 ); insert_sort( arr, 9 ); insert_sort( arr, 2 ); insert_sort( arr, 8 ); insert_sort( arr, 7 ); insert_sort( arr, 3 ); insert_sort( arr, 4 ); insert_sort( arr, 6 ); insert_sort( arr, 5 ); insert_sort( arr, 0 ); for ( i = 0; i < 10; i++ ){ printf("%d ", arr[i]); } return 0;}
程序输出: