之后,必须用free释放内存,否则,就会产生内存泄漏,每次释放内存后,虽然不再占用着这块内存中,但是对应的指针依然指向这块区域,这个指针就是野指针,所以释放内存后,建议给指针赋NULL。如下:
int main(){
? int *p = (int*)malloc(100*sizeof(int));?
? /*
? ? 执行语句?
? */?
? free(p);//这时p依然指向那块内存,成了野指针
? p = NULL;? //对p赋值NULL
? return 0;?
}
3、C语言的I/O输入输出
C语言本身并不带有输入输出的特性,所以它的所有I/O操作都是通过系统调用来实现。幸运的是C标准库,已经给我们封装好了一系列的I/O操作的函数。
putchar ():把变量中的一个字符常量输出到显示器屏幕上;
getchar ();从键盘上输入一个字符常量,此常量就是该函数的值;
printf ();把键盘中的各类数据,加以格式控制输出到显示器屏幕上;
scanf? ();从键盘上输入各类数据,并存放到程序变量中;
puts? ? ():把数组变量中的一个字符串常量输出到显示器屏幕上
gets? ? ():从键盘上输入一个字符串常量并放到程序的数组中
一些为对文件的操作,由于一切皆可看作是文件,标准输入,输出也可以当作文件来操作,文件描述符:标准输入(0)、标准输出(1)、标准错误(2)
fputs();输出到文件
fgets();从文件输入
fscanf();格式化文件输入
fprintf();格式化文件输出
另外两个很重要的函数,当然还有他们的派生函数也是类似的
sscanf(); 从一个字符串中提取各类数据。
sprintf(); 把格式化的数据写入某个字符串
这里不对每个函数进行详解,主要对格式化函数进行分析:
(1)当我们要把一个字符串转换成一个整数或者把一个整数转换成一个字符串时,我们一般会想到atoi()或者itoa()(非标准函数),但是我们可以通过流来实现:
int main(){
? ? int num = 10;
? ? char str[10] = {0};
? ? sprintf(str,"%d",num); //把int转换成char[]
? ? num = 0;
? ? sscanf(str,"%d",&num);//把字符串转换成int
? ? printf("num:%d str:%s\n",num,str);
? ? return 0;
}
输出结果如下:

把字符串转与其它类型之间的转换:比如float,16进制,unsigned等都可以用流实现。
(2)格式化函数中的正则表达式
所有的格式化函数都可以定制自己的扫描集 %[abc]、%[a-z]、%[^abc]、%[^a-z],其中[]内是匹配的字符,^表示求反集。
当我们要从标准输入输入一个可能带空格的字符串时,直接用scanf("%s",str);当读到空格时就返回,此时就可以使用正则表达式:
char str[100] = {0};
scanf("%[^\n]",str);//直到遇到回车才写入
从标准输入中只要读小写字母a-z,遇到其它字符则返回:
char str[100] = {0};
scanf("%[a-z]",str);
其他格式化函数的用法相同,不一???举例。
4、总结
从大一开始学习C语言也有四五年了,个人认为:C语言中最大的成功在于它的指针,但是也是最容易出错的,想要理解C,必须要掌握指针。虽然说,语言只是一门工具,但是这是基础。或许,你可以说,现在是JAVA的天下了,满大街都是招聘JAVA工程师;或者你可以说C太底层,现在都是OOP的时代了,谁还会用面向过程的......你们不要忘了操作系统是用什么写的?是C;C实现的nginx的并发量是C++实现的apache的几十倍。无论是什么编程语言,好好学,深入学就行,不要因为它今天流行就抛弃昨天所学的。