C 2015年笔试题
1、写出程序输出结果#
1234567891011121314151617void
main()
{
char
p[10]=
"abc"
;
char
q[]=
"xyz"
;
int
i,j;
i=0;
while
(*(p+i)!=
'\0'
) i++;
//此时i=3
j=0;
i++;
// i= 4
while
(*(q+j)!=
'\0'
)
{
*(p+i)=*(q+j);
j++;
i++;
}
printf
(
"%s"
, p);
}
解答:经过代码运行,p所指向的字符串内容为{a,b,c,\0,x,y,z,\0},所以最后运行的结果为输出abc。
或者
12345678910111213141516void
main()
{
char
p[10]=
"abc"
;
char
q[]=
"xyz"
;
int
i,j;
i=0;
while
(*(p+i)!=
'\0'
) i++;
//此时i=3
j=0;
i++;
// i= 4
while
(*(q+j)!=
'\0'
)
{
*(p+i)=*(q+j);
j++;
}
printf
(
"%s"
, p);
}
解答:经过代码运行,p所指向的字符串内容为{a,b,c,\0,z,\0},所以最后运行的结果为输出abc。
2、 写出该代码的功能,并给出改进之处#
12345678910111213141516171819void
main()
{
int
n, x, j, i = 1;
float
sum = 1, k = -1;
printf
(
"Input n and x:\n"
);
scanf
(
"%d %d"
, &n, &x);
while
(i <= n) {
k = -1;
for
(j = 1; j <= i; j++) {
k = -1*k*x;
}
for
(j = 1; j <= i; j++) {
k = k/ j;
}
sum += k;
i++;
}
printf
(
"%f\n"
, sum);
}
解答,该代码的功能为求解1+x+x^2/2! +x^3/3! + ... + x^n/n!
该代码可以通过动态规划进行改进,使得时间复杂度下降至O(n),代码如下:
12345678910111213void
main()
{
int
n,x,i=1;
float
sum = 1,k = -1;
printf
(
"Input n and x:\n"
);
scanf
(
"%d %d"
, &n, &x);
while
(i <= n) {
k = -1 * k*x / i;
sum += k;
i++;
}
printf
(
"%f"
, sum);
}
3、代码for(int i=1;i<n;i++) S;是什么结构?该代码如何使用显示结构表示?
解答:该代码是循环判断选择结构。该代码的显示结构如下:
1234567int
i = 1;
FOR:
if
(i<n)
goto
S0;
goto
S1;
S0: S;
i = i+1;
goto
FOR;
S1: ...
4、根据下面的代码,填写表格。内存按2字节编址,整数占2字节,字符占1字节,指针占4字节。每个区域的相对地址都从0开始。#
1234567891011int
num=2;
//2存储在常量区,num存储在全局区,两个都是整形占2字节。
void
main()
{
char
str1[10]={
"UESTC"
};
//"UESTC"和10存储在常量区,各占6和2个字节
char
*str2=
"CHENGDU"
;
//"CHENGDU"存储在常量区,占8各字节,注意’\0’。
char
p;
//p存储在main区,占1字节。str1和str2存储在main区,str1占10字节,str2占4字节
}
void
func(
int
m)
//m存储在func区,占2字节
{
int
n=10;
//n存储在func区,10存储在常量区,各占2字节。
}
根据出现的顺序,就可以知道相对地址为多少了。每占用两个字节,内存向后偏移一位。
5 填空题#
5.1 给定一个数,给出质数分解结果,例如90=2*3*3*5。#
12345678910111213141516171819int
main()
{
int
n, i=2;
printf
(
"\nInput:"
);
scanf
(
"%d"
, &n);
printf
(
"="
);
i = 2;
while
(n > 1)
{
if
(n%i == 0)
{
printf
(
"%d"
, i);
n = n / i;
if
(n > 1)
printf
(
"*"
);
}
else
i++;
// 如果不能整除时,说明不是其素数
}
return
0;
}
5.2 若100个人围成圈,从第一个人开始,1~3报数,数到3的人退出,求剩下来的人编号是几号#
代码:
123456789101112131415161718192021222324252627282930313233343536373839//求最后剩下的编号
int
main(
{
int
n = 100, num[100];
int
m
/*m为已退出人数*/
,f = 3, i, *p;
p = num;
for
(i = 0; i < n; i++)
//将1~n存入num
{
*(p + i) = i + 1;
}
i = 0;
m = 0;
int
k = 0;
// k是工作指针
printf
(
"杀死顺序为:\n"
);
while
(m < n - 1)
{
if
(*(p + i) != 0)
//碰到元素为0的跳过,说明已经杀死,不再参与计数
{
k++;
}
if
(k == f)
//正好到第f个时,将第f个元素置0
{
printf
(
"%d\t"
,*(p + i));
//输出满足条件的元素
*(p + i) = 0;
k = 0;
//重新开始计数
m++;
}
i++;
if
(i == n)
//当i = 6时,将i置0,循环操作
i = 0;
}
while
(*p == 0)
{
p++;
}
printf
(
"\n最后一个是:%d"
,*p);
return
0;
}
扩展:约瑟夫环问题:【 N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。例如N=6,M=5,被杀掉的顺序是:5,4,6,2,3,1】
代码:
1234567891011121314151617181920212223242526272829303132333435363738394041424344//求最后剩下的号
int
main()
{
int
n, num[100];
int
m
/*注:m为已退出人数*/
,f, i, *p;
printf
(
"n= "
);
scanf
(
"%d"
, &n);
//n是总人数
printf
(
"f= "
);
scanf
(
"%d"
, &f);
//f是第f个杀掉的人
p = num;
for
(i = 0; i < n; i++)
//将1~n存入num
{
*(p + i) = i + 1;
}
i = 0;
m = 0;
int
k = 0;
// k是工作指针
printf
(
"杀死顺序为:\n"
);
while
(m < n - 1)
{
if
(*(p + i) != 0)
//碰到元素为0的跳过,说明已经杀死,不再参与计数
{
k++;
}
if
(k == f)
//正好到第f个时,将第f个元素置0
{
printf
(
"%d\t"
,*(p + i));
//输出满足条件的元素
*(p + i) = 0;
k = 0;
//重新开始计数
m++;
}
i++;
if
(i == n)
//当i = 6时,将i置0,循环操作
i = 0;
}
while
(*p == 0)
{
p++;
}
printf
(
"\n最后一个是:%d"
,*p);
return
0;
}
5.3 带头结点链表逆序 【同2017年24题】#
方法1:取下头结点,然后按照头插法即可实现链表逆序
方法2:后继指针指向前驱结点
6 编程题#
6.1 将给定字符串例如”aaa111bbb222#”中的数字全部提取出来,放到给定的数组中。字符串以#结尾。#
函数形式为void int_find(int arr[], char *pc);溢出以-1作为标志
分析:该题目有一处表述不清,即溢出以-1做为标志。已知C语言无法求出这种情况下的数组长度,所以无法判断数组溢出。综上,该溢出标志可能为数组的最后一个元素,即所有数字查找完毕时以-1结尾。
代码:
12345678910111213141516171819202122232425262728293031323334353637383940#include <stdlib.h>
void
int_find(
char
*pc)
{
int
arr[50] = {0};
char
*p = pc;
// p 是工作指针
int
i = 0;
while
(*p !=
'\0'
)
{
if
(*p >
'0'
&&*p <
'9'
)
{
arr[i]=
atoi
(p);
/*
int atoi(const char *str): 把参数str所指向的字符串转换为一个整数(类型为 int 型),该函数返回转换后的长整数,如果没有执行有效的转换,则返回零,标准库:<stdlib.h>
*/
i++;
//遇到数字后继续进行直到遇到非数字元素
while
(*p >
'0'
&&*p <
'9'
)
{
p++;
}
}
//如果不是数字,则跳过
else
p++;
}
arr[i] = -1;
//最后以-1结尾
//输出arr的值
int
*q = arr;
for
(i = 0;*(q + i) != -1;i++)
{
printf
(
"%d\t"
,arr[i]);
}
}
int
main()
{
char
ch[] =
"aaa111bbb222dsadas2ew2ewq213rf32342r53433#"
;
char
*c = ch;
int_find(c);
return
0;
}
![]()
6.2 随机输入最多100个整数和浮点数,将整数按从大到小排列,浮点数按从小到大排列(浮点数排序可省略),并输出。#
如:输入10 12.3 12 5 52.1 3.65 88.6 1.0 输出:12 10 5 1.0 3.65 12.3 52.1 88.6
分析:这道题目在不借助库函数编程非常困难,也是当年的一道难题。若忽略1.0这样的数字,可以将输入全部视为浮点数,然后判断浮点数可以使用if(int(num)==num)这种方法判断。要实现完美解答,并以最少的时间完成本题,需要借助strstr、atoi、atof三个函数
代码:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778#include <stdio.h>
#include <stdlib.h>
//整数降序排序
void
sort_int(
int
num[],
int
n)
{
int
i, j;
for
(i = 0; i<n - 1; i++)
{
for
(j = i + 1; j <= n - 1; j++)
{
if
(num[j]>num[i])
{
int
temp = num[i];
num[i] = num[j];
num[j] = temp;
}
}
}
//输出整型
for
(i = 0;i < n;i++)
{
printf
(
"%d\t"
,num[i]);
}
}
//浮点数升序排序
void
sort_float(
float
num[],
int
n)
{
int
i,j;
//冒泡排序
for
(i = 0;i < n-1;i++)
{
for
(j = i+1;j <= n-1;j++)
{
if
(num[j]<num[i])
{
int
temp = num[i];
num[i] = num[j];
num[j] = temp;
}
}
}
//输出浮点数
for
(i = 0;i < n;i++)
{
printf
(
"%f\t"
,num[i]);
}
}
int
main()
{
int
intarr[100];
float
fltarr[100];
int
m=0,n,i=0,j=0;
char
buff[100];
printf
(
"input n:\n"
);
//n是几个数
scanf
(
"%d"
, &n);
while
(m < n)
{
scanf
(
"%s"
, buff);
//如果是浮点型数
if
(
strstr
(buff,
"."
))
/*
strstr(str1,str2)函数用于判断字符串str2是否是str1的子串。如果是,则该函数返回 str1字符串从 str2第一次出现的位置开始到 str1结尾的字符串;否则,返回NULL
*/
fltarr[j++]=
atof
(buff);
//浮点数存入fltarr数组
/*
float atof(const char *str)把参数str所指向的字符串转换为一个浮点数(类型为 float型,函数返回转换后的单精度浮点数,如果没有执行有效的转换,则返回零(0.0),标准库:<stdlib.h>
*/
else
//若为整型
intarr[i++] =
atoi
(buff);
//整型存入intarr数组中
m++;
}
printf
(
"排序后:\n"
);
sort_int(intarr, i);
sort_float(fltarr,j);
return
0;
}
6.3 编写完整的程序,构造整数集合,并实现对该集合操作的若干功能:查找集合内的某元素;集合中加入一个新元素;删除集合中某一元素;求两个集合的并集;求两个集合的交集;并给出main函数调用的例子#
分析:该代码等价于构造一个链表,判断某元素是否在链表内,当加入一个元素时,判断该元素是否在链表内,如果不在则插入链表;当删除一个元素时,找到这个元素并删除该节点;输出两个链表的交集,输出两个链表的并集。该题目代码量非常大
代码:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154#include <stdio.h>
#include <stdlib.h>
typedef
struct
node
{
int
data;
struct
node *next;
};
//判断某元素是否在集合内
int
isexist(
struct
node *L,
int
num)
{
struct
node *p = L->next;
while
(p != NULL)
{
if
(p->data == num)
return
1;
p = p->next;
}
return
0;
}
//增加一个元素
void
add(
struct
node *L,
int
num)
{
//头插法,逆序
if
(isexist(L,num) == 0)
{
struct
node *p = (
struct
node *)
malloc
(
sizeof
(
struct
node));
p->data = num;
p->next = L->next;
L->next = p;
}
}
//删除集合中某一元素
void
del(
struct
node *a,
int
num)
{
if
(isexist(a,num) == 0)
{
printf
(
"没有此元素,删除失败!\n"
);
}
struct
node *p = a->next, *pre = a;
while
(p != NULL)
{
if
(p->data == num)
{
pre->next = p->next;
free
(p);
break
;
}
pre = p;
p = p->next;
}
}
//输出链表
void
inputnode(
struct
node *a)
{
struct
node *l = a ->next;
while
(l != NULL)
{
printf
(
"%d\t"
,l ->data);
l = l ->next;
}
}
//输出两个集合并集
void
intersection(
struct
node *a,
struct
node *b)
{
struct
node *p = a->next;
int
flag = 0;
while
(p != NULL)
{
printf
(
"%d "
, p->data);
p = p->next;
}
struct
node *q = b->next;
while
(q != NULL)
{
p = a->next;
flag = 0;
while
(p != NULL)
{
if
(q->data == p->data)
{
flag = 1;
break
;
}
p = p->next;
}
if
(!flag)
printf
(
"%d "
, q->data);
q = q->next;
}
}
//输出两个集合交集
void
Union(
struct
node *a,
struct
node *b)
{
struct
node *p = a->next, *q = b->next;
while
(p != NULL)
{
q = b->next;
while
(q != NULL)
{
if
(p->data == q->data)
{
printf
(
"%d "
, q->data);
break
;
}
q = q->next;
}
p = p->next;
}
}
void
main()
{
struct
node *L = (
struct
node *)
malloc
(
sizeof
(
struct
node));
//L的头结点
struct
node *S = (
struct
node *)
malloc
(
sizeof
(
struct
node));
//S的头结点
L->next = NULL;
S->next = NULL;
printf
(
"输入L:\n"
);
int
temp;
scanf
(
"%d"
, &temp);
while
(temp != -1)
{
add(L, temp);
scanf
(
"%d"
, &temp);
}
printf
(
"输入S:\n"
);
scanf
(
"%d"
, &temp);
while
(temp != -1)
{
add(S, temp);
scanf
(
"%d"
, &temp);
}
printf
(
"输出L:"
);
inputnode(L);
printf
(
"\n输出S:"
);
inputnode(S);
printf
(
"\n删除L中的元素2:\n"
);
del(L,2);
inputnode(L);
printf
(
"\n并集:"
);
intersection(L, S);
printf
(
"\n交集:"
);
Union(L, S);
}
作者:Hang Shao
出处:https://www.cnblogs.com/pam-sh/p/12549561.html
版权:本作品采用「知识共享」许可协议进行许可。
声明:欢迎交流! 原文链接 ,如有问题,可邮件(mir_soh@163.com)咨询.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)