三、简答题(25分)
1、头文件中的 ifndef/define/endif 干什么用?(5分)
答:防止该头文件被重复引用。
2、#include
答:对于#include
对于#include filename.h ,编译器从用户的工作路径开始搜索 filename.h
3、const 有什么用途?(请至少说明两种)(5分)
答:(1)可以定义 const 常量
(2)const可以修饰函数的参数、返回值,甚至函数的定义体。被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。
4、在c++ 程序中调用被 c编译器编译后的函数,为什么要加 extern c? (5分)
答:c++语言支持函数重载,c语言不支持函数重载。函数被c++编译后在库中的名字与c语言的不同。假设某个函数的原型为: void foo(int x, int y);
该函数被c编译器编译后在库中的名字为_foo,而c++编译器则会产生像_foo_int_int之类的名字。
c++提供了c连接交换指定符号externc来解决名字匹配问题。
四、有关内存的思考题(每小题5分,共20分)
一.
void getmemory(char *p)
{
p = (char *)malloc(100);
}
void test(void)
{
char *str = null;
getmemory(str);
strcpy(str, "hello world");
printf(str);
}
请问运行test函数会有什么样的结果?
答:试题传入getmemory( char *p )函数的形参为字符串指针,在函数内部修改形参并不能真正的改变传入形参的值,执行完 char *str = null; getmemory( str ); 后的str仍然为null;
二.
char *getmemory(void)
{
char p[] = "hello world";
return p;
}
void test(void)
{
char *str = null;
str = getmemory();
printf(str);
}
请问运行test函数会有什么样的结果?
答:可能是乱码。 char p[] = "hello world"; return p;的p[]数组为函数内的局部自动变量,在函数返回后,内存已经被释放。这是许多程序员常犯的错误,其根源在于不理解变量的生存期。
三.
void getmemory2(char **p, int num)
{
p = (char *)malloc(num);
}
void test(void)
{
char *str = null;
getmemory(str, 100);
strcpy(str, "hello");
printf(str);
}
请问运行test函数会有什么样的结果?
答: (1)能够输出hello (2 )test函数中也未对malloc的内存进行释放。(3)getmemory避免了试题1的问题,传入getmemory的参数为字符串指针的指针,但是在getmemory中执行申请内存及赋值语句
p = (char *) malloc( num );
后未判断内存是否申请成功,应加上: if ( *p null ) {
...//进行申请内存失败处理
}
四.
void test(void)
{
char *str = (char *) malloc(100);
strcpy(str, hello);
free(str);
if(str != null)
{
strcpy(str, world);
printf(str);
}
}
请问运行test函数会有什么样的结果?
答:执行 char *str = (char *) malloc(100); 后未进行内存是否申请成功的判断;另外,在free(str)后未置str为空,导致可能变成一个野指针,应加上: str = null;