博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C和指针---第十六章:标准函数库
阅读量:6458 次
发布时间:2019-06-23

本文共 11517 字,大约阅读时间需要 38 分钟。

  hot3.png

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来获得随机数.
#include 
#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; }}
16.1.3 字符串转换<stdlib.h>
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 
int setjmp( jmp_buf state );void longjmp( jump_buf state, int value );
你声明一个jmp_buf变量,并调用setjmp函数对它进行初始化,setjmp的返回值为0.setjmp把程序的状态信息保存到跳转缓冲区.你调用setjmp时所处的函数便成为你的"顶层"函数.

以后,在顶层函数或其他任何它所调用的函数内的任何地方调用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 * ) );
#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]; qsort( array, 50, sizeof( Record ), r_compare ); return EXIT_SUCCESS;}
bsearch用于二叉树查找:
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;}

程序输出:

转载于:https://my.oschina.net/voler/blog/163658

你可能感兴趣的文章
noj 2033 一页书的书 [ dp + 组合数 ]
查看>>
ERDAS软件应用(四)遥感影像数据增强
查看>>
修改OBS为仅直播音频
查看>>
完整版:《开源框架实战宝典电子书V1.0.0》内测版下载地址!
查看>>
OCP读书笔记(14) - 管理数据库性能
查看>>
OCA读书笔记(3) - 使用DBCA创建Oracle数据库
查看>>
CKEditor的使用-编辑文本
查看>>
洗礼灵魂,修炼python(40)--面向对象编程(10)—定制魔法方法+time模块
查看>>
HDU------checksum
查看>>
使用树莓派拍摄延时动画,制作GIF图
查看>>
css命名规范
查看>>
js 效果
查看>>
19.Java5同步集合类的应用
查看>>
python 关键字yield解析
查看>>
<c:forEach varStatus="status">中 varStatus的作用
查看>>
Aqua Data Studio 数据库开发工具
查看>>
puppet来管理文件和软件包
查看>>
【转载】基于lucene的搜索方案
查看>>
Python基础进阶之路(一)之运算符和输入输出
查看>>
阻塞非阻塞异步同步 io的关系
查看>>