我们新年好呀,春节这段时间太忙了,一向没有写文章,这两天才想起来应该搞搞学习了,就把年前写的atm项目中遇到的一些问题整理出来,供需求的人参阅学习,也供自己回顾温习。
1. void*指针类型
一开始学习C言语时,对void*
这个类型没有过多的了解与关注,只知道是“没有类型的指针”,没有用过,在写atm这个项目的时分,才真实去了解它。
void*
类型是一个指向未知类型的指针,不能直接用于拜访指向的数据。
其实,各种类型之间没有实质的差异,void*
也相同,只是解释内存中的数据方式不同,int*
指向的内存中存储着数字,char*
指向的内存中存储着字符串。假如需求转化为特定的数据类型,需求根据详细的数据类型进行强制类型转化,才能正确的拜访和操作数据。但需求留意的是,在进行void*
向特定类型的数据转化时,需求保证原始的void*
指针指向的内存确实包含了有用的转化指针数据,不然可能会导致未界说行行为。
- 比方,
void*
类型转化为char*
类型,保证void*转化时指向的内存中存储的便是char
类型数据即可。 - 特定类型的数据也能够转化为
void*
类型。因为void*
是一种通用的指针类型,能够承受任何类型的指针。比方,char*
类型转化为void*
类型,只需求强制转化,刺进类型转化为void*
类型不会丢失任何信息,只需求保证在转化之前正确地分配内存。
在很多通用的函数接口中,给的都是参数类型都是void*。
比方:void* memcpy(void* dest,const void* src,size_t n);
其间,dest
是指向目标内存地址的指针,src
是指向源内存地址的指针,n
是要被仿制的字节数。这个函数返回一个指向目标内存地址的指针。运用memcpy
函数能够便利的将一段内存中的数据仿制到另一段内存中,而不需求手动逐个字节地仿制。
这样设计的目的是,因为你不知道用户的数据类型是什么,但是你有必要能够,处理用户的各种数据类型,所以会运用void*
,void*
能包容的承受各种类型的指针。假如你希望接口能够承受任何类型的参数,你能够运用void*
类型,但在详细运用的时分,你有必要转化为详细的指针类型。
在运用void*
需求特别留意的是,你有必要清楚原始传入的是什么类型,然后转化成对应的类型。
void*
很强大,但是必定要在适宜的时分运用;
2. 读取/写入方位产生拜访冲突
遇到 C/C++程序运行时提示“读取/写入方位产生拜访冲突”。
产生原因:一般都是因为产生反常处的代码中,涉及到数据的读取或写入,而且拜访数据时运用的是指针,而该指针并未得到适宜的初始化,导致其所指向内存为NULL。
解决方法:
- 写入冲突:初始化变量;
- 读取冲突:输出类型写正确;
3. while循环中有Switch,怎么跳出while循环
3.1. while循环用boolean变量操控
switch
中的break
只能停止switch
循环,无法停止while
循环,假如将break
改为return
,虽然能停止循环,但是也会用力过猛,整个方法都会停止。
怎么做到准确的停止掉当时while循环,我们能够在外面界说一个boolean
变量flag
来操控while
循环,通过改变flag
的值来操控while
循环。
如下是atm系统中“修正用户信息”函数的部分代码:
//修正用户信息
void updateInfo(){
int i=0;
int flag = 1;
Customer *user = (Customer*)getData(hashmap,custCurrent->accountCard);
while(flag){
scanf("%d",&i);
switch(i){
case 1:printf("请输入账户名称:n");scanf("%s", &user->accountName);break;
case 2:printf("请输入电话号码:n");scanf("%s", &user->mobile);break;
case 3:printf("请输入要修正的密码:n");scanf("%s", &user->password);break;
case 0:flag = 0;break;
default:printf("输入有误,请输入对应的值");
}
}
printf("修正用户信息成功! ");
return;
}
在修正用户信息函数中,一开始我并没有运用flag
变量,导致循环总是出现提早停止或堕入死循环的问题,后面奇妙的运用了一个flag
变量去操控循环的停止就能够完美的实现啦。
4. static关键字
4.1. 润饰部分变量
运用static
润饰的部分变量不会在函数重新进入时再次赋初值,不会在函数完毕时而释放(存储在大局区),也不会在循环中多次赋初值。这种变量的效果域为部分效果域,当界说它的函数完毕时,其效果域随之完毕。运用static
润饰的部分变量存储于进程的大局数据区,即使函数返回,它的值也会坚持不变。
4.2. 润饰大局变量
运用static
润饰的大局变量仅对当时文件可见,其他文件不行拜访,其他文件能够界说与其同名的变量,两者相互不影响。在界说不需求与其他文件同享大局变量时,加上static
关键字能够有用地下降程序模块化之间的耦合,避免不同文件同名变量的冲突,且不会误运用。
4.3. 润饰函数
运用static
润饰的函数只能在本文件中调用,不能在其他文件中调用。这种函数没有this
指针,它无法拜访属于类对象的非静态数据成员,也无法拜访非静态成员函数,它只能调用其余的静态成员函数。出现在类体外的函数界说不能指定关键字static
。