
Char 8 -128~127
Unchar 8 0~255
(signed)int 16 -32768~32767
(signed)short 16 -32768~32767
(signed)long 32 -21474838~21474837
(unsigned)int 16 0~65535
(unsigned)short 16 0~65535
(unsigned)long 32 0~4294967295
Float 32 3.4e-38~3.4e38
Double 1.7e-308~1.7e308
指针的数据类型
定义 含义
Int i; 定义整型变量i。
Int *p; p为指向整型数据的指针变量。
Int a[n] ; 定义含n个元素的整型数组a。
Int *p[n]; n个指向整型数据的指针变量组成的指针数组P。
Int (*p)[n];p为指向含n个元素的一维整型数组的指针变量。
Int f();f为返回整型数的函数。
Int *p();p为返回指针的函数,该指针指向一个整型数据。
Int(*p)();p为指向函数的指针变量,该函数返回整型数。
Int**P; p为指针变量,它指向一个指向整型数据的指针变量。
例 下列定义的含义
int *p[3]; 指针数组。
Int (*p)[3];指向一维数组的指针。
Int *p(int);返回指针的函数。
Int (*p)(int);指向函数的指针,函数返回int型指针。
Int *(*p)(int);函数指针数组,函数返回int型变量。
Int (*p[3])(int);函数指针数组,函数返回int 型变量。
Int *(*p[3])(int);函数指针数组,函数返回int型指针。
1.1 宏定义(1)
宏定义
–普通宏
#define PI (3.1415926)
–带参数的宏
#define max(a,b) ((a)>(b)?(a),(b))
–取消定义
#undefMacroName
为什么要用宏定义
–维护性:有时我们需要将某个特定数据(如某个数据表的大小)在程序中出现的所有实例统统加以修改,我们希望能够只做一个改动就达到目的
#define MAXSIZE 100
–在函数调用的时候会带来重大的系统开销,因此我们有时希望有一个程序块,看上去像一个函数,但却没有函数调用的开销
#define max( a,b) (((a)>=(b))?(a):(b))
–提高程序的易读性:文字比数字要容易理解多,一个好的宏名可以顾名思义。
1.1 宏定义(2)
宏定义的特点
–宏定义值使用宏名代替一个字符串,不做语法检查
–对程序中用双括号括起来的字符串内部的字符,即使与宏名相同,也不进行替换
函数调用和宏定义的区别
–函数调用时,先求出实参表达式的值,然后代入形参。而使用带参数的宏只是进行简单的字符替换
–对于函数调用,对实参要进行类型检查,如果实参与形参类型不一致,应进行类型转换,如果无法转换,编译时会出错。但是宏定义不会做类型检查
宏定义和类型定义的区别
–宏定义不做语法检查,可以把任何字符串定义成类型
#define A integer /* integer不是一个合法的类型*/
–使用宏定义结果有时与预期的不同
#define T1 structstudent*
Typedefstructstudent *T2 ;
T1 a, b; /*相当于structstudent* a, b,b不是结构体指针,与预期的不同*/
T2 a, b;
1.1 宏定义(3)
使用宏定义需要注意
–不要忽视宏定义中的空格
#define f (x) (x) +1// 实际上是把f 定义成了(x) (x)+1
–对于不带参数的宏,若宏值多于一项,一定要使用括号
•#define MAX (M+N)
–要给每个参数加上括号,否则可能会影响计算的优先级
#define abs(x) (x>=0)?x:-x
z =abs(a+b); /*相当于z= (a+b>=0)?a+b:-a+b
//修改后
#define abs(x) ((x)>=0?(x): -(x)
–尽量用typedef而不是宏定义去定义类型
1.2 条件编译
条件编译例子
#ifdefBMW
#define SIZE 16
#else
#define SIZE 32
#endif
条件编译指令
–#ifdef…#else …#endif
–#ifndef…#else …#endif
–#if 1 …#else …#endif
–#if 0 …#else …#endif
条件编译的应用
–解决头文件重复包含的问题
–在调试时,用条件编译的方式将debug语句加入;
–在修改Bug时候,用条件编译方式引入新的修正,并保留原来的程序;
1.3 文件包含
头文件包含
–#include “xxxx.h”
–含义是在编译时将头文件的内容加入到包含文件中。
头文件包含的方式
–#include “xxxx.h”
•到本级目录去找。
–#include •到系统默认目录和本级目录去找。 重复包含(重复定义) –由于头文件包含可以嵌套,那么C文件就有可能包含多次同一个头文件,就可能出现重复定义的问题的 –通过条件编译开关来避免重复包含(重复定义) •例如 #ifndef__headerfileXXX__ #define __headerfileXXX__ … 文件内容 … #endif 2.1位操作(1) 基本位操作符 –<<,>> –如(0x01) << 4 =0x10; (0x80)>> 4 = 0x08 位操作应用举例 –乘法、除法,例如a*8可以写成a<<3; –地址计算,例如一个32位的地址装在元素类型是char的数组a[4]中(假设按照从低到高存放),那么计算这个地址的方法为((a[3]<<24)|(a[2]<<16)|(a[1]<<8)|a[0] 容易出现的问题 –尽量使用无符号变量,避免产生符号错误; –注意避免发生数据溢出; 2.1位操作(2) 位运算符例子分析 请分析下面问题的含义。 #define unsigned charUINT1 #define unsigned shortUINT2 #define unsigned longUINT4 问题1: #defineMC_GET_CHAR(__data__)\ (*((UINT1*)(__data__))) 问题2: #define MC_GET_SHORT(__data__) \ ((UINT2)((((UINT2)(*((UINT1*)(__data__))))<<8 )\ |((UINT2)(*((UINT1*)(__data__)+1)))&0x00ff)))Neusoft Group Ltd. Date: 2006年4月4日星期二 2.1位操作(3) 问题3: #defineMC_GET_LONG(__data__)\ ((((UINT4)MC_GET_SHORT((__data__)))<<16 )\ |(((UINT4)MC_GET_SHORT(__data__+2))&0x0000ffff)) 问题4: #define MC_GET_3BN(__data__)\ ((((UINT4)MC_GET_CHAR((__data__)))<<16 )\ |(((UINT4)MC_GET_SHORT(__data__+1))&0x0000ffff)) C语言常用库函数 •math.h •stdio.h •stdlib.h •malloc.h •string.h •assert.h 动态存储分配(malloc.h) •函数名: malloc 功能: 内存分配函数 用法: void *malloc(unsigned size); 程序例: #include •#include #include void main( void ) { char *string; /* Allocate space for a path name */ string = malloc( _MAX_PATH ); if( string == NULL ) printf( "Insufficient memory available\\n" ); else{ printf( "Memory space allocated for path name\\n" ); free( string ); printf( "Memory freed\\n" ); } } 动态存储分配(malloc.h) •函数名: free 功能: 释放已分配的块 用法: void free(void *ptr); 程序例: #include #include #include int main(void) { char *str; /* allocate memory for string */ str = malloc(10); /* copy "Hello" to string */ strcpy(str, "Hello"); /* display string */ printf("String is %s\\n", str); /* free memory */ free(str); return 0; } 动态存储分配(malloc.h) •函数名: realloc 功能:改变已分配内存的大小,ptr为已分配有内存区域的指针,newsize为新的长度,返回分配好的内存指针; 用法: void *realloc(void *ptr,unsigned newsize) 程序例: #include #include #include void main( void ) { long *buffer; size_t size; if( (buffer = (long *)malloc( 1000 * sizeof( long ) )) == NULL ) exit( 1 ); size = _msize( buffer ); printf( "Size of block after malloc of 1000 longs: %u\\n", size ); /* Reallocate and show new size: */ if( (buffer = realloc( buffer, size + (1000 * sizeof( long )) ))== NULL ) exit( 1 ); size = _msize( buffer ); printf( "Size of block after realloc of 1000 more longs: %u\\n", size ); free( buffer ); exit( 0 ); } 动态存储分配(malloc.h) •函数名:calloc 功能:分配nelem个长度为elsize的内存空间并返回所分配内存的指针; 用法: void *calloc( size_t numsize); , size_t 程序例: #include #include void main( void ) { long *buffer; buffer = (long *)calloc( 40, sizeof( long ) ); if( buffer != NULL ) printf( "Allocated 40 long integers\\n" ); else printf( "Can't allocate memory\\n" ); free( buffer ); } 类型转换函数(stdlib.h) •函数名: atof 功能: 把字符串转换成双精度数,并返回这个数,错误返回0; 用法: double atof(const char *nptr); 程序例: #include #include int main(void) { float f; char *str = "12345.67"; f = atof(str); printf("string = %s float = %f\\n", str, f); return 0; } 类型转换函数(stdlib.h) •函数名: atoi 功能: 把字符串转换成整型数,并返回这个数,错误返回0; 用法: int atoi(const char *nptr); 程序例: #include #include int main(void) { int n; char *str = "12345.67"; n = atoi(str); printf("string = %s integer = %d\\n", str, n); return 0; } 类型转换函数(stdlib.h) •函数名: atol 功能: 把字符串转换成长整型数,并返回这个数,错误返回0; 用法: long atol(const char *nptr); 程序例: #include #include int main(void) { long l; char *str = "98765432"; l = atol(lstr); printf("string = %s integer = %ld\\n", str, l); return(0); } 随机数函数(stdlib.h) •函数名: srand 功能: 初始化随机数发生器 用法: void srand(unsigned seed); 程序例: #include #include #include int main(void) { int i; time_t t; srand((unsigned) time(&t)); printf("Ten random numbers from 0 to 99\\n\\n"); for(i=0; i<10; i++) printf("%d\\n", rand() % 100); return 0; } 随机数函数(stdlib.h) •函数名: rand 功能: 随机数发生器 用法: void rand(void); 输入输出函数(stdio.h) •函数名: fopen 功能:打开用filename指定的文件,并使其与一个流相联。 用法: FILE *fopen(const char *filename,const char *mode) 使用方式:文件指针名=fopen("文件名处理方式") "处理方式"取: "rt"打开一个文本文件,只能读。 "wt"生成一个文本文件,只能写。若文件存在则被重写。 "at"打开一个文本文件,只能在文件尾部添加。 "rb"打开一个二进制文件,只能读。 "wb"生成一个二进制文件,只能写。 "ab"打开一个二进制文件,只能在文件尾部添加。 "rt+"打开一个文本文件,可读可写。 "wt+"生成一个文本文件,可读可写。 "at+"打开一个文本文件,可读可添加。 "rb+"打开一个二进制文件,可读可写。 "wb+"生成一个二进制文件,可读可写。 "ab+"打开一个二进制文件,可读可添加。 返回值:指明流的指针(成功时)或NULL(失败时) 注:需先定义FILE *文件指针名; "文件名"若用argv[1]代替,则可使用命令行形式指定文件名 输入输出函数(stdio.h) •函数名: fclose 功能: 关闭一个流 用法: int fclose(FILE *stream); 程序例: #include #include int main(void) { FILE *fp; char buf[11] = "01234567"; /* create a file containing 10 bytes */ fp = fopen("DUMMY.FIL", "w"); fwrite(&buf, strlen(buf), 1, fp); /* close the file */ fclose(fp); return 0; } 输入输出函数(stdio.h) •函数名: fread 功能: 从一个流中读数据 用法: int fread(void *ptr, int size, int nitems, FILE *stream); 程序例: #include #include int main(void) { FILE *stream; char msg[] = "this is a test"; char buf[20]; if ((stream = fopen("DUMMY.FIL", "w+"))== NULL) { fprintf(stderr,"Cannot open output file.\\n"); return 1; } /* write some data to the file */ fwrite(msg, strlen(msg)+1, 1, stream); /* seek to the beginning of the file */ fseek(stream, SEEK_SET, 0); /* read the data and display it */ fread(buf, strlen(msg)+1, 1, stream); printf("%s\\n", buf); fclose(stream); return 0; } 输入输出函数(stdio.h) •函数名: fseek 功能: 重定位流上的文件指针 用法: int fseek(FILE *stream,long offset,int fromwhere); 程序例: #include long filesize(FILE *stream); int main(void) { FILE *stream; stream = fopen("MYFILE.TXT", "w+"); fprintf(stream, "This is a test"); printf("Filesize of MYFILE.TXT is %ld bytes\\n", filesize(stream)); fclose(stream); return 0; } 输入输出函数(stdio.h) •函数名: fwrite 功能: 写内容到流中 用法: int fwrite(void *ptr, int size, int nitems, FILE *stream); 输入输出函数(stdio.h) •函数名: sprintf 功能: 送格式化输出到字符串中 用法: int sprintf(char *string, char *farmat [,argument,...]); 程序例: #include #include int main(void) { char buffer[80]; sprintf(buffer, "An approximation of Pi is %f\\n", M_PI); puts(buffer); return 0; } 存储数组操作函数(memory.h) •函数名: memcpy 功能: 从源source中拷贝n个字节到目标destin中 用法: void *memcpy(void *destin, void *source, unsigned n); 程序例: #include #include #include int main(void) { char src[] = "******************************"; char dest[] = "abcdefghijlkmnopqrstuvwxyz0123456709"; char *ptr; printf("destination before memcpy: %s\\n", dest); ptr = memcpy(dest, src, strlen(src)); if (ptr) printf("destination after memcpy: %s\\n", dest); else printf("memcpy failed\\n"); return 0; } 存储数组操作函数(memory.h) •函数名: memset 功能: 设置s中的所有字节为ch, s数组的大小由n给定 用法: void *memset(void *s, char ch, unsigned n); 程序例: #include #include #include int main(void) { char buffer[] = "Hello world\\n"; printf("Buffer before memset: %s\\n", buffer); memset(buffer, '*', strlen(buffer) -1); printf("Buffer after memset: %s\\n", buffer); return 0; } 存储数组操作函数(memory.h) •函数名: memcmp 功能:比较正好是n字节长的两个字符串s1和s2; 用法: int memcmp( const void *buf1, const void *buf2, size_t count); 程序例: #include #include void main( void ) { char first[] = "1234567012345670"; char second[] = "1234567012345671"; int result; result = memcmp( first, second, 19 ); if( result < 0 ) printf( "First is less than second.\\n" ); else if( result == 0 ) printf( "First is equal to second.\\n" ); else if( result > 0 ) printf( "First is greater than second.\\n" ); result = memcmp( first, second, 20 ); if( result < 0 ) printf( "First is less than second.\\n" ); else if( result == 0 ) printf( "First is equal to second.\\n" ); else if( result > 0 ) printf( "First is greater than second.\\n" ); } 字符串函数(string.h) •函数名: strcpy 功能: 拷贝一个字符串到另一个 用法: char *strcpy(char*destin, char *source); 程序例: #include #include int main(void) { char string[10]; char *str1 = "abcdefghi"; strcpy(string, str1); printf("%s\\n", string); return 0; } 字符串函数(string.h) •函数名: strcat 功能: 字符串拼接函数 用法: char *strcat(char *destin, char *source); 程序例: #include #include int main(void) { char destination[25]; char *blank = " ", *c = "C++", *Borland = "Borland"; strcpy(destination, Borland); strcat(destination, blank); strcat(destination, c); printf("%s\\n", destination); return 0; } 字符串函数(string.h) •函数名: strcmp 功能: 串比较 用法: int strcmp(char *str1, char *str2); 程序例: #include #include int main(void) { char *buf1 = "aaa", *buf2 = "bbb", *buf3 = "ccc"; int ptr; ptr = strcmp(buf2, buf1); if (ptr > 0) printf("buffer 2 is greater than buffer 1\\n"); else printf("buffer 2 is less than buffer 1\\n"); ptr = strcmp(buf2, buf3); if (ptr > 0) printf("buffer 2 is greater than buffer 3\\n"); else printf("buffer 2 is less than buffer 3\\n"); return 0; } 字符串函数(string.h) •函数名: strcpy 功能: 串拷贝 用法: char *strcpy(char *str1, char *str2); 程序例: #include #include int main(void) { char string[10]; char *str1 = "abcdefghi"; strcpy(string, str1); printf("%s\\n", string); return 0; } 数学函数(math.h) •函数名:abs •功能:求整数的绝对值 •用法:int abs(int i) •程序例: •#include #include int main(void) { int number = -1234; printf("number: %d absolute value: %d\\n",number, abs(number)); return 0; } 数学函数(math.h) •函数名: acos 功能: 反余弦函数 用法: double acos(double x); 程序例: #include #include int main(void) { double result; double x = 0.5; result = acos(x); printf("The arc cosine of %lf is %lf\\n", x, result); return 0; } 数学函数(math.h) •函数名: asin 功能: 反正弦函数 用法: double asin(double x); 程序例: #include #include int main(void) { double result; double x = 0.5; result = asin(x); printf("The arc sin of %lf is %lf\\n", x, result); return(0); } 数学函数(math.h) •函数名: atan 功能: 反正切函数 用法: double atan(double x); 程序例: #include #include int main(void) { double result; double x = 0.5; result = atan(x); printf("The arc tangent of %lf is %lf\\n",x,result); return(0); } 数学函数(math.h) •函数名: atan2 功能: 计算Y/X的反正切值 用法: double atan2(double y, double x); 程序例: #include #include int main(void) { double result; double x = 90.0, y = 45.0; result = atan2(y,x); printf("The arc tangent ratio of %lf is %lf\\n",(y/ x),result); return 0; } 数学函数(math.h) •函数名: fmod 功能: 计算x对y的模, 即x/y的余数 用法: double fmod(double x, double y); 程序例: #include #include int main(void) { double x = 5.0, y = 2.0; double result; result = fmod(x,y); printf("The remainder of (%lf / %lf) is %lf\\n", x, y, result); return 0; } 数学函数(math.h) •函数名: sqrt 功能: 计算平方根 用法: double sqrt(double x); 程序例: #include #include int main(void) { double x = 4.0, result; result = sqrt(x); printf("The square root of %lf is %lf\\n",x,result); return 0; } 诊断函数(assert.h) •函数名: assert 功能: 测试一个条件并可能使程序终止 用法: void assert(int test); 程序例: #include #include #include struct ITEM { int key; int value; }; void additem(struct ITEM *itemptr) { assert(itemptr != NULL); } int main(void) { additem(NULL); return 0; }
