1.分析下面代码有什么问题?
void test1()
{
char string[10];
char* str1 = "0123456789";
strcpy(string, str1);
}
解答:字符串str1需要11个字节才能存放下(包括末尾’\0’),而string只有10个字节的空间,strcpy会导致数组越界;
2.分析下面代码有什么问题?
void test2()
{
char sting[10],str1[10];
int i;
for(i=0; i<10; i++)
{
str = 'a';
strcpy(string, str1);
}
}
解答:首先,代码根本不能通过编译,因为数组名str1位char* const类型的右值类型,根本不能赋值。再者,即使想对数组的第一个元素赋值,也要使用*str1 = ‘a’;
其次,对字符数组赋值后,使用库函数strcpy进行拷贝操作,strcpy会从源地址一直往后拷贝,直到遇到’\0’为止。所以拷贝的长度是不定的。如果一直没有遇到’\0’导致越界访问非法内存,程序就崩了。
完美修改方案为:
void test2()
{
char string[10],str1[10];
int i;
for(i=0; i<9; i++)
{
str1[i] = 'a';
}
str1[9] = '\0';
strcpy(string, str1);
}
3.指出下面代码有什么问题?
void test3(char* str1)
{
if(str == NULL){
return ;
}
char string[10];
if(strlen(str1) <= 10)
{
strcpy(string, str1);
}
}
解答:if(strlen(str1) <= 10)应改为if(strlen(str1) < 10),因为strlen的结果未统计’\0’所占用的1个字节。
4.看看下面的一段程序有什么错误?
swap(int* p1,int* p2)
{
int *p;
*p = *p1;
*p1 = *p2;
*p2 = *p;
}
解答:1.需要一个返回值void
2.在swap函数中,p是一个“野”指针,有可能指向系统区,导致程序运行的崩溃。在VC++中debug运行时提示错误“Access Violation”。改程序应该改为:
void swap( int* p1,int* p2)
{
int p;
p = *p1;
*p1 = *p2;
*p2 = p;
}
5.分别给出BOOL,int,float,指针变量与“零值”比较的if语句(假设变量名为var)
解答:
BOOl型变量:if(!var);
int型变量:if(var == 0);
float型变量:
const float EPSINON = 0.00001;
if((x >= -EPSINON)&&(x <= EPSINON))
指针变量:if(var == NULL)
剖析:
考查对0值判断的“内功”BOOL型变量的0判断完全可以写成if(var == 0),而int型变量也可以写成if(!var),指针变量的判断也可以写成if(!var),上述写法虽然程序都能正确运行,但是未能清晰地表达程序的意思。一般的,如果想让if判断一个变量“真”、“假”,应直接使用if(var)、if(!var),表明其为“逻辑”判断;如果用if判断指针则适宜用if(var == NULL),这是一种很好的编程习惯。浮点型变量并不精确,所以不可将float变量用“==”或“!=”与数字比较,应该设法转化成“ >= ”或“ <= ”形式。如果写成if(x == 0.0),则判为错,得0分。
6.编写一个函数,作用是把一个char组成的字符串循环右移n个。比如原来是“abcdefghi”如果n = 2,移位后应该是“hiabcdefg”函数头是这样的
//pStr是指向以‘\0’结尾的字符串的指针
//steps是要求移动的n
void LoopMove(char* pStr,int steps)
{
//请填充...
}
解答:
void LoopMove(char *str,int steps)
{
int len = strlen(str);
char tmp[MAXSIZE];
strcpy(tmpm,str+len-steps);
strcpy(tmp+steps.str);
*(tmp+len) = '/0';
strcpy(str,tmp);
}