学习Linux C编程 笔试训练(二)

linux中 文件属性以 l、b、c、d。开头的都是什么文件?
l是链接,相当于windows的快捷方式
d是目录,相当于windows的文件夹
c是字符设备文件,给你说你不懂,鼠标,键盘算是
b是块设备,硬盘就是一个例子
 
/etc/services : 定义网络服务的端口
 
linux中 UID PID PPID 分别是什么?
UID是用户ID,
PID是进程ID,
PPID是父进程ID。
 
程序kill -9与kill -15的区别
 
在Linux/unix下,中止一个Java进程有两种方式,一种是kill -9 pid,一种是kill -15 pill(默认)。
两种方式的区别是:
SIGNKILL(9) 的效果是立即杀死进程. 该信号不能被阻塞, 处理和忽略。
SIGNTERM(15) 的效果是正常退出进程,退出前可以被阻塞或回调处理。并且它是Linux缺省的程序中断信号。
 
内存分配方式有几种?
静态存储区 栈 堆 的内存分配
1,从静态存储区域分配内存。(全局变量 static)程序编译的时候内存已经分配好了,并且在程序的整个运行期间都存在,例如全局变量。
2,在栈上创建。在执行函数时,函数内局部变量的存储单元可以在栈上创建,函数结束时这些存储单元自动被释放。
处理器的指定集中有关于栈内存的分配运算,因此效率比较高,但是分配的内存容量有限。
3,在堆上分配内存,亦称动态内存分配,程序在运行的时候用malloc函数或new运算符申请任意大小的内存,程序员要用free函数或delete运算符释放内存。动态内存使用非常灵活,但问题也很多。
 
常见的错误      
类型 1:内存未分配成功,却使用了它。
方   法:在使用之前检查指针是否为NULL。
             1)当指针p是函数的参数时,在函数入口处用语句assert(p!=NULL)进行断言检查。
             2)当使用malloc或new来申请内存时,应该用if(p != NULL)进行防错检查。
类型 2:引用了尚未初始化的指针
原   因:内存的缺省初始值究竟是什么并没有统一的标准,在使用之前都进行初始化。
              1)没有初始化的观念。
              2)内存的缺省值是未定义,即垃圾值。
类型 3:越界操作内存
原   因:内存分配成功且初始了,但越界操作是不允许的。
例   如:在使用数组时经常发生下标“多1”或“少1”,特别是在for循环语句时。
类型 4:忘记释放内存,造成内存泄漏。
原   因:含有这种类型错误的函数,每被调用一次,就丢失一块内存。当内存充足时看不到这种错误带来的影响,当内存耗尽时系统提示:“内存耗尽”。因此,动态内存的申请与释放必须配对,程序中malloc与free的使用次数要相同。
类型 5:释放了内存却继续使用它
原   因:对应的情况有2种
              1)返回了“栈内存的指针或引用”,因为堆栈中的变量在函数结束后自动销毁。
              2)某块内存被free后,没有将指向该内存的指针设置为NULL,导致产生“野指针”
 
野指针
       概念:“野指针”不是NULL指针,是指指向“垃圾”内存的指针。即指针指向的内容是不确定的。
指向不确定地址的指针变量
访问了没有权限的内存
访问了已经释放了的内存
       产生的原因:1)指针变量没有初始化。因此,创建指针变量时,该变量要被置为NULL或者指向合法的内存单元。
                      2)指针p被free之后,没有置为NULL,让人误以为p是个合法的指针。
                     3)指针跨越合法范围操作。不要返回指向栈内存的指针或引用
例子1-1:引用尚未初始化的指针
[cpp] view plain copy
char *p;  
*p = 'A';//error,p指向未定义  
例子1-2:return语句返回指向“栈内存”的指针
[cpp] view plain copy
char *GetString1(void)  
{  
    char p[] = "hello world!";  
    //p在栈区,常量字符串在常量字符区  
  
    return p;//error,返回栈内存的地址  
}  
例子1-3:使用了被释放的内存
[cpp] view plain copy
char *pstr = (char *)malloc(sizeof(char)*100);  
free(pstr); //pstr所指的内存被释放  
if (NULL !=pstr)//没起到作用  
{  
    strcpy(pstr,"string!");//error,有时候程序不会提示有误,但还是不允许  
}  
注意:free()释放的是指针指向的内存!不是指针变量!这点非常非常重要!指针是一个变量,只有程序结束时才被销毁。释放了内存空间后,原来指向这块空间的指针还是存在!只不过现在指针指向的内容的垃圾,是未定义的,所以说是垃圾。因此,前面我已经说过了,释放内存后把指针指向NULL,防止指针在后面不小心又被解引用。
对比下面的例子,加深理解
例子1-4:函数返回值传递动态内存
[cpp] view plain copy
char* GetMemory(int num)  
{  
    char *p = (char *)malloc(sizeof(char) * num);  
    return p ;//ok,返回堆区的地址值  
}  
例子1-5:
[cpp] view plain copy
char *GetString(void)  
{  
    char *p = "hello world!";  
    //指针变量p在栈区,指向文字常量区的字符  
  
    return p;//ok,返回字符串的地址  
}  
 
避免的方法:
1.使用前对其初始化(置为null;用malloc分配内存,访问合法内存)
2.指针用完后记得释放内存(置为null, 用malloc的用free , 用memset清零内存)
 
写bool , float,  指针变量 与“零值”比较的if语句。
布尔变量与零值比较 
l 【规则4-3-1】不可将布尔变量直接与TRUE、FALSE或者1、0进行比较。 
根据布尔类型的语义,零值为“假”(记为FALSE),任何非零值都是“真”(记为TRUE)。TRUE的值究竟是什么并没有统一的标准。例如Visual   C++   将TRUE定义为1,而Visual   Basic则将TRUE定义为-1。 
假设布尔变量名字为flag,它与零值比较的标准if语句如下: 
if   (flag) //   表示flag为真 
if   (!flag) //   表示flag为假 
其它的用法都属于不良风格,例如: 
if   (flag   ==   TRUE) 
if   (flag   ==   1   ) 
if   (flag   ==   FALSE)       
if   (flag   ==   0) 


4.3.2   整型变量与零值比较 
l 【规则4-3-2】应当将整型变量用“==”或“!=”直接与0比较。 
假设整型变量的名字为value,它与零值比较的标准if语句如下: 
if   (value   ==   0)       
if   (value   !=   0) 
不可模仿布尔变量的风格而写成 
if   (value) //   会让人误解   value是布尔变量 
if   (!value)    


4.3.3   浮点变量与零值比较 
l 【规则4-3-3】不可将浮点变量用“==”或“!=”与任何数字比较。 
千万要留意,无论是float还是double类型的变量,都有精度限制。所以一定要避免将浮点变量用“==”或“!=”与数字比较,应该设法转化成“> =”或“ <=”形式。 
假设浮点变量的名字为x,应当将 
if   (x   ==   0.0)   //   隐含错误的比较 
转化为    
if   ((x> =-EPSINON)   &&   (x <=EPSINON)) 
其中EPSINON是允许的误差(即精度)。 
例如精度为:const float EPSINON = 0.00001;


4.3.4   指针变量与零值比较 
l 【规则4-3-4】应当将指针变量用“==”或“!=”与NULL比较。 
指针变量的零值是“空”(记为NULL)。尽管NULL的值与0相同,但是两者意义不同。假设指针变量的名字为p,它与零值比较的标准if语句如下: 
if   (p   ==   NULL) //   p与NULL显式比较,强调p是指针变量 
if   (p   !=   NULL) 
不要写成 
if   (p   ==   0)   //   容易让人误解p是整型变量 
if   (p   !=   0)             
或者 
if   (p) //   容易让人误解p是布尔变量 
if   (!p) 
 
灭绝人性的智力题
三人决斗问题:
三个小伙子同时爱上了一个姑娘,为了决定他们谁能娶这个姑娘,他们决定用手枪进行一次决斗。阿历克斯的命中率是30%,克里斯比他好些,命中率是50%,最出色的枪手是鲍博,他从不失误,命中率是100%。由于这个显而易见的事实,为公平起见,他们决定按这样的顺序:阿历克斯先开枪,克里斯第二,鲍博最后。然后这样循环,直到他们只剩下一个人。那么这三个人中谁活下来的机会最大呢?他们都应该采取什么样的策略?
三人相对
A活下来有三种情况
1.A杀了C,B杀不死A,A又杀了B,概率30%×50%×0.3/0.65
2.A杀不死C,B杀了C,A杀了B,概率70%×50%×0.3/0.65
3.A杀不死C,B杀不死C,C杀了B,A杀了C,概率70%×50%×30%
所以A活下来的可能性为0.105+3/13≈0.336大于三分之一,比较幸运了。
B活下来有三种情况
1.A杀了C,B杀了A,概率30%×50%
2.A杀不死C,B杀了C,AB相对的情况下B杀了A,概率70%×50%×0.35/0.65
3.A杀了C,B杀不了A,AB相对的情况下B杀了A,概率30%×50%×0.35/0.65
所以B活下来的可能性为0.15+3.5/13≈0.419大于三分之一,非常幸运了。
C活下来只有一种情况
A杀不死C,B杀不死C,C杀了B,A杀不死C,C杀了A,概率70%×50%×70%
所以C活下来的可能性为0.245小于三分之一,非常不幸。
ABC活下来可能性之和恰为1。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值