1、与192.168.1.110/27不属于同一个子网的主机地址有(ACD)
A、192.168.1.50
B、192.168.1.100
C、192.168.1.150
D、192.168.1.200
解析:
(1)该网络的网络前缀
是多少?
答案:27
解析:192.168.1.110/27 加粗部分就是网络前缀
(2)该网络的子网掩码是多少?
答案:255.255.255.224
解析:子网掩码是根据网络前缀推算的,255.255.255.224 转换成二进制表示为11111111.11111111.11111111.11100000,网络前缀代表的是该地址的网络位
,前面说到一个IP地址是由32位二进制数表示的
,网络前缀为27就表示从左往右数前27位为该网络的网络位,剩下的后5位为该网络的主机位。而 子网掩码就是网络位全为1,主机位全为0 。
(3)子网地址为多少?
答案:192.168.1.96
解析:IP地址与子网掩码进行按位与
运算得到 子网地址。11000000.10101000.00000001.01101110 和11111111.11111111.11111111.11100000 按位与,得到11000000.10101000.00000001.01100000=192.168.1.96
(4)广播地址?
答案:192.168.1.127
解析:子网掩码取反
后与子网地址进行或
运算就可以得到广播地址。 00000000.00000000.00000000.00011111 和 11000000.10101000.00000001.01100000 按位或,得到 11000000.10101000.00000001.01111111=192.168.1.127
(5)子网范围
192.168.1.110/27 子网范围为[192.168.1.97, 192.168.1.126]
。96和127分别是网络地址和广播地址。
2、在使用浏览器打开一个网页的过程中,浏览器使用到的网络协议有(ABC)
A、DNS
B、TCP
C、HTTP
D、Telnet
3、UDP的报头不包括(ABC)
A、目的地址
B、窗口大小
C、序列号
D、校验和
解析:
UDP报头由4个域组成,其中每个域各占用2个字节
,具体如下:
源端口号
目标端口号
数据报长度
校验值
4、为什么进程切换代价比线程切换要大?(D)
A、因为进程切换要切换控制块数据结构
B、因为进程切换要切换栈
C、因为进程切换要切换PC指针
D、因为进程切换要切换段表
解析:线程也要切换栈、PC指针、控制块数据结构?
5、初始值为M的信号量,当前值为-2表示的含义是什么?(B)
A、当前有M个任务正在等待信号
B、当前有2个任务正在等待信号
C、当前有M个任务正在持有信号
D、当前有M+2个任务正在持有信号
解析:信号量表示的是可用的资源数
。初值为M,表示初始时有M个可用的资源。现在为-2,说明这M个可用资源已经被占用了,而且有 2 个进程在等待资源,所以就为-2了。
6、当系统umask设置为242,那么创建一个新文件后,它的权限是(B)
A、rw- r-- rw-
B、r---w-r--
C、r-x -wx r-x
D、r-x -wx rwx
解析:umask是从权限中“拿走”相应的位,且文件创建时不能赋予执行权限。
创建时,文件 默认666,目录默认777,减去umask的位就是结果。
666 - 242 = 424,r-- -w- r–(r:4,w:2,x:1)
7、如下的C程序代码块存在哪些问题(A)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MEM_LEN 100
char *ptr=NULL;
int malloc_test() {
int ii=0;
for(ii=0;ii<10;ii++){
ptr=(char*)malloc(MEM_LEN);
memset(ptr,0x00,MEM_LEN);
//printf("%d\x20", *ptr);
}
free(ptr);
return 0;
}
A、申请内存后未做非空判断
B、存在内存泄漏
C、存在野指针(选?)
D、返回数据类型错误
解析:
“0x00”意思是:十进制数字0。
“0x00”是十六进制数。
参考:https://blog.csdn.net/weixin_47792933/article/details/118968469
(1)malloc和free这两个函数总是成对出现的
,一个开辟内存,一个释放内存,这两个函数的单独使用极有可能会导致程序出错
。
malloc的返回值一定要做检查!!!
(2)free函数释放内存空间后,并不会将接受开辟空间起始地址的的指针置为空指针
。
malloc开辟空间后,free函数释放P指向的内存空间,但不会把p指针里面地址的内容释放
,这可能就会造成,p又通过地址访问之前的内存空间,造成内存非法访问
,所以一定要手动的把把P置为NULL。
(3)void *memset(void *s, int ch, size_t n);
函数解释:将s中当前位置后面的n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s 。
通常为新申请的内存做初始化工作
。
8、以下链接的描述中,正确的是(ABC)
A、一个静态库中不能包含两个同名全局函数的定义
B、一个动态库中不能包含两个同名全局函数的定义
C、如果两个静态库包含一个同名全局函数。它们不能同时被链接
D、如果两个动态库包含一个同名全局函数。它们不能同时被链接
解析:
9、C程序的输出
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
unsigned char a,b;
a=0x0f;
b=(~a)>>4;
printf("b=0x%02x\n",b);
return 0;
}
结果:b=0xff
解析:a=0x0f,十进制为15,转为二进制为 00000000000000000000000000001111
~a:a的二进制值取反
。
所以,~a=11111111111111111111111111110000
(~a)>>4:a右移4位(会转为有符号位再进行移位。因为最高位为1,故而是负数
),即为 11111111111111111111111111111111,转为16进制为 0xffffffff。
%02X
:x 表示以十六进制形式输出;02 表示不足两位,前面补0输出;
10、以下说法正确的是(ABCD)
A、数据段保存在目标文件中
B、BBS不保存在目标文件中
C、文本段容易受到编译优化选项的影响
D、可执行文件的大小受到是否调试(debug)编译的影响
11、在一个以HL为头的单链表中,若要在指针q指向结点的后面插入一个由指针p所指向的结点,以下哪个选项可以完成此需求?(D)
A、q->next=p->next;p->next=q;
B、p->next=q->next;q=p;
C、q->next=p->next;p->next=q;
D、p->next=q->next;q->next=p;
12、以下初始化正确的是(BC)
A、char *p_a={‘a’,‘b’,‘c’}; (应该修改为:char p_a[] ={'a','b','c'}; 或 char p_a[] ={ {'a' },{ 'd' },{ 'e' } };
)
B、char *p_b[3]={{"ab"},{"cd"},{"ef"}}; 等价于 char *p_b[3]={"ab","cd","ef"};
C、char arr[][3]={"ab","cd","ef"};
D、char arr[3][]={“ab”,“cd”,“ef”};
解析:花括号的作用就是打包
,使之形成一个整体。
13、程序的输出结果
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char s[]="\\123456\n\123456\t";
printf("%d\n",strlen(s));
return 0;
}
结果:13
解析:"\123456\n\123456\t"相当于{’\’,‘1’,‘2’,‘3’,‘4’,‘5’,‘6’,’\n’,'\123'
,‘4’,‘5’,‘6’,’\t’}
‘\’为转义符,转义字符用反斜杠\后面跟一个字符或一个八进制或十六进制数表示
。
参考:https://blog.csdn.net/qq_43041053/article/details/118726778
14、代码运行结果
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char *s= "abcdef";
s+=2;
fprintf(stderr,"%d\n",s);
return 0;
}
输出:字符’c’的地址
15、合法的赋值语句
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char *s1="hello world";
char s2[]="hello world";
//s1[2]='E'; //错误
s2[2]='E'; //正确
//*(s1+2)='E'; //错误
*(s2+2)='E'; //正确
printf("%s",s2);
return 0;
}
结果:
heElo world
解析:
C++存储空间的分配这样的:
1.栈–用来存储自动变量
;
2.堆–程序员可以自由申请的内存
,不过用后要释放;
3.全局区–用于存储静态变量
,全局变量
以及文字常量
;
4.代码区–用于存储程序的二进制代码
;
因此,全局变量是存储在全局区的,由于全局数组肯定是全局变量了,所以存储在全局区,局部数组是自动变量
,就存在栈中。
char *s1 = “hello,world”,在内存中s1指针变量存储在栈区
;
而“hello,world”存储在常量区
,常量是不能被改变的
char *s1=“hello”:是一个
字符串常量
,你可以像一个字符数组一样使用它
,但是你不能更改这个字符串的值
。
比如 s1[2] = 'e’这样不行,s1 放在全局数据区
。
char s2[]=“world”:是一个
字符串变量
,可以被修改
,s2 是函数的栈空间区域
,函数执行完成,这个空间就没了
。
这两者在作 函数的形参 的时候是 完全等价 的。
void function(char *s1);
void function(char s1[]);
可以相当绝对的说这两种完全等价,没有任何区别。
参考:https://blog.csdn.net/dongqihai/article/details/97523117
16、哪句有错
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
int a[5]={0}; // 将数组a中的5个元素初始化为0
int *p=a;
//a++; // 错误
p++;*p=5;
for(int i=0;i<5;i++)
printf("%d",a[i]);
return 0;
}
结果:
05000
解析:
(1)int a[5]={0 * 5}; 这个表达为什么错误?
答:数组初始化赋值是 编译过程中 做的
,0 * 5是计算,程序执行过程中执行
,这语法不对,
应该是下面的语法:int a[5]={0}; 等价 int a[5]={0,};
(2)数组名++,为什么错误?
答:当a为数组名时,可以当做一维指针
进行取值运算,但是由于数组名等同于常量指针
,所以不可以对数组名进行赋值运算
。
所以当a为数组时, a = 任意表达式
这样的计算都是非法的
。
而a++,等效于a=a+1
, 所以这种表达式一样是非法的
,编译的时候会报错。
17、运行结果
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
int a[2][2]={{1,2},{3,4}};
int (*p)[2]=a;
printf("%d",*(*p+1));
return 0;
}
结果:2
解析:int (*p)[2](数组指针,指向数组的指针
):指针变量p是一个指向包含有两个 int 元素的数组的指针。
*p:列指针
p:行指针
18、运行结果
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void func1(int a){
printf("func1 %d\n",a);
}
void func2(int b){
printf("func2 %d\n",b);
}
int main() {
void(*p[])(int)={func1,func2};
p[1](2);
return 0;
}
结果:func2 2
解析:
*p[]=*p([])
,指针数组。首先,它是一个数组,数组里面保存的是指针。
(*p)[]
,数组指针。首先它是一个指针,然后,它指向一个数组,但通常,在定义的时候需要指定所指向数组的大小
。
19、设有变量说明与函数说明为int a[10],b,c;int fun(int a[],int b);,则以下合法的函数调用语句是(A)
A、c=func(a,b);
B、func(a,b)=c;
C、c=func(a[],b);
D、c=func(a[10],b);
20、定义数组int A[4][5];若将其作为参数传入函数中,则对应的形参可以定义为(AD)
A、int(*s)[5]
B、int *s[5]
C、int B[4][]
D、int B[][5]
21、在32位机器中,运行如下程序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void welcome(char acWeI[]){
printf("%d",sizeof(acWeI));
}
int main(int argc,char **argv) {
char acWeI[]="Welcome to Skyworth";
welcome(acWeI);
return 0;
}
结果:4
解析:数组名作为参数传递给函数时,退化为指针
,计算的是指针的大小。需要数组大小时, 需要一个参数传数组名
,另一个传数组大小
。
22、运行结果
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int sub(int a,int b){
if(a<b)
exit(0);
return (a-b);
}
int main(int argc,char **argv) {
int x=0,y=0,z=0;
x=sub(3,2);
printf("x=%d",x);
y=sub(3,3);
printf("y=%d",y);
z=sub(2,3);
printf("z=%d",z);
return 0;
}
结果:
x=1y=0
解析:
exit()就是退出,传入的参数是程序退出时的状态码,0表示正常退出,其他表示非正常退出。
退出程序,括号中的0表示程序的退出返回代码,无实际意义。exit()就是退出 , 0就是返回的参数, 也可以返回 1 、-1 等 你可以用来判断函数是否正确返回。
23、对于以下程序的描述,错误的是(ACD)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
printf("%p\n",main);
return 0;
}
//结果:
//32位中:00641299 (32 / 4 = 8位16进制 )
//64位中:00007FF743FB1154(64 / 4 = 16位16进制)
A、程序会编译错误
B、程序执行时会打印输出 main 函数的地址(正确)
C、程序执行时会陷入死循环,最终会crash
D、程序会打印一个随机值
参考:https://blog.csdn.net/i_pangpang/article/details/80261647
printf 函数族中对于%p一般以十六进制整数方式输出指针的值,附加前缀0x
。
24、在32位小端系统中定义typedef struct st_task{short id;int value;long timestamp;}st_task;,以下函数的输出是()
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct st_task {
short id; // 2B
int value; // 4B
long timestamp; // 4B
}st_task;
int main(int argc, char **argv) {
st_task task;
long a = 0x12010023;
printf("%d\n",sizeof(st_task));// 12
memset(&task, 0, sizeof(st_task));// 初始化
printf("%d\n",sizeof(a)); //4
memcpy(&task,&a,sizeof(a));
printf("0x%x,0x%x,0x%x\n",task.id,task.value,task.timestamp);
return 0;
}
结果:
12:3 * 4=12
4
0x23,0x0,0x0
解析:
void * memcpy(void * str1, const void * str2, size_t n)
作用:从存储区 str2 复制 n 个字节到存储区 str1
str1:指向用于存储复制内容的目标数组,类型强制转换为 void * 指针
str2:指向要复制的数据源,类型强制转换为 void * 指针
n:要被复制的字节数
返回值:该函数返回一个指向目标存储区 str1 的指针
故而:
memset(&task, 0, sizeof(st_task));产生的结果是:
task.id=0; // short——2
task.value=0; // int ——4
task.timestamp=0;// long ——4
memcpy(&task,&a,sizeof(a));产生的结果是:
从 a 中复制 4个字节(4*8=32位)到 task 中
long a = 0x12010023; 占4个字节,即
23
00
01
23
因为位对齐,虽然 short id; 只占2字节,但还有2字节剩余,共4字节。即4个字节之后才存放int value;,故而:
取long a在内存中的前两个字节作为 short id 的值,即为0x0023。
参考:http://c.biancheng.net/view/2035.html
25、在32位小端系统中:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef union { // 共用体
char id[4]; // 4B
long long data; // 8B
}list;
typedef struct { // 结构体i
int *ptr; // 4B
list cur_data; // 8B
}Sdata;
int main(int argc, char **argv) {
printf("%d\n",sizeof(list)+sizeof(Sdata));
return 0;
}
结果:24
解析: 8 + 8*2=24
26、判断
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
unsigned char index;
char array[] = "123456789";
for (index = strlen(array) - 1; index >= 0; index--) {
printf("%c ",array[index]);
}
printf("\n");
return 0;
}
结果为:987654321。错误
解析:strlen(array)=9
unsigned char
index; 注意!!
27、判断
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char *s1 = "hello";
char *s2 = "world";
char *s3 = strcat(s1,s2);
return 0;
}
答案:空间问题。错误
28、判断
int a[] = { 1,2,3,4,5,6,7,8,9 };
for (int i = 0; i < sizeof(a); i++) {
a[i] = i;
printf("%d ", a[i]);
}
printf("\n");
return 0;
结果:
解析:sizeof(a)=9 * 4=36(长度 * 类型)
超出了数组限制。
29、代码输出
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
int a[5] = { 1,2,3,4,5};
int *ptr = (int *)(&a + 1);
printf("%d,%d\n ", *(a+1),*(ptr-1));
return 0;
}
输出:2 5
解析:*(a+1)=a[1]
&a+i = a + i * sizeof(a);
a+i = a +i * sizeof(a[0]);
参考:https://www.cnblogs.com/xiaodingmu/p/7200867.html
30、二分查找算法,从长度为200的升序整数序列中用查找二分查找算法查找某数,最坏情况下需要比较的次数是7次(错误)
解析: 对有序数组进行查找,一般采用折半查找,也叫二分查找。二分查找的最大比较次数,或者查找
一个数组中不存在的数据
的最大比较次数:log2n + 1
log2n + 1 = log2200 + 1 = 8
参考:https://blog.csdn.net/weixin_43476037/article/details/102733392
31、优先级
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
int a = 4;
a += a*a << 1+2;
printf("%d\n ", a);
return 0;
}
结果:132
解析:运算符的优先级 高于 移位运算符
。
优先级:乘(*) > 加(+) > 位移(<<)
32、宏运算
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SUM(a,b) (a)+(b)
int main() {
int x = 2,y=5;
printf("%d\n ", SUM(x++, 10)*SUM(y--, 10));
return 0;
}
结果:62
解析: SUM(x++, 10)*SUM(y–, 10)=(x++)+10 * (y–)+10=(2)+10 * (5)+10=2+50+10=60,之后x=3,y=4。
33、使用基数排序对十进制正整数序列123,981,12,98,5进行升序排序,低位优先,堆数为10,排序过程中可能的中间序列为()
参考:https://blog.csdn.net/u014231646/article/details/80267468