一个菜鸟学习C的路程(一)

 

 

2011年11月19日星期六

今天,下午睡觉的时候,突然间起来看见手机上有两天短息,一条是班长发的,一条是图书馆发的“尊敬的XX读者,您预约的<C语言深度解剖>已归还...”,当时就心情激动,本来还睡意蒙蒙的,马上带上电脑,骑着车去了图书馆。然后去了实验室,看是第二次阅读了,然后...我发现了附录有几道题,它说“请在40分钟...50分一下,请不要气馁...”,好吧,我十几分钟就做完了,并且上面还有好多题目是自己以前在CSDN上看见过的,可是当时竟然蒙了,忘记啦...

 

我承认自己是没有好好的用心去记住!

 

现在贴几个我做错的题目,不知道这样子会不会算是侵权,如果是,还请将本帖删除!!!!自己因为还是学生,这些方面还有些不明白...

 

2、下面代码有什么问题?为什么?

 

void foo(void)

 

{

 

 char string[10],str1[10];

 

 int i;

 

 for( i = 0;i < 10; i++ )

 

 {

 

   str1[ i ] = 'a';

 

 }

 

 strcpy(string, str1);

 

 printf( "%s", string);

 

}

 

我当时是这样子回答的,“没有字符串结束符,一直输出或者报错”,而书上提供的参考答案是这样子的:

 

“运行到strcpy的时候可能会产生内存异常”,其解释是:“因为str1没有结束标识符,str1数组后面继续存储可能不是'\0',而是乱码。printf函数,对于输出char* 类型,顺序打印字符串字符直到遇到空字符'\0'或者打印了由精度制定的字符数为止。”还好,也算是理解到了。

 

5、下面代码的结果是什么?为什么?

 

int main()

 

{

 

 char a[1000];

 

 int i;

 

 for( i = 0; i < 1000; i++ )

 

  a[i] = -1 - i;

 

 printf( "%d",strlen( a ) );

 

 return ( 0 );

 

}

 

我的回答是1000,因为内存一旦分配好了,其大小和具体地址不能再改变,除非重新动态分布。

 

书上提供的答案是这样子的,“255, 按照负数补码的规则,可以知道-1的补码是0xff,-2的补码为0xfe....当i的值为127时,a[127]的值为-128,而128是char类型数据能够表示的最小负数。当i继续增加,a[128]的值肯定不是-129.因为这是发生了溢出,-129需要9位才能够存储下来,而char类型数据只有8位,所以最高位被丢弃。剩下的8位是原来9位补码的低8位的值,即0x7f。当i继续增加到255时,-256的补码的低8位为0,当i继续增加到-256时,-257的补码低8位全为1,即低8位的补码为0xff,如此开始新一轮的循环…

按照上面的分析,a[0]~a[254]里面的值都不为0,而a[255]的值为0.strlen函数是计算字符串长度的,比不包含最后字符串的‘\0’,而判断一个字符串是否到达末尾的标志就是看是否遇见了‘\0’,如遇见则表示字符串结束。”

其实这个题目是看见过的,只不过当时就看看就过去了,可是再次做得时候却不知如何下手了,有点可恨。

7、下面两段代码有什么区别?什么时候需要用代码(2)?

代码(1)

int i = 10;

int j = i;

int k = i;

代码(2)

volatile int i = 10;

int j = i;

int k = i;

这个题目我当时是不会做的,就放弃了。主要是因为volatile没有接触过,就不熟悉了,直接看了答案,“代码1:这时候编译器对代码进行优化,因为在代码1的两条语句中,i没有被用作左值(就是没有被赋值)。这时候编译器认为i的只没有发生变化,所以在第一条语句从内存中取出i的值赋给j之后,这个值并没有被丢弃,而是在第二条语句继续赋给k。编译器不会产生汇编代码重新从内存里取i的值(不会编译生成装载内存的汇编指令,如ARM的LDM指令),这样子提高了效率。但要注意:两条语句之间i没有被用作左值才行。

代码2 :volatile关键字告诉编译器i的值随时可变,每次使用它的时候必须从内存中取出i的值,因此编译器会生成汇编指令重新从内存中取i的值。

代码2的使用时机:如果i是一个寄存器变量,表示一个端口数据或者是多个线程的共享数据,那么就容易出错,所以说volatile可以保证对特殊地址的稳定访问。”

这个确实挺不容易的,因为还没有接触多线程编程,可能还不是很理解,当时我想回用到的,因为接下来我会好好学习linux编程。当时上面的volatile确实用得很少,自己要注意下了。

8、在32位的X86系统下,输出的值为多少?

int main()

{

 int a[5] = {1,2,3,4,5};

 int *ptr1 = ( int *)( &a + 1);

 int *ptr2 = ( int *)( (int)a + 1) ;

 printf( “%x,%x”ptr1[-1],*ptr2 );

return ( 0 );

}

给的答案是5,2 000 000,具体是怎么样子的,也是关于指针的把,先放着,把后面总结完了再来查证。

9、0x01<<2+3的值是多少?为什么?

当时我的答案是,“不确定,移动的位数大于了要求移位的数,其结果是未定义的。”但是答案却给了当头一棒,结果是32,因为“+”的优先级高于<<,则先运算加法,在进行移位计算,这个和我的答案相差也太远了吧,不好!

 

后面的题目也差不多了,我想说的是,学了C大概两年了,可是现在连个80分得水平都没有,这个是有点可悲的呢,当时大学也差不多是这样的,引用几句我们学院牛人的话“老师教的恰好是我们不会用到的,而我们要用到的,确实他不教授的”…是有点可惜的。没关系,明年才工作,还有的机会补救。今天算是第一个步骤,恩!我会一直记录自己的成长历程的,为什么说是成长,因为我已经失败过了,这次一定会成功了!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值