实验室考核题解析

6da2b7aa1ca1481cbade266f939e2682.png

 这题,当时做的时候以为四个答案都不对,因为要指向d的话,得后移4次(别忘了\0),然后就盲猜了c,因为ab肯定不对,d我感觉语法不对(没见人用过)

后来经过我的搜索和分析不同代码输出的结果,终于弄懂了~

首先说一下二维数组名是什么:

  • s在表达式中可以作为数组指针使用,它指向第一行的一维数组的首元素,那么s+1就指向第二行的首元素,此时,**(s+1)='c';
  • 但我们在题目中进行了一个强制转换的操作,将p转换为(char*),它就变成了一级指针,s+1就指向了第一行的第二个元素,此时*(p+1)='b'

那么,我们该怎么定义一个指向二维数组的指针呢,若直接用char**p=s,会报错,因为二维数组的数组名不等于二级指针,它其实是指向维度-1的数组指针,在定义时,应为下图(这几种都行):

char(*w)[3] = &s[0];
char(*p)[3] = s;

它指向有三个元素的一维数组,因此[]里为3

在打印时需要解引用两次,因为w或p中储存的是第一行一维数组首元素的地址,解引用一次为s[0],指以s[0][0]为首元素的一维数组,解引用第二次才是s[0][0]的值

A:*(s+3)本质为地址,不能打印出值,而改成**(s+3)后指第四行首元素的地址,但该数组只有两行,因此,此时的*(s+3)为野指针;

B:别忘了上文说到的,p为一级指针,因此p[1][1]的写法是错误的,正确应为p[4];

C:*(p+3)为c,应为*(p+4)或p[4];

D:++的优先级更高,因此先计算++p,*的优先级比+高,因此先为++p解引用,得'b',而'b'+2得'd'(此处为ascii码值计算)

拓展一下:

咱们继续谈谈数组指针,我们数组指针是指向一维数组的指针,因此*p=s[0],(此时默认指向第一行,因此为a[0],其中包括3个元素),而要得到s[0]中的某一个元素,则为下图

    char s[2][3] = { "ab","df"};
    char(*p)[3] = a;
    printf("%c\n", (*p)[1]);
    printf("%c\n", *((*p)+1));

以上代码结果均为'b',若要得到'f',则为下图

    printf("%c\n", (*(p + 1))[1]);
    printf("%c\n", *(*(p + 1) +1));
    printf("%c\n", *(a[1] + 1));

*(p+1)指s[1],*((s[1])+1)指s[1][1],即*(*(p+1)+1)=s[1][1]; 

 冒泡排序最差要执行的次数:

最差的自然是循环到底,设有n个元素需要排序,则外循环有n-1次,内循环有n-1-i次(i为外循环已执行的次数)

因此第一次进来,需要循环n-1次,第二次进来时,已经有一个元素有序,因此只需循环n-2次,按照此规律,后续便是n-3次,n-4次...最后一趟为1次(n-(n-2)-1=1)

总的次数就是n-1+n-2+n-3+...+1=n*(n-1)/2

 4725ee25b89d400db2fe75ceedea1e84.png

写的时候文件只学了一半,而且那一半还不扎实,啥也没记住呢(哭)

这里的fscanf是指将fp中的内容读入到t中,我是傻杯,当时记反了,以为是将t内容移到fp中,就想着t中都没内容,怎么写入,而且也忘了a+可以新建文件(嘤嘤嘤),就有了如上傻瓜操作哈哈哈

因为前面已经将s的内容写入,此时光标移动到最后一个数据的末尾处,因此无法执行读出操作(读取时会读光标后的内容),因此需要将光标移动到初始位置,则使用fwind()函数

714dce5f2872440cb1a794490cc28b75.png

 害,看到我写的就来气,我是大傻子,忘记负数的存储形式是补码,还有!正数的补码就是它自己(在计导考试里狠狠地栽了好几个跟头,不懂,这么基础的东西居然会错,我真菜)

因为要得到int的最小值,就是要得到一个100000...的二进制

最初我的想法就是定义一个负数,然后右移31位,因为右移会补符号位,因此就可以得到32个1(这里以int为32位做例子),但我忘了-1是以补码储存,也忘了最终要将补码转化为原码才是该值的大小,我天真的以为我得到了1111...1就得到了int的最小值(跪倒)

所以,经过我的网上搜索,要得到int的最小值,就是将+1左移31位,得到1000...0,其实,补码本身没有符号位,是过去的人发现了补码最高位和原码的符号位是一致的,因此就认为补码最高位是符号位,其实!它是数值位,假设有4位二进制数,-2的原码为1010,补码为1110,若我们将1110全部计入计算,为14,而14+2=16,恰好等于2^4,因此补码只是将负数根据某一运算规则转化为正数罢了

那么,int的最小值是-2^31,其有32位,对应补码就是2^32-2^31=2^31,即1000...0(这里1的权重就是2^31哟)

因此,我们需要得到这样的一串二进制序列,如何得到呢,就是将+1左移31位,左移是右边补0,得到后经转换为原码,可得int的最小值

349a33a1d0134b4c8e3218452fbbf72a.jpg

 是看的这一篇文的思想,推荐你们一定要看看!!!

写完啦~昨天到现在摆烂了一天,只写了这一篇博客,希望可以给你一些帮助,如果可以,也希望你们可以给我一些建议,很感谢你们看到现在,撒花🌸

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值