文档章节

C和指针---第十六章:标准函数库

fzyz_sb
 fzyz_sb
发布于 2013/09/23 19:28
字数 2855
阅读 65
收藏 0
点赞 0
评论 0

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 <stdio.h>
#include <stdlib.h>

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 <stdlib.h>
#include <time.h>
#define TRUE	1
#define FALSE	0

void 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 <stdio.h>
#include <time.h>

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 <stdio.h>
#include <time.h>
#include <stdlib.h>

int main(void)
{
	time_t *tt = malloc( sizeof( time_t ) );
	time( tt );

	printf("%d\n", tt );
	free( tt );

	return 0;
}
但是,返回值貌似不太对哦,不同的运行,显示不同的答案.

于是,我对代码进行了修改(书上明显介绍有误,不知道是不是翻译的问题):

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

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 <stdio.h>
#include <time.h>
#include <stdlib.h>

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 <setjmp.h>
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 <stdlib.h>
#include <string.h>

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 <stdlib.h>
#include <string.h>

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 <stdio.h>
#include <stdlib.h>
#include <math.h>

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 <stdio.h>
#include <stdlib.h>
#include <time.h>


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 <stdio.h>
#include <stdlib.h>
#include <time.h>


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 <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

#define A 10.45
#define B 10.00
#define C -1.0
#define X 1.78816

double 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 <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

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 <stdio.h>
#include <stdlib.h>
#include <time.h>

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 <stdio.h>
#include <stdlib.h>
#include <time.h>

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 <stdio.h>
#include <stdlib.h>
#include <time.h>

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 <stdio.h>
#include <stdlib.h>
#include <time.h>

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 <stdio.h>
#include <stdlib.h>

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;
}

程序输出:



© 著作权归作者所有

共有 人打赏支持
fzyz_sb
粉丝 408
博文 209
码字总数 447144
作品 0
武汉
程序员
C++快速入门

只学过Java的我最近笔试接触到各种C++的题目,于是稍微恶补了一下C++的基础部分,以下内容是基于《21天学通C++》的部分读书笔记,按照章节写的。 第二章 C++程序的组成部分 ①#include 预处理...

waffle930
2016/10/02
56
0
[编程语言]C陷阱与缺陷

内容摘要 作者以自己1985年在Bell实验室时发表的一篇论文为基础,结合自己的工作经验扩展成为这本对C程序员具有珍贵价值的经典著作。写作本书的出发点不是要批判C语言,而是要帮助C程序员绕过...

21gprs
2014/05/23
0
0
c++ primer 第五版学习笔记

第二章 函数体外定义的内置类型变量会初始化为0,函数体外的是未初始化的 用constexpr声明变量表示它是一个常量表达式(编译器可以确定的值),且只能应用于字面值 c++11中可以用 来定义一个...

David栗子
2017/12/11
0
0
业余爱好者的C程序设计学习之路

我学习和工作的方向都是化工,和 IT 专业一点边都不搭,属于程序设计爱好者一类。坚持了很多年了,谈谈我的认识。 一、为什么是C 汇编太难,直接下手会吓死宝宝的。 basic 不能考虑,因为“对...

四彩
2016/02/04
107
2
Go1.6 和 Go语言圣经中文版 正式发布!

Go1.6 和 Go语言圣经中文版 正式发布! Go1.6正式版本发布。在 https://golang.org/doc/go1.6 可以预览Go1.6的发布信息。自Go1.5发布以来的重大变化有以下几个: 《Go语言圣经》 面世标志着G...

chai2010
2016/01/27
10K
18
C++ Primer 学习笔记(第三章:字符串、向量和数组)

C++ Primer 学习笔记(第三章:字符串、向量和数组) [TOC] 3.1 命名空间的声明 声明语句可以一行放多条。 位于头文件的代码,一般来说不应该使用声明。因为其内容会拷贝到每个使用该头文件的...

ShawnLue
2015/08/20
0
0
【原创】《深入剖析Tomcat》读书笔记

第一章 一个简单的Web服务器 第二章 一个简单的servlet容器 第三章 连接器 第四章 Tomcat的默认连接器 第五章 servlet容器 第六章 生命周期 第七章 日志记录器 第八章 载入器 第九章 Sessio...

pandudu
2015/12/22
46
0
《Beginning Linux Programming》读书笔记(四)

1, 读写空指针 先看第一种情况,printf试图访问空指针,以打印出字符串,而sprintf试图向空指针写入字符串,这时,linux会在GNU C函数库的帮助下,允许读空指针,但不允许写空指针。 复制代...

嗯哼9925
01/08
0
0
《C++程序设计语言(特别版)》忠告(advice)部分

《C++程序设计语言(特别版)》忠告(advice)部分 Bjarne Stroustrup 裘宗燕 译 _ 这里是一组在你学习C++的过程中或许应该考虑的“规则”。随着你变得更加熟练,你将能把它转化为某种更适合你的...

晨曦之光
2012/03/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

高效编写Dockerfile的几条准则

概述 Dockerfile 是专门用来进行自动化构建镜像的编排文件(就像Jenkins 2.0时代的Jenkinsfile是对Jenkins的Job和Stage的编排一样),我们可以通过 docker build 命令来自动化地从 Dockerfi...

小致dad
35分钟前
0
0
SpringBoot | 第十章:Swagger2的集成和使用

前言 前一章节介绍了mybatisPlus的集成和简单使用,本章节开始接着上一章节的用户表,进行Swagger2的集成。现在都奉行前后端分离开发和微服务大行其道,分微服务及前后端分离后,前后端开发的...

oKong
今天
9
0
Python 最小二乘法 拟合 二次曲线

Python 二次拟合 随机生成数据,并且加上噪声干扰 构造需要拟合的函数形式,使用最小二乘法进行拟合 输出拟合后的参数 将拟合后的函数与原始数据绘图后进行对比 import numpy as npimport...

阿豪boy
今天
7
0
云拿 无人便利店

附近(上海市-航南路)开了家无人便利店.特意进去体验了一下.下面把自己看到的跟大家分享下. 经得现场工作人员同意后拍了几张照片.从外面看是这样.店门口的指导里强调:不要一次扫码多个人进入....

周翔
昨天
1
0
Java设计模式学习之工厂模式

在Java(或者叫做面向对象语言)的世界中,工厂模式被广泛应用于项目中,也许你并没有听说过,不过也许你已经在使用了。 简单来说,工厂模式的出现源于增加程序序的可扩展性,降低耦合度。之...

路小磊
昨天
194
1
npm profile 新功能介绍

转载地址 npm profile 新功能介绍 npm新版本新推来一个功能,npm profile,这个可以更改自己简介信息的命令,以后可以不用去登录网站来修改自己的简介了 具体的这个功能的支持大概是在6这个版...

durban
昨天
1
0
Serial2Ethernet Bi-redirection

Serial Tool Serial Tool is a utility for developing serial communications, custom protocols or device testing. You can set up bytes to send accordingly to your protocol and save......

zungyiu
昨天
1
0
python里求解物理学上的双弹簧质能系统

物理的模型如下: 在这个系统里有两个物体,它们的质量分别是m1和m2,被两个弹簧连接在一起,伸缩系统为k1和k2,左端固定。假定没有外力时,两个弹簧的长度为L1和L2。 由于两物体有重力,那么...

wangxuwei
昨天
0
0
apolloxlua 介绍

##项目介绍 apolloxlua 目前支持javascript到lua的翻译。可以在openresty和luajit里使用。这个工具分为两种模式, 一种是web模式,可以通过网页使用。另外一种是tool模式, 通常作为大规模翻...

钟元OSS
昨天
2
0
Mybatis入门

简介: 定义:Mybatis是一个支持普通SQL查询、存储过程和高级映射的持久层框架。 途径:MyBatis通过XML文件或者注解的形式配置映射,实现数据库查询。 特性:动态SQL语句。 文件结构:Mybat...

霍淇滨
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部