资源描述
1.const意味着”只读",下面的申明都是什么意思?
const int a;
int const a;
const int *a;
int * const a;
int const * a const;
前两个的作用是同样,a是一个常整型数。第三个意味着a是一个指向常整型数的指针(也就是,整型数是不可修改的,但指针能够)。第四个意思a是一个指向整型数的常指针(也就是说,指针指向的整型数是能够修改的,但指针是不可修改的)。最后一个意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的,同时指针也是不可修改的)。
结论:·;核心字const的作用是为给读你代码的人传达非常有用的信息,实际上,申明一个参数为常量是为了告诉了用户这个参数的应用目标。假如 你曾花诸多时间清理其他人留下的垃圾,你就会很快学会感激这点多出的信息。(当然,懂得用const的程序员极少会留下的垃圾让他人来清 理的。) ·; 通过给优化器某些附加的信息,使用核心字const也许能产生更紧凑的代码。 ·; 合理地使用核心字const能够使编译器很自然地保护那些不希望被变化的参数,预防其被无意的代码修改。简而言之,这么能够减少bug的出现。
(1)欲制止一个变量被变化,能够使用 const 核心字。在定义该 const 变量时,一般需要对它进行初 始化,因为以后就没有机会再去变化它了;
(2)对指针来说,能够指定指针自身为 const,也能够指定指针所指的数据为 const,或二者同时指 定为 const;
(3)在一个函数申明中,const 能够修饰形参,表白它是一个输入参数,在函数内部不能变化其值;
(4)对于类的组员函数,若指定其为 const 类型,则表白其是一个常函数,不能修改类的组员变量;
(5)对于类的组员函数,有时候必须指定其返回值为 const 类型,以使得其返回值不为“左值”。
2.核心字volatile有什么含意?并给出三个不一样的例子。
一个定义为volatile的变量是说这变量也许会被意想不到地变化,这么,编译器就不会去假设这个变量的值了。精准地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在存储器里的备份。下面是volatile变量的几个例子:
(1)并行设备的硬件存储器(如:状态存储器)
(2)一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
(3)多线程应用中被几个任务共享的变量
3.一个参数既能够是const还能够是volatile吗?解释为何。 一个指针能够是volatile 吗?解释为何。
答案:
(1)是的。一个例子是只读的状态存储器。它是volatile因为它也许被意想不到地变化。它是const因为程序不应当试图去修改它。
(2) 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。
4.static核心字有什么作用?
(1)函数体内 static 变量的作用范围为该函数体,不一样于 auto 变量,该变量的内存只被分派一次,因此其值在下次调用时仍维持上次的值;
(2)在模块内的 static 全局变量能够被模块内所用函数访问,但不能被模块外其他函数访问;
(3)在模块内的 static 函数只可被这一模块内的其他函数调用,这个函数的使用范围被限制在申明 它的模块内;
(4)在类中的 static 组员变量属于整个类所拥有,对类的所有对象只有一份拷贝;
(5)在类中的 static 组员函数属于整个类所拥有,这个函数不接收 this 指针,因而只能访问类的static 组员变量。
5. extern 在"C"中有什么作用:
(1)被 extern "C"限定的函数或变量是 extern 类型的;
extern是 C/C++语言中表白函数和全局变量作用范围(可见性)的核心字,该核心字告诉编译器,其申明的函数和变量能够在本模块或其他模块中使用。
(2)被 extern "C"修饰的变量和函数是按照 C 语言方式编译和连接的;
extern "C"的常使用方法
(1)在 C++中引用 C 语言中的函数和变量,在包括 C 语言头文献(假设为 cExample.h)时,需进 行下列处理:
extern "C" { #include "cExample.h" }
而在 C语言的头文献中,对其外部函数只能指定为 extern 类型,C语言中不支持 extern "C"申明, 在.c 文献中包括了 extern "C"时会出现编译语法错误。
(2)在 C 中引用 C++语言中的函数和变量时,C++的头文献需添加 extern "C",不过在 C 语言中不 能直接引用申明了 extern "C"的该头文献,应当仅将 C 文献中将 C++中定义的extern "C"函数申明为 extern 类型。
6. 堆和栈的区分?
管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制,轻易产生memory leak。
申请大小:栈:栈是向低地址扩展的数据结构,是一块连续的内存的区域
堆:是向高地址扩展的数据结构,是不连续的内存区域。
分派方式:堆都是动态分派的 ,动态分派由alloca函数进行分派
栈的动态分派由编译器进行释放,无需我们手工实现
7.如下函数输出成果是
main()
{ int a[5]={1,2,3,4,5};
int *ptr=(int *)(&a+1);
printf("%d,%d",*(a+1),*(ptr-1));
}
答:2,5 *(a+1)就是a[1],*(ptr-1)就是a[4],执行成果是2,5
&a+1不是首地址+1,系统会以为加一个a数组的偏移,是偏移了一个数组的大小(本例是5个int)
int *ptr=(int *)(&a+1);则ptr实际是&(a[5]),也就是a+5
原因如下:&a是数组指针,其类型为 int (*)[5];
而指针加1要依照指针类型加上一定的值,不一样类型的指针+1之后增加的大小不一样。
a是长度为5的int数组指针,因此要加 5*sizeof(int),因此ptr实际是a[5],
不过prt与(&a+1)类型是不一样样的(这点很重要),因此prt-1只会减去sizeof(int*)
a,&a的地址是同样的,但意思不一样样
a是数组首地址,也就是a[0]的地址,&a是对象(数组)首地址,
a+1是数组下一元素的地址,即a[1],&a+1是下一个对象的地址,即a[5].
8.链表和数组的区分在哪里?
二者都属于一个数据结构
从逻辑结构来看
1.数组必须事先定义固定的长度(元素个数),不能适应数据动态地增减的情况。当数据增加时,也许超出原先定义的元素个数;当数据减少时,导致内存浪费;数组能够依照下标直接存取。
2.链表动态地进行存储分派,能够适应数据动态地增减的情况,且能够以便地插入、删除数据项。(数组中插入、删除数据项时,需要移动其他数据项,非常繁琐)链表必须依照next指针找到下一个元素
从内存存储来看
1. (静态)数组从栈中分派空间, 对于程序员以便迅速,不过自由度小
2. 链表从堆中分派空间, 自由度大不过申请管理比较麻烦
从上面的比较能够看出,假如需要迅速访问数据,极少或不插入和删除元素,就应当用数组;相反, 假如需要常常插入和删除元素就需要用链表数据结构了。
9.结构体
struct strA { int a; float b; char c; } expA;
printf("%ld",sizeof(expA));
输出成果为 12 ?
该问题包括编译器的“内存对齐”问题:
当代计算机中内存空间都是按照byte(字节)划分的,从理论上讲似乎对任何类型的变量的访问能够从任何地址开始,但实际情况是在访问特定变量的时候常常在特定的内存地址访问,这就需要各类型数据按照一定的规则在空间上排列,而不是次序的一个接一个的排放,这就是对齐。
对齐的作用和原因:各个硬件平台对存储空间的处理上有很大的不一样。某些平台对某些特定类型的数据只能从某些特定地址开始存取。其他平台也许没有这种情况,
不过最常见的是假如不按照适合其平台的要求对数据存储进行对齐,会在存取效率上带来损失。例如有些平台每次读都是从偶地址开始,假如一个int型(假设为32位)假如存储在偶地址开始的地方,那么一个读周期就能够读出,而假如存储在奇地址开始的地方,就也许会需要2个读周期,并对两次读出的成果的高低
字节进行拼凑才能得到该int数据。显然在读取效率上下降诸多。这也是空间和时间的博弈。
一般,我们写程序的时候,不需要考虑对齐问题。编译器会替我们选择适合目标平台的对齐方略。当然,我们也能够通知给编译器传递预编译指令而变化对指定数据的对齐措施。
不过,正因为我们一般不需要关心这个问题,因此因为编辑器对数据存储做了对齐,而我们不了解的话,常常会对某些问题感到困惑。最常见的就是struct数据结构的sizeof成果,出乎意料。
对于结构体来说,按组员中所占字节最大的是float类型,占用4个字节,一共有3个组员,因此总的占用字节为:4* 3 = 12.
10.为何标准头文献都有类似如下的结构?
#ifndef __INCvxWorksh
#define __INCvxWorksh
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif
显然,头文献中的编译宏“#ifndef __INCvxWorksh、#define __INCvxWorksh、#endif” 的作用是预防该头文献被重复引用。
11.sprintf,strcpy,memcpy使用上有什么要注意的地方?
答:strcpy是一个字符串拷贝的函数,它的函数原型为strcpy(char *dst, const char *src);将src开始的一段字符串拷贝到dst开始的内存中去,结束的标志符号为'�',因为拷贝的长度不是由我们自己控制的,因此这个字符串拷贝很轻易犯错。
具备字符串拷贝功效的函数有memcpy,这是一个内存拷贝函数,它的函数原型为memcpy(char *dst,const char* src, unsigned int len);将长度为len的一段内存,从src拷贝到dst中去,这个函数的长度可控。不过会有内存叠加的问题。
sprintf是格式化函数。将一段数据通过特定的格式,格式化到一个字符串缓冲区中去。sprintf格式化的函数的长度不可控,有也许格式化后的字符串会超出缓冲区的大小,导致溢出。
12.用预处理指令#define申明一个常数,用以表白1年中有多少秒(忽视闰年问题)
#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL
13.下面是笔试常考题,下面表示代码的意思
a) int a; // An integer
b) int *a; // A pointer to an integer
c) int **a; // A pointer to a pointer to an integer
d) int a[10]; //一个有10个指针的数组,该指针是指向一个整型数的。
e) int *a[10]; //一个有10个指针的数组,该指针是指向一个整型数的。
f) int (*a)[10]; //一个指向有10个整型数数组的指针
g) int (*a)(int); //一个指向函数的指针,该函数有一个整型参数并返回一个整型数。
h) int (*a[10])(int); //一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数。
14. 如下为Windows NT下的32位C++程序,请计算sizeof的值
void Func ( char str[100] )
{
sizeof( str ) = ?
}
void *p = malloc( 100 );
sizeof ( p ) = ?
这题很常见了,Func ( char str[100] )函数中数组名作为函数形参时,在函数体内,数组名失去了自身的内涵,仅仅只是一个指针;在失去其内涵的同时,它还失去了其常量特性,能够作自增、自减等操作,能够被修改。Windows NT 32位平台下,指针的长度(占用内存的大小)为4字节,故sizeof( str ) 、sizeof ( p ) 都为4。
15.写一个”标准"宏MIN ,这个宏输入两个参数并返回较小的一个。
#define MIN(A,B)
((A) <= (B) ? (A) : (B))
这个测试是为下面的目标而设的:
标识#define在宏中应用的基本知识。这是很重要的,因为直到嵌入(inline)操作符变为标准C的一部分,宏是以便产生嵌入代码的唯一措施,对于嵌入式系统来说,为了能达成要求的性能,嵌入代码常常是必须的措施。三重条件操作符的知识。这个操作符存在C语言中的原因是它使得编译器能产生比 if-then-else 更优化的代码,了解这个使用方法是很重要的。 懂得在宏中小心地把参数用括号括起来 .
我也用这个问题开始讨论宏的副作用,例如:当你写下面的代码时会发生什么事?
least = MIN(*p++, b);
成果是:
((*p++) <= (b) ? (*p++) : (*p++))
这个体现式会产生副作用,指针p会作三次++自增操作。
.main()
{
int a[5]={1,2,3,4,5};
int *ptr=(int *)(&a+1);
printf("%d,%d",*(a+1),*(ptr-1));
}
答:2,5
*(a+1)就是a[1],*(ptr-1)就是a[4],执行成果是2,5
&a+1不是首地址+1,系统会以为加一个a数组的偏移,是偏移了一个数组的大小(本例是5个int)
int *ptr=(int *)(&a+1);
则ptr实际是&(a[5]),也就是a+5
原因如下:
&a是数组指针,其类型为 int (*)[5];
而指针加1要依照指针类型加上一定的值,不一样类型的指针+1之后增加的大小不一样。
a是长度为5的int数组指针,因此要加 5*sizeof(int)
因此ptr实际是a[5]
不过prt与(&a+1)类型是不一样样的(这点很重要)
因此prt-1只会减去sizeof(int*)
a,&a的地址是同样的,但意思不一样样
a是数组首地址,也就是a[0]的地址,&a是对象(数组)首地址, a+1是数组下一元素的地址,即a[1],&a+1是下一个对象的地址,即a[5].
16.如下为Windows NT下的32位C++程序,请计算sizeof的值
void Func ( char str[100] )
{
sizeof( str ) = ?
}
void *p = malloc( 100 );
sizeof ( p ) = ?
前两个的作用是同样,a是一个常整型数。第三个意味着a是一个指向常整型数的指针(也就是,整型数是不可修改的,但指针能够)。第四个意思a是一个指向整型数的常指针(也就是说,指针指向的整型数是能够修改的,但指针是不可修改的)。最后一个意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的,同时指针也是不可修改的)。
结论:
核心字const的作用是为给读你代码的人传达非常有用的信息,实际上,申明一个参数为常量是为了告诉了用户这个参数的应用目标。假如
你曾花诸多时间清理其他人留下的垃圾,你就会很快学会感激这点多出的信息。(当然,懂得用const的程序员极少会留下的垃圾让他人来清
理的。)
•通过给优化器某些附加的信息,使用核心字const也许能产生更紧凑的代码。
•; 合理地使用核心字const能够使编译器很自然地保护那些不希望被变化的参数,预防其被无意的代码修改。简而言之,这么能够减少bug的出现。
(1)欲制止一个变量被变化,能够使用 const 核心字。在定义该 const 变量时,一般需要对它进行初始化,因为以后就没有机会再去变化它了;
(2)对指针来说,能够指定指针自身为 const,也能够指定指针所指的数据为 const,或二者同时指定为 const;
(3)在一个函数申明中,const 能够修饰形参,表白它是一个输入参数,在函数内部不能变化其值;
(4)对于类的组员函数,若指定其为 const 类型,则表白其是一个常函数,不能修改类的组员变量;
(5)对于类的组员函数,有时候必须指定其返回值为 const 类型,以使得其返回值不为“左值”。
核心字volatile有什么含意?并给出三个不一样的例子。
一个定义为volatile的变量是说这变量也许会被意想不到地变化,这么,编译器就不会去假设这个变量的值了。精准地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在存储器里的备份。下面是volatile变量的几个例子:
•; 并行设备的硬件存储器(如:状态存储器)
•; 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
•; 多线程应用中被几个任务共享的变量
17. 一个参数既能够是const还能够是volatile吗?解释为何。
• 一个指针能够是volatile 吗?解释为何。
下面是答案:
•; 是的。一个例子是只读的状态存储器。它是volatile因为它也许被意想不到地变化。它是const因为程序不应当试图去修改它。
•; 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。
18.extern "C"的常使用方法
(1)在 C++中引用 C 语言中的函数和变量,在包括 C 语言头文献(假设为 cExample.h)时,需进 行下列处理:
extern "C"
{
#include "cExample.h"
}
而在 C 语言的头文献中,对其外部函数只能指定为 extern 类型,C 语言中不支持 extern "C"申明, 在.c 文献中包括了 extern "C"时会出现编译语法错误。
(2)在 C 中引用 C++语言中的函数和变量时,C++的头文献需添加 extern "C",不过在 C 语言中不能直接引用申明了 extern "C"的该头文献,应当仅将 C 文献中将 C++中定义的 extern "C"函数申明为 extern 类型。
19.为何标准头文献都有类似如下的结构?
#ifndef __INCvxWorksh
#define __INCvxWorksh
#ifdef __cplusplus
extern "C" {
#endif
/*...*/
#ifdef __cplusplus
}
#endif
#endif /* __INCvxWorksh */
显然,头文献中的编译宏“#ifndef __INCvxWorksh、#define __INCvxWorksh、#endif” 的作用
是预防该头文献被重复引用。
20. 用变量a给出下面的定义
a) 一个整型数(An integer)
b)一个指向整型数的指针( A pointer to an integer)
c)一个指向指针的的指针,它指向的指针是指向一个整型数( A pointer to a pointer to an intege)r
d)一个有10个整型数的数组( An array of 10 integers)
e) 一个有10个指针的数组,该指针是指向一个整型数的。(An array of 10 pointers to integers)
f) 一个指向有10个整型数数组的指针( A pointer to an array of 10 integers)
g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A pointer to a function that takes an integer as an argument
and returns an integer)
h)一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数( An array of ten pointers to functions t
hat take an integer argument and return an integer )
答案是:
a) int a; // An integer
b) int *a; // A pointer to an integer
c) int **a; // A pointer to a pointer to an integer
d) int a[10]; // An array of 10 integers
e) int *a[10]; // An array of 10 pointers to integers
f) int (*a)[10]; // A pointer to an array of 10 integers
g) int (*a)(int); // A pointer to a function a that takes an integer argument and returns an integer
h) int (*a[10])(int); // An array of 10 pointers to functions that take an integer argument and return an integer
21.核心字 const什么含义?
参考答案:
1)欲制止一个变量被变化,能够使用 const 核心字。在定义该 const变量时,一般需要对它进行初始化,因为以后就没有机会再去变化它了;
2)对指针来说,能够指定指针自身为 const,也能够指定指针所指的数据为const,或二者同时指定为const;
3)在一个函数申明中,const 能够修饰形参,表白它是一个输入参数,在函数内部不能变化其值;
4)对于类的组员函数,若指定其为 const类型,则表白其是一个常函数,不能修改类的组员变量;
5)对于类的组员函数,有时候必须指定其返回值为 const类型,以使得其返回值不为“左值”。例如:
const classA operator*(const classA& a1,const classA& a2);
operator*的返回成果必须是一个 const对象。假如不是,这么的变态代码也不会编译犯错:
22.static 核心字的作用?
参考答案:
1)函数体内 static 变量的作用范围为该函数体,不一样于 auto变量,该变量的内存只被分派一次,因此其值在下次调用时仍维持上次的值;
2)在模块内的 static全局变量能够被模块内所用函数访问,但不能被模块外其他函数访问;
3)在模块内的 static函数只可被这一模块内的其他函数调用,这个函数的使用范围被限制在申明它的模块内;
4)在类中的 static组员变量属于整个类所拥有,对类的所有对象只有一份拷贝;
5)在类中的 static 组员函数属于整个类所拥有, 这个函数不接收 this指针,因而只能访问类static 组员变量。
23.extern “C”的作用?
参考答案:
extern "C"的重要作用就是为了能够正确实现 C++代码调用其他 C语言代码。加上extern "C"后,会指示编译器这部分代码按 C 语言的进行编译,而不是 C++的。因为 C++支持函数重载,因此编译器编译函数的过程中会将函数的参数类型也加到编译后的代码中,而不但仅是函数名;而 C 语言并不支持函数重载,因此编译C 语言代码的函数时不会带上函数的参数类型,一般只包括函数名。
24.核心字 volatile是什么含义?并给出三个不一样的例子
参考答案:
一个定义为 volatile的变量是说这变量也许会被意想不到地变化,这么,编译器就不会去假设这个变量的值了。 精准地说就是, 优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在存储器里的备份。
下面是volatile变量的几个例子:
1) 并行设备的硬件存储器(如:状态存储器)
2) 一 个 中 断 服 务 子 程 序 中 会 访 问 到 的 非 自 动 变 量(Non-automaticvariables)
3) 多线程应用中被几个任务共享的变量
25.do-while 和while 的区分?
参考答案:
1)do...while 语句的 while 语句后要加分号“; ”
2)while 语句也许一次也不执行循环体,但 do...while语句最少执行一次循环体。
3)对于同一个问题,既能够用 while 语句,也能够用 do...while 语句。
26.new、delete、malloc、free 关系
参考答案:
delete 会调用对象的析构函数,和 new 对应 free 只会释放内存,new调用结构函数。malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。它们都可用于申请动态内存和释放内存。对于非内部数据类型的对象而言,光用 maloc/free无法满足动态对象的要求。对象在创建的同时要自动执行结构函数, 对象在消亡之前要自动执行析构函数。 因为malloc/free是库函数而不是运算符, 不在编译器控制权限之内, 不能够把执行结构函数和析构函数的任务强加于 malloc/free。因此C++语言需要一个能完成动态内存分派和初始化工作的运算符 new,以及一个能完成清理与释放内存工作的运算符 delete。注意new/delete不是库函数。
27. sprintf,strcpy,memcpy的功效,在使用上有哪些要注意的地方.
参考答案:
strcpy是一个字符串拷贝的函数, 它的函数原型为strcpy(char *dst, constchar *src);将 src 开始的一段字符串拷贝到 dst开始的内存中去,结束的标志符号为'\0', 因为拷贝的长度不是由我们自己控制的, 因此这个字符串拷贝很轻易犯错。具备字符串拷贝功效的函数有 memcpy, 这是一个内存拷贝函数, 它的函数原型为 memcpy(char *dst, const char* src, unsigned int len);将长度为len的一段内存,从 src 拷贝到 dst 中去,这个函数的长度可控。不过会有内存叠加的问题。sprintf是格式化函数。将一段数据通过特定的格式,格式化到一个字符串缓冲区中去。sprintf格式化的函数的长度不可控,有也许格式化后的字符串会超出缓冲区的大小,导致溢出。
28.#define DOUBLE(x)x+x, i=5*DOUBLE(5); i 是多少?
解析:答案是30
本题重要考查学生对宏的基本知识的掌握,学习宏的时候,需要记住一个标准:原封不动的替代。也就是说宏只作替代,不做计算。
29.写一个宏 MIN,这个宏输入两个参数并返回较小的一个
解析:答案是 #define MIN(A,B) ((A) <= (B)? (A) : (B))这个测试是为下面的目标而设的:
1)标识#define 在宏中应用的基本知识。这是很重要的,因为直到嵌入(inline)操作符变为标准C的部分,宏是以便产生嵌入代码的唯一措施,对于嵌入式系统来说,为了能达成要求的性能,嵌入代码常常是必须的措施。
2)三重条件操作符的知识。这个操作符存在C语言中的原因是它使得编译器能产生比if-then-else更优化的代码,了解这个使用方法是很重要的。
3)懂得在宏中小心地把参数用括号括起来
4)我也用这个问题开始讨论宏的副作用,例如:当你写下面的代码时会发生什么事?least = MIN(*p++, b);
30.用预处理指令#define申明一个常数,表示1 年中有多少秒(忽
略闰年)
解析:答案是 #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL
考查知识点:
1) #define 语法的基本知识 (例如: 不能以分号结束, 括号的使用, 等等)
2)懂得预处理器将为你计算常数体现式的值,因此,直接写出你是怎样计算一年中有多少 秒而不是计算出实际的值,是更清楚而没有代价的。
3) 意识到这个体现式将使一个16位机的整型数溢出-因此要用到长整型符号L,告诉编译器这个常数是的长整型数。
4) 假如你在你的体现式中用到UL(表示无符号长整型),那么你有了一个好的起点
31.用宏定义互换两个数
解析:答案如下
#define SWAP(a,b,type) {type c; c = (a); (a) = (b); (b) = c;}
32.分别给出 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 判断一个数值型变量(short、int、long等),应当用if(var==0),表白是与0进行“数值”上的比较;而判断指针则适宜用if(var==NULL),这是一个很好的编程习惯。浮点型变量并不精准,因此不可将 float变量用“==”或“!=”与数字比较,应当设法转化成“>=”或“<=”形式。假如写成 if (x == 0.0),则判为错,得0分。
33.a)一个整型数__________________
b)一个指向整型数的指针___________
c)一 个 指 向 指 针 的 指 针 , 它 指 向 的 指 针 是 指 向 一 个 整 _____________
d)一个有 10个整型数的数组___________
e) 一个有 10 个整型数的数组,该指针是指向一个整型数的_______________
f)一个指向有 10个整型数数组的指针_______
g)一个指向函数的指针,该函数有一个整型参数并返回一个整型数_____________
解析:答案如下
a) int a; b) int *a; c) int **a; d) int a[10];
e) int *a[10]; f) int (*a)[10];
g) int (*a)(int); h) int (*a[10])(int);
34. 编写函数_memmove 阐明如下: 实现 c 语言库函数 memmove的功效:将一块缓冲区中的数据移动到应一块缓冲区中。
阐明:不能直接调用 memmove、memcpy 之类的库函数。
答案:void *memmove(void *dest, const void *src, size_t count)
{
char *tmp, *s;
if (dest <= src) {
tmp = (char *) dest;
s = (char *) src;
while (count--)
*tmp++ = *s++;
}else{
tmp = (char *) dest + count;
s = (char *) src + count;
while (count--)
*--tmp = *--s;
}
return dest;
}
解析:假如目标地址小于源地址,阐明目标地址最开始的部分并没有被覆盖重叠,就从把源地址的内容从前向后拷贝;假如目标地址不小于源地址,阐明目标地址的最背面的部分没有被覆盖重叠,因此就把源地址的内容从后往前拷贝。
35.一个猴子吃桃一天吃桃子剩余数量的二分之一,感觉不够,再吃一个,共10天吃完,问一共吃了多少桃子,写出你的代码。
解析:重要考查学生的逻辑思维能力,以及循环的使用。答案没有统一标准,参考答案如下:
int day,x1,x2;
day = 9; x2=1;
while (day>0) { x1 = (x2+1)*2; x2 = x1; day --;}
printf("total = %d \n”,x1);
36. 数组有 1000 个元素,设为数组 a[1000],存储 1-1000的数值,不过目前有一个数值重复了,只扫描一遍数组,找出那个重复的数
参考答案如下:(假设为固定的int型数组,其元素为5个)
int a[5] ={1,2,3,4,3};
int b[6] = {0};int num =0;
for (int i = 0; i<5; i++) {
num = a[i]; //得到 a[i]的值
b[num]++;//让 a 数组中的值作为 b 数组的下标
if (b[num]>1) {
//此位置加了两次,其重复
break;} }
printf("重复的数字为: %d",num);
相同题:设计一个算法,要求在20个数字中(0到19)随机选用十个数字,不过这十个数字不能重复(用C语言或者OC实现)
37.编写一个函数,作用是把一个char组成的字符串循环右移n个。例如本来是“abcdefghi”假如 n=2,
展开阅读全文