11.19
复习:
常见笔试面试题:
1.堆内存与栈内存的区别
是什么,有什么用,优缺点,注意事项
谁管理,大小,使用,安全性
2.堆内存越界的后果
脏数据
超过33页产生段错误
破坏malloc的维护信息,影响下一次的malloc,free
3.什么是内存泄漏,如何定位内存泄漏
由于程序的业务逻辑问题或者粗心大意导致使用完毕的内存没有释放,当再次需要时又重新申请,又继续没释放,
长期如此导致可用的内存越来越少,系统越来越慢甚至系统崩溃,这种情况叫做内存泄漏
1.windows查看任务管理器,linux通过ps命令,可以通过GDB调式查看内存使用情况
2.借助mtrace工具分析malloc,free代码使用情况
3.封装malloc,free,记录调用情况
4.什么是内存碎片,如何减少内存碎片?
已经释放,但又无法使用的内存,由于申请,释放时间和大小不协调导致
1.尽量使用栈内存
2.申请大块内存,自己管理
3.不要频繁申请,释放堆内存
---------------------------------------------------------------------------------------------------------------
字符串
字符:
字符就是符号或图案,在计算机中以整形形式存储的,需要显示时会根据ASCII码表中的对应关系,来显示出相应的图案或符号
'\0' 0
'0' 48
'A' 65
'a' 97
%c %hhd
char ch;
字符的输入:
scanf("%c",&ch)
ch = getchar()
字符的输出:
printf("%c",ch);
putchar(ch);
串:
是一种数据结构,由一组连续的若干个相同类型的数据组成,对这种数据结构的处理都是批量性的,在末尾有一个结束标志,处理从开头到结束标志为止
字符串:
由字符组成的串型结构,结束标志是'\0'
字符串的输入:
scanf %s 地址
不能接收空格,自动在输入结束后末尾加'\0'
char *gets(char *s);
功能:输入字符串,并且可以接受空格
返回值:链式调用(一个函数的返回值,作为另一个函数的参数)
char *fgets(char *s, int size, FILE *stream);
功能:可以设置输入的字符串的长度为size-1,超出的部分不接收,会给'\0'预留位置
stream:键盘文件:标准输入 stdin
注意:输入的长度不足size-1时,会把最后的\n一并接受
返回值:链式调用
字符串的输出:
printf %s 地址
int puts(const char *s);
功能:输出一个字符串,并且在打印完后自动再打印一个换行
返回值:成功输出的字符个数
字符串的存在方式:
字符数组:char str[10] = {'a','b','c'};
由char字符类型组成的数组,要注意为'\0'预留位置
初始化不方便
使用的是栈内存,数据可以修改
字符串字面值:
"由双引号包含的若干个字符",会在末尾隐藏一个'\0'
字符串字面值以地址形式存在,数据存储在代码段中,如果修改会产生段错误,相当于常量
sizeof("xixi") 计算字符串字面值中所有字符的个数,包括'\0'
const char* p = "字符串字面值";
sizeof(p) 永远是4|8
注意:相同的字符串字面值,在代码段中只存在一份
常用方式:
字符数组[] = 字符串字面值;
自动为'\0'预留位置
赋值完成后,字符串就存在两份,一份在代码段,一份在栈内存(可修改)
练习1:实现一个判断是否是回文串的函数
abccba abcba
#include <stdio.h>
int pd(const char* arr)
{
size_t len = 0;
while(arr[len]) len++;
for (int i=0;i<len/2;i++)
{
if (arr[i] != arr[len-i-1])
return 0;
}
return 1;
}
int main(int argc,const char* argv[])
{
char arr[256] = {};
scanf ("%s",arr);
printf ("%s",pd(arr)?"YES":"NO");
//printf ("%d\n",ret);
//printf ("%c",arr[0]);
}
练习2:实现一个函数把一个由数字字符组成的字符串转换成整数值
#include <stdio.h>
int str_to_int(const char* arr)
{
int num = 0;
while(*arr)
{
num = num*10 + *arr - '0';
arr++;
}
return num;
}
int main(int argc,const char* argv[])
{
char arr[256] = {};
int a=0;
scanf ("%s",arr);
printf ("%d",str_to_int(arr));
}
练习3:实现一个函数把字符串逆序
abcd dcba
#include <stdio.h>
int main(int argc,const char* argv[])
{
int temp = 0;
char arr[256] = {},cnt=0;
fgets(arr,256,stdin);
for (cnt=0;arr[cnt]!='\0';cnt++);
for (int i=0;i<=(cnt-1)/2;i++)
{
temp = arr[i];
arr[i] = arr[cnt-i-1];
arr[cnt-i-1] = temp;
}
puts(arr);
// printf ("%d",cnt);
}
输出缓冲区:
程序并不会把要输出的数据立即显示到屏幕上,而是先存储在输出缓冲区中,需要满足一定的条件才能显示出来。
缓冲区机制可以提高数据的读写速度, 另一方面可以让高速的cpu与低速的输入输出设备之间协调工作。
刷新输出缓冲区的条件:
1.遇到'\n' printf("---------\n")
2.遇到输入语句,函数
3.当输出缓冲区满4kb时
4.当程序结束时
5.手动刷新 fflush(stdout)