思考题LWord格式文档下载.docx
《思考题LWord格式文档下载.docx》由会员分享,可在线阅读,更多相关《思考题LWord格式文档下载.docx(31页珍藏版)》请在冰点文库上搜索。
数组元素是前后相邻的一组变量,最后一个元素是最后定义的,因而地址最小,存储在栈顶。
(参见题1)
7、不增设其他变量,用其他什么方法可以实现交换两个变量的值?
写出代码。
1算术法
inta,b;
(2)
a=10;
b=12;
a=10;
a=b-a;
//a=2;
b=12a=b/a;
b=b-a;
b=10b=b/a;
a=b+a;
//a=12;
b=10a=b*a;
2.异或法
a=10,b=12;
//a=1010^b=1100;
a=a^b;
//a=0110^b=1100;
b=a^b;
//a=0110^b=1010;
//a=1100=12;
b=1010;
8、教材117页中说到:
“复合语句相当于一个无返回值和参数列表为空的函数,复合函数体就是这个函数体。
”这个描述是否正确,请给出正确或不正确的理由。
9、总结一下变量的生命期与作用域的关系(综合第六、七章的知识)。
首先简单说说各类型变量。
1:
自动型(auto型):
此变量是在函数内部定义的一种变量,它局限于该函数或所在的函数,故也称为局部变
量,更加确切的说定义在某一对花括号之内,生命起始终止于这个大括号;
2:
外部型(extern):
此变量又称为外部变量,是一种全局变量,在函数之外定义,
3:
寄存器型(register)又称为寄存器型变量,只有int,short,char类型的变量才能定义为寄存器型变量,
它只适用于auto型变量和函数的形式参数,所以它只有在函数内定义,并且作用域和生命周期同auto一样.
4:
静态型(static):
分为内部静态变量和外部静态变量;
内部静态变量同auto变量,也是在函数内部定义,它局限于定义它的函数,但是在退出函数的时候并部消失,而是在整个程序中都存在;
用一句话说就是,内部静态变量有的可见性和全局的生命期;
外部静态变量:
是在函数外部定义的变量,作用域是定义它的源文件,即对定义它的源文件是全程知道的;
对源文件之外的文件是部可见的;
综上,我们将变量的生命域与作用域关系总结成一张表格。
变量的存储类型
函数内
函数外
文件外
作用域与生存期是否一致
自动局部变量
作用域
本函数体内
√
×
是
生存期
一次函数调用过程
静态局部变量(内部静态变量)
否
第一次执行其定义语句到程序结束
寄存器变量
同自变量
文件作用域的外部变量(外部静态变量)
本文件内
第一次执行其定义语句到文件结束
全局作用域的外部变量
其定义点以下所有除去同名局部变量的部分
从编译到程序结束
10、为什么在C语言中字符常量占4个字节而字符变量只占1个字节(VC环境下)?
首先编程检验。
#include<
stdio.h>
intmain()
{
charch;
printf(“%d,%d,%d\n”,sizeof(char),sizeof(ch),sizeof(‘A’));
return0;
}
运行结果为:
1,1,4
原因:
在C语言中常量统一用32位二进制数表示,占四字节;
128个字符和0-127(ASCII码)一一对应,因而字符型变量能以一个字节的整数形式存储。
11、探讨25/6、25/-6、-25/6、-25/-6、25%6、25%-6、-25%6、-25%-6的结果,上机测试并总结规律。
结果分别为25/6=4-25/-6=425/-6=-4-25/6=-4
25%6=1-25%-6=-125/-6=1-25%6=-1
规律:
对于“/”除号,遵循同号为正,异号为负的原则。
对于“%”取余号,结果的正负只看“%”号前的数的正负,%前为正,则余数为正,反之为负。
12、在C语言中,表达式中的结合性有什么意义?
它与计算的优先级有什么联系?
我们可以做个比喻:
结合性是仲裁者,在几个操作符具有相同的优先级时决定先执行哪一个。
许多操作符的优先级都是相同的。
这时,操作符的结合性就开始发挥作用了。
在表达式中如果有几个优先级相同的操作符,结合性就起仲裁的作用,由它决定哪个操作符先执行。
结合性只用于表达式中出现两个以上相同优先级的操作符的情况,用于消除歧义
优先级决定表达式中各种不同的运算符起作用的优先次序,而结合性则在相邻的运算符的具有同等优先级时,决定表达式的结合方向。
13、对于二维数组inta[3][5],&
a[0][0]、a[0]、&
a[0]、*a、a的值是否一样?
各代表什么含义?
全部相同。
&
a[0][0]=a[0]
表示第0行第0列元素的地址,是一维数组指针。
*a=a=&
a[0]
表示第0行元素的行址,是二维指针常量。
14、是不是所有的递归函数都可以用非递归函数等效实现?
反之,是不是所有的非递归函数都可以用递归函数实现?
说出理由并给出例示程序。
任何递归程序都可以通过引入堆栈转化为非递归的形式。
这种转化其实就是模拟计算机实现递归的过程,因为任何递归计算过程最后总是要用堆栈转化为循环来实现的,你可以考虑人脑来计算递归的过程:
先倒过来向前递归,到达最初点以后再正过来向后递推,堆栈的作用就是记住过程中的临时变量。
非递归化就是指不引入堆栈等辅助空间进行计算的算法。
更确切地说,非递归是指辅助的空间为O
(1)的算法(辅助空间的规模和问题的输入规模无关)。
不引入堆栈的所谓非递归本质上还是递归,只不过原来由编译器做的事让你的程序来模拟实现了。
不是所有的可计算问题都可以由递归转化为递推的。
例如著名的Ackermann函数,就没有递推算法。
Ackermann函数定义如下:
若m=0,返回n+1。
若m>
0且n=0,返回Ackermann(m-1,1)。
0且n>
0,返回Ackermann(m-1,Ackermann(m,n-1))
意义
从Ackermann函数的定义中可以看出,Ackermann函数可以看成关于n的一个函数序列,其中第0个函数返回n+1,而第m个函数则是将第m-1个函数对1迭代n+1遍。
对较小的m,该函数为:
Ackermann(0,n)=n+1
Ackermann(1,n)=n+2
Ackermann(2,n)=2*n+3
Ackermann(3,n)=2^(n+3)-3
Ackermann(4,n)=2^2^2^……^2-3,乘幂中共有n+3个2。
当m≥4,Ackermann函数的增长快得惊人。
Ackermann(4,0)=13,Ackermann(4,1)=65533,Ackermann(4,2)=2^65536-3有19729位,而Ackermann(4,3)则即使是位数也不易估计。
Ackermann(5,0)=65533,Ackermann(5,1)=Ackermann(4,65533)……
二、编程类:
1、编程测试程序可以通过指针申请多少个字节的动态空间。
可以申请25*10000000*8个字节。
测试程序如下:
stdlib.h>
#defineN10000000
voidf(void);
while
(1)
f();
return0;
voidf(void)
double*p;
staticintc=0;
c++;
p=(double*)malloc(N*sizeof(double));
if(p==NULL)
{
printf("
allocationfailure"
);
exit
(1);
}
printf("
c=%d\t"
c);
输出结果为:
c=1c=2..............................c=25allocationfailure
2、向有序数组中插入一个元素,请改进教材中例5.10的算法,将定位和移位两个循环合并为一个循环来实现。
inta[7]={12,23,34,45,56,67};
inti,x;
pleaseinputxbeinserted:
\n"
scanf("
%d"
&
x);
for(i=5;
i>
=0&
a[i]>
x;
i--)
a[i+1]=a[i];
a[i+1]=x;
thenewarrayis:
for(i=0;
i<
7;
i++)
%d"
a[i]);
3、用函数FindAll实现查找变量x是否是数组中的元素,如果是,返回所有的存在下标,而不是只返回第一个元素的下标,主函数调用该函数输出所有的值等于x的元素的下标。
voidFindAll(int*p,intn,intx);
inta[10]={2,2,2,2,4,4,5,6,7,7};
FindAll(a,10,7);
voidFindAll(int*p,intn,intx)
inti;
intIndex[10],count=0;
n;
if(p[i]==x)
{
Index[count++]=i;
}
if(count>
0)
所有下标为:
"
for(i=0;
count;
printf("
Index[i]);
else
不存在\n"
4、通过编程说明一个递归函数在哪些情况下无法终止。
例:
intAddFn(inta)
a+=1;
if(a>
8)
{a=AddFn(a);
returna;
(1).如上所示,AddFn为一个简单的递归函数,假设以下为使用时的代码
intj=2;
j=AddFn(j);
returnj;
此时j的值为:
3,程序成功结束。
(2).假设调用方式改成下面的
intj=8;
此时递归函数无法被中止,因为递归函数中的条件a>
8永远为true!
5、编程实现一个约会问题:
女朋友对男朋友说,你等我,如果我三分钟内不来,你就再等我,直到我来为止。
(建议调用系统时钟来运行本程序,时间可以设定为一分钟不来)
time.h>
windows.h>
ints;
clock_tstart;
srand(time(NULL));
start=clock();
do
srand(time(NULL));
s=rand()%2;
//1设置为等,0设置为女友来
if(s==0)
come"
break;
}while((clock()-start)/1000!
=60);
//时间设置为一分钟
if(s)
wait"
6、改进教材中的删除算法,要求删除所有的值等于x的元素,分别用两层循环和一层循环实现。
(根据编程需要来定义数组和普通变量,个数不限但不允许定义不使用的变量)
一层循环:
inta[]={1,2,2,2,3,5,6,9,18,34,2,23,2,2,14,51,34,5,2,2},b[20];
inti,j=0,x;
pleaseinputxbedeleted:
20;
if(a[i]!
=x)
b[j++]=a[i];
j;
b[i]);
二层循环:
inta[]={1,2,2,2,3,5,6,9,18,34,2,23,2,2,14,51,34,5,2,2};
inti,j,x,n=20;
if(a[i]==x)
n--;
for(j=i;
j<
n-1;
j++)
a[j]=a[j+1];
i--;
7、打印九九乘法表,要求打印表头,两个乘法因子都要能清晰显示,下面的表是完整表,请完成程序分别打印上三角和下三角的乘法表,表头和每行的最左侧参照下面的结果。
九九乘法表:
===========================================
123456789
-----------------------------------------------------------------------
1|123456789
2|24681012141618
3|369121518212427
4|4812162024283236
5|51015202530354045
6|61218243036424854
7|71421283542495663
8|81624324048566472
9|91827364554637281
//打印九九乘法表的上三角和下三角
voidprint1();
voidprint2();
print1();
print2();
voidprint1()
inti,j;
九九乘法表:
===========================================================================\n"
\t1\t2\t3\t4\t5\t6\t7\t8\t9\n"
---------------------------------------------------------------------------\n"
9;
%d|\t"
i+1);
for(j=0;
=i;
%d\t"
(i+1)*(j+1));
voidprint2()
inti,j,m;
%d|"
for(m=0;
m<
m++)
\t"
for(j=i;
8、下面是汉诺塔程序的递归代码,请将每一层递与归的过程及参数的变化情况用图表达出来。
汉诺塔问题描述:
汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。
大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。
大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。
并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
汉诺塔求解代码:
voidHanoi(intn,chara,charb,charc)
{if(n>
=1)
{Hanoi(n-1,a,c,b);
%c--->
%c\n"
a,c);
Hanoi(n-1,b,a,c);
主函数中调用:
Hanoi(3,'
A'
'
B'
C'
表示将三个盘子从A柱借助于B柱移动到C柱上。
请完成完整的程序写出运行结果,并画出“递”与“归”及每层调用情况的图示
//汉诺塔问题,主函数中调用:
//表示将三个盘子从A柱借助于B柱移动到C柱上。
请完成完整的程序写出运行结果,
voidHanoi(intn,chara,charb,charc);
移动三个圆盘的步骤:
Hanoi(3,'
9、请用递归改写教材中程序6.19,用二分法实现在有序数组中查找某一个元素,若存在则返回其下标。
主函数中调用该递归函数实现相应功能。
intbisearch(int*pa,intm,intn,intitem)
intlow=m,high=n-1,mid=0;
mid=(low+high)/2;
if(low>
high)
return(-1);
else
if(item==pa[mid])
return(mid);
if(item<
pa[mid])
bisearch(pa,m,mid,item);
bisearch(pa,mid+1,n,item);
inta[10]={12,23,34,45,56,67,78,89,90,100};
intx,pos;
printf("
INPUTXBESEARCHED:
scanf("
pos=bisearch(a,0,10,x);
if(pos!
=-1)
pos=%d\n"
pos);
Notfound!
10、编程打印用“*”组成的图形,如心形、正五边形、正六边形、耐克商标、蝙蝠侠标记等,至少完成三个。
打印心形(两个,一正一倒):
voidA(intn)//A函数:
输