管理网站模板下载免费下载,微信公众平台和微网站的区别,河南推广网站的公司,wordpress 设置文件学习完c语言#xff0c;需要对所学知识进行一个检测#xff0c;下面有一套笔试题#xff0c; 你有四十分钟进行检测#xff0c;每道题五分#xff0c;严格要求自己打分。
根据作者原话#xff1a;在没有何提示的情况下,如果能得满分,那你可以扔掉本书了,因为你的水平已经…学习完c语言需要对所学知识进行一个检测下面有一套笔试题 你有四十分钟进行检测每道题五分严格要求自己打分。
根据作者原话在没有何提示的情况下,如果能得满分,那你可以扔掉本书了,因为你的水平已经大大超过了作者;如果能得80分以上,说明你的C语言基础还不错,学习本书可能会比较轻松;如果得分在50分以下,也不要气馁,努力学习就行了;如果不小心得了10分以下,那就得给自己敲敲警钟了;如果不幸得了0分,那实在是不应该,因为毕竟很多题是很简单的。 答案解析 1.根据隐式类型转换存储规则
long double
double
float
unsigned long int
long int
unsigned int
int
当连个不同类型的值比较或相加减时默认从低到高转换即向上转换所以a和b相加时b会隐式转换成unsigned int类型对于-20来说,其补码为
100000000 00000000 00000000 00010100 -- 原码
1111111111 111111111 111111111 11101011 -- 反码
1111111111 111111111 111111111 11101100 -- 补码此时b是无符号整型首位不再被当成符号位所以b成了一个很大的数字加上a当然比6大。 2.运行到strcpy的时候可能会发生异常因为str1存储了10个字符a之后后面存储的不是’\0’ strcpy拷贝时会寻找’\0’作为结束标志str1中第10个字符a之后的空间不是str1的是内存的空间 strcpy从此地方开始向后寻找’\0’时会造成内存的非法访问可能会导致程序出现异常。 3.i 10j 1. 由于静态的局部变量是再内存中的静态区存储静态局部变量在初始化一次后不会被销毁且只初始化一次在下一次使用时仍然保持上一次的值。所以i只初始化一次每次继续调用该函数时仍然保留上一次i的值。 对于j来说j是静态全局变量每次调用函数都会被初始化. 4.除了(3)是400以外其余全都是4。 1p是指针被置为空 所以p所指向的地址就是一个空地址既然是地址题目限定了在32位系统下所以就是4个字节。 2p其实就是对p进行解引用p是所指向的对象是一个int类型计算p其实就是计算int类型的大小。 3对于数组来说数组名表示数组首元素地址除了下面两个例外 1.sizeof(数组名)即数组名单独放在sizeof内部表示的是整个数组的大小。 2.数组名取到的是整个数组的地址。 除了上面两个特例其余的数组名都是表示数组首元素地址。
很明显3中的数组名单独放在sizeof内部计算的就是整个数组大小a数组有100个元素每个元素是int类型总大小就是400字节。 4a[100]就是计算a的第100个元素的大小虽然a[100]并不存在也不影响计算a的第100个元素的大小也是一个int类型。比如说int b[1] {0}; 计算sizeof(b[10])大小仍为4个字节。
5a是上面两个特例中的第二个特例取到的是整个数组的地址其实整个数组的地址就是首元素的地址只是如果取到整个数组的地址后1会跳过整个数组。 既然它是地址地址就是4个字节。 6a[0]就是取首元素地址是地址就是4字节。 7这是一个典型的数组传参问题b传参时因为b是数组首元素地址本质上传的是一个int*的指针形参部分int b[100]实际上这是一个指针所以计算b的大小就是计算指针的大小即4个字节。b不再是数组首元素地址b是一个指针 5.对于数组a来说它的元素类型是signed char类型范围是-128~127。a[0] -1,a[1] -2,…a[127] -128,此时a[128]不可能是-129因为 -128的二进制原码是
100000000 00000000 00000000 10000000补码是
11111111 11111111 11111111 10000000存入a[127]中会发生截断补码的低8位放进去即 10000000放入转化成原码为
1 00000000 而该原码规定就是-128。
而-129的二进制原码为
100000000 00000000 00000000 10000001补码为
11111111 11111111 11111111 01111111截取低8位存入a[128]中是
01111111转换成二进制原码是
01111111这是正数正数的原码反码补码相同转换成十进制是127. 所以a[128] 127, a[129] 126… ,直到a[255] 0; strlen计算长度时就需要找’\0’作为结束标志而0就代表’\0’。所以计算数组的长度时大小为255. 6.1const放在p之前限制的是 * p,所以p不可更改但是p未被限制所以p指向的对象可以更改。 2同1同样放在*p之前结果同1 3const放在p之前p之后限制的是p所以p指向的对象不可更改p可以更改 4p和p都被限制了所以p指向的对象和p都不可更改。 7.代码(1):这时候编译器对代码进行优化,因为在代码(1)的两条语句中i没有被用作左值(没有被赋值)。这时候编译器认为i的值没有发生改变,所以在第1条语句时从内存中取出i的值赋给j之后,这个值并没有被丢掉,而是在第⒉条语句时继续用这个值给k赋值。编译器不会生成出汇编代码重新从内存里取i的值(不会编译生成装载内存的的汇编指令﹐比如ARM的LDM指令)这样提高了效率。但要注意:两条语句之间i没有被用作左值(没有被赋值)才行。 代码(2)的使用时机:如果i是一个寄存器变量、表示一个端口数据或者是多个线程的共享数据,那么就容易出错,所以说 volatile可以保证对特殊地址的稳定访问。 代码(2)的使用时机:如果i是一个寄存器变量、表示一个端口数据或者是多个线程的共享数据,那么就容易出错,所以说 volatile可以保证对特殊地址的稳定访问。 8.这道题需要画图理解。结果是 52000000 数组a的5个元素的十六进制表示形式在内存中的布局如上图 对于ptr1来说a取到了整个数组的地址1跳过了整个数组再强转成int*所以ptr1指向的是数组的后一位的地址。如下图 以16进制的形式打印ptr[-1]时其实可以理解成打印 *(ptr-1)指针-1跳过指针所指向对象的类型ptr1指向的对象是int类型所以-1跳过一个int。如下图 指针指向的对象是一个int类型所以一次取出4个字节。 由于计算机是小端存储模式所以低位放在低地址处高位放在高地址处拿出来就是 00 00 00 05以十六进制的形式打印5前面的0是不显示的没什么意义所以打印出来就是5。
对于ptr2来说a是数组首元素地址强转成(int)所以a的地址就被强转成了一个整型假设a的地址为0x0012ff40,该地址就被强转成了一个整型此时0x0012ff40是一个整型整型1之后就是0x0012ff41加了一个字节整型1就是1。0x0012ff41再强转成一个int*的指针赋给ptr2。此时ptr2指向的位置如下图 ptr2指向的对象是int类型所以ptr2一次性会读取4个字节即读取 00 00 00 02由于计算机是小端存储低位放在低地址高位放在高地址。
所以以十六进制的形式表示是0x 02 00 00 00以十六进制的形式打印出来是2 00 00 0002中的0会被去掉 9.值为32 号的优先级高于,先计算23再计算0x01 即 0x015 将0x01的十六进制补全是 0x00 00 00 01转换成二进制的形式为
00000000 00000000 00000000 00000001操作符移动的是二进制位左移5位后变成
00000000 00000000 00000000 00100000转换成十进制是32 10.答案
#define SQR(x) ((x)*(x))然而该宏是有缺陷的如果传入xx这样有副作用的参数宏就会出现问题。
指出宏有缺陷者满分 11.结构体在内存中的存储较为复杂具体请看 结构体内存对齐 这里直接说明答案即可 在未说明的情况下默认对齐数为8 代码1的结构体大小为12字节代码2的结构体大小为8字节。 12.实际上这道题目是存在一点问题的实际中不能随便找一个地址就对该地址的内容进行访问这是野指针问题是非法访问的问题对编译器来说这是违法行为。 相当于题目让你闯红灯闯红灯本来就是违法行为。这里没有针对任何人只是就本道题说一下我的看法
可能题目是想让写题人知道指针的强大和灵活让写题人重视指针的运用。
不过如果真的要写就是下面的写法
int *p (int*)0x12ff7c;
*p 0x100;13. a表示数组首元素地址a1跳过了一个元素的大小所以a1就是a[1]的地址*(a1) 就拿到了a[1]所以结果是1。 对ptr来说a取到的是整个数组的地址1跳过了整个数组所以ptr指向了元素5的后一位 * (ptr-1) 就指向5打印出来就是5。 14. 0x100014,0x100001,0x010004 (1) 首先需要知道结构体的大小是多少由上面结构体内存存储模式可知该结构体大小为20字节。 p是一个结构体指针指针0x1跳过了一个结构体的大小所以p1跳过了20字节因为p的值为0x100000,所以p1为0x10001420转换为十六进制是14。 (2) 将p强转成unsigned long类型后p的值就是一个长整型即0x100000是unsigned long类型整型1就是1. 结果为0x100001
(3)将p强转成unsigned int*的指针1后跳过一个int类型所以结果为0x100004 15.考察逗号表达式。 (0,1)计算的结果是1(2,3)计算结果是3(4,5)计算结果是5 a初始化后的结果为
1 2
5 0
0 0a[0]就是第一行元素的地址此时p就是指向第一行元素的地址然后打印p[0]相当于找到了第一行第一个元素打印结果为1 16.1传参的时候有问题b[10]实际上是不存在的。 2fun的参数部分如果它是想对数组的a[3]进行修改传参应该传b即可因为b是数组名数组名表示首元素地址类型是char* 想改变它的值应该使用char*的指针来接收。
编译器会有一个警告说类型不匹配因为b[10]的类型是char而函数参数类型是char*。 17.1在使用完pstu后没有置空这是一个野指针问题。 (2)结构体的成员name也是一个指针代码并没有给该指针申请空间直接使用name会出现越界访问问题。 18典型的递归问题直接上答案
0
1
2
5
1019. getchar函数的返回类型是一个int但是c是一个char类型将一个int类型放入char类型中会发生截断。‘ 假如读取失败getchar会返回EOFEOF是一个宏其本质是-1 但有可能getchar读取失败返回的EOF不再-128~127这个范围内导致if条件判断语句不进入存在潜在的危险。 20.方法1
int main()
{int a 1;int ret *((char*)a);if (ret 1){printf(小端\n);}else{printf(大端\n);}
}方法2
union un
{int a;char c;
}s;int main()
{s.a 1;if (s.c 1){printf(小端\n);}else{printf(大端\n);}return 0;
}在没有何提示的情况下,如果能得满分,那你可以扔掉本书了,因为你的水平已经大大超过了作者;如果能得80分以上,说明你的C语言基础还不错,学习本书可能会比较轻松;如果得分在50分以下,也不要气馁,努力学习就行了;如果不小心得了10分以下,那就得给自己敲敲警钟了;如果不幸得了0分,那实在是不应该,因为毕竟很多题是很简单的。