发 帖  
原厂入驻New

[经验] 朱兆祺教你如何攻破C语言学习、笔试与机试的难点(连载)

2013-7-31 08:47:54  184386 C语言 C语言 C语言 C语言 C语言
分享
341
本帖最后由 zzq宁静致远 于 2014-2-27 19:42 编辑

    再过1个月又是一年应届毕业生应聘的高峰期了,为了方便应届毕业生应聘,笔者将大学四年C语言知识及去年本人C语言笔试难点进行梳理,希望能对今年应届毕业生的应聘有所帮助。

2013年10月18日更新-->    攻破C语言这个帖子更新到这里,我不仅仅是为了补充大学学生遗漏的知识,我更重要的是希望通过我的经验,你们实际项目中的C语言写得漂亮,写出属于你的风格。“朱兆祺STM32手记”(http://bbs.elecfans.com/jishu_385613_1_1.html)一帖中我就多次强调过编程的模块化,要考虑到可移植性和别人的可阅读性。我在某公司实习的时候,拿到一个程序,我当时就想吐槽,我想除了这个程序的当时写作者能够看懂之外,其他人有谁还能看懂,程序构架、可移植性性就更是一塌糊涂。结果我全部推到重写。因此明志电子科技工作室从承接第一个项目做开始,我便和搭档说,我们必须制定我们工作室的编程规范和编程风格,这样就算给谁,换成谁,拿到项目都能马上接下去做。
    朱兆祺在这个帖子将会不断更新,明志电子工作室的项目经验也将在电子发烧友论坛不断贴出,我希望能用我们仅有的力量,将我们的经验毫不保留传授给大家。我只希望在未来某一天,有那么几个人会竖着大拇指说:明志电子科技工作室的经验受益匪浅就够了。我相信,在深圳,明志电子科技工作室的影响力会日益增长,因为我们已经规划好了未来脚步。
    C语言是一门技术,但更是一门艺术。写一个c语言代码不难,写一个高水平、漂亮的代码很难。朱兆祺将在此帖不断为大家攻破C语言。

<--朱兆祺于2013年10月18日

-->朱兆祺更新于2014年2月21日:
    深圳市馒头科技有限公司于2014年2月注册成立,当初命名为馒头科技,不管是吴坚鸿所说亲切还是谢贤斌所说草根。馒头科技永远以用户满意为我们的追求,馒头科技不追求锦上添花,但是我们很愿意为每一位客户雪中送炭。因为锦上添花每一个人都会做,但是雪中送炭却不是每一个人愿意去做。
    馒头科技往后将为每一位读者送上更为精美的学习资料。敬请期待。



第一节  C语言编程中的几个基本概念
http://bbs.elecfans.com/jishu_354666_1_1.html

第二节  数据存储与变量
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2088253&fromuid=222350

第三节  数学算法解决C语言问题
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2088283&fromuid=222350

第四节  关键字、运算符与语句
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2088352&fromuid=222350

第五节    C语言中的细节
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2088375&fromuid=222350

第六节  数组与指针
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2088417&fromuid=222350

第七节  结构体与联合体
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2088582&fromuid=222350

第八节  内存分配与内存释放
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2088596&fromuid=222350

第九节   笔试中的几个常考题
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2088606&fromuid=222350

第十节  数据结构之冒泡排序、选择排序
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2092632&fromuid=222350

第十一节   机试题之数据编码
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2096393&fromuid=222350

第十二节  机试题之十进制1~N的所有整数中出现“1”的个数
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2097513&fromuid=222350

第十三节  机试题之  遍历单链表一次,找出链表中间元素
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2103563&fromuid=222350

第十四节  机试题之全排序
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2105648&fromuid=222350


第十五节 机试题之大整数运算
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2109737&fromuid=222350


第十六节  机试题之大整数减法与乘法
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2115675&fromuid=222350

第十七节  算法之二分查找
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2128027&fromuid=222350

第十八节  数据结构之单向链表(颠覆你手中数据结构的三观)
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2139670&fromuid=222350

第十九节  数据结构之双向链表(接着颠覆你手中的数据结构三观)
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2156978&fromuid=222350

第二十节 数据结构之栈
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2193337&fromuid=222350


C语言技术公开课第一讲——编译环境给C语言带来的困扰,网络课程讲义
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2230571&fromuid=222350

第二十一节  通过加减法高效的求出两个无符号整数的商和余数
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2252461&fromuid=222350

第二十二节  表达式计算器(1)
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2280837&fromuid=222350

第二十三节  表达式计算器(2)
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2325485&fromuid=222350

第二十四节  表达式计算器(3)
http://bbs.elecfans.com/forum.ph ... 4547&fromuid=222350

第二十五节  表达式计算器(4)
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2395966&fromuid=222350

C语言技术公开课第三讲  const问题
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2434706&fromuid=222350

第二十六节  序列差最小
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2466868&fromuid=222350

第二十七节  sizeof与strlen的深入
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2676569&fromuid=222350

第二十八节  C与C++中的const

第二十九节 do、while
第三十节 变量的生命周期

第一节  C语言编程中的几个基本概念
1.1      include< >与#include" "


1.   #include< >和#include" "有什么区别
这个题目考查大家的基础能力,#include< >用来包含开发环境提供的库,
#include" "用来包含.c/.cpp文件所在目录下的头文件。注意:有些开发环境可以在当前目录下面自动收索(包含子目录),有些开发环境需要指定明确的文件路径名。
1.2      switch()
1.   switch(c) 语句中 c 可以是 int, long, char, float, unsigned int 类型?
其实这个题目很基础,c应该是整型或者可以隐式转换为整型的数据,很明显不能是实型(float、double)。所以这个命题是错误的。
1.3      const
1.   const有什么用途?
虽然const很常用,但是我相信有很多人仍然答不上来。
(1) 欲阻止一个变量被改变,可以使用const 关键字。在定义该 const 变量时,通常需要对它进行初 始化,因为以后就没有机会再去改变它了;
(2) 对指针来说,可以指定指针本身为 const,也可以指定指针所指的数据为 const,或二者同时指定为 const;
(3) 在一个函数声明中,const 可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值;
(4) 对于类的成员函数,若指定其为 const 类型,则表明其是一个常函数,不能修改类的成员变量;
(5) 对于类的成员函数,有时候必须指定其返回值为 const 类型,以使得其返回值不为“左值”。
1.4      #IFndef/#define/#endif
1.   头文件中的 #ifndef/#define/#endif 干什么用?
其实#ifndef、#define、#endif这些在u-boot、linux内核文件中经常见到,在这么大型的程序中大量使用,可见它的作用不可小觑。
这些条件预编译多用于对代码的编译控制,增加代码的可裁剪性,通过宏定义可以轻松的对代码进行裁剪。
#ifndef/#define/#endif最主要的作用是防止头文件被重复定义。
1.5      全局变量和局部变量
1.         全局变量和局部变量在内存中是否有区别?如果有,是什么区别?
全局变量储存在静态数据库,局部变量在堆栈。 其实,由于计算机没有通用数据寄存器,则函数的参数、局部变量和返回值只能保存在堆栈中。提示:局部变量太大可能导致栈溢出,所以建议把较大数组放在main函数外,防止产生栈溢出。
思考:如程序清单1. 1所示。会出现怎样的情况?
程序清单1. 1  大数组放在main函数中导致堆栈溢出
int main(int argc, char *argv[])
{
    int iArray[1024 * 1024];
    return 0;
}






评分

参与人数 3威望 +7 +7 积分 +10 收起 理由
eminjie + 2 + 2
A670521546 + 5 + 5 很精彩,期待您更多的分享
冰葑世纪 + 5 + 5 您的付出是论坛的动力,感谢您一直支持!.

查看全部评分

zzq宁静致远 2013-8-7 19:16:49
本帖最后由 zzq宁静致远 于 2013-8-7 19:20 编辑

第十六节  机试题之大整数减法与乘法
考虑到有的初学者对第十五节的减法和乘法的疑惑,本节特此将减法和乘法的程序补上。
/******************************************************************************
**  函数名称:BigNumberSub
**  函数功能:大整数的减法运算
**  入口参数:str1:第一个减数
             str2:第二个减数
    ptr:容纳两数之差的空间首地址
    ptrSize:此空间大小
**  出口参数:
******************************************************************************/
int BigNumberSub(const char *str1, const char *str2, char *ptr, int ptrSize)
{
/*
**  iStr1Len:存储第一个字符串
**  iStr2Len:存储第二个字符串
**  iMaxLen :两个字符串中最长的长度
**  i、j    :循环
**  iTemp   :当前位暂存位
**  iBorrow :进位标志位
*/
int   iStr1Len , iStr2Len , iMaxLen , i , j , iTemp = 0 , iBorrow = 0 ;
char  character1 , character2 ;
/* 测量两个字符串的长度 */
iStr1Len = strlen(str1) ;
iStr2Len = strlen(str2) ;
/* 将ptr存储区域的数据全部清零 */
memset(ptr, 0, ptrSize) ;
/* 如果被减数小于减数 */
if ( iStr1Len < iStr2Len ) {
  return 0 ;
}
/* 从高位到低位逐位相减 */
for ( i = 0 ; i < iStr1Len ; i++ ) {
  character1 = str1[iStr1Len - 1 - i] ;
  character2 = (iStr2Len - 1 - i) < 0 ? '0' : str2[iStr2Len - 1 - i] ;
  /* 如果有哪一位不是数字,则退出运算 */
  if ( (!isdigit(character1)) || (!isdigit(character2)) ) {
   return 0 ;
  }
  /* 当前位相减之后的暂存值 */
  iTemp   = (character1 - '0') + 10 - iBorrow - (character2 - '0') ;
  assert(i < ptrSize) ;
  /* 将当前相减位的值转换为字符存入结果 */
  ptr  = iTemp % 10 + '0' ;
  /* 借位位的值 */
  iBorrow = 1 - iTemp / 10 ;
}
assert(i < ptrSize) ;
ptr = '\0' ;
/* 将字符串从高位依次输出 */
for ( j = 0 ; j < i-- ; j++) {
  char cTemp  = ptr[j] ;
       ptr[j] = ptr ;
    ptr = cTemp  ;
}
return 1 ;
}

/******************************************************************************
**  函数名称:BigNumberMul
**  函数功能:大整数的乘法运算
**  入口参数:str1:第一个乘数
             str2:第二个乘数
    ptr:容纳两数之积的空间首地址
    ptrSize:此空间大小
**  出口参数:
******************************************************************************/
int BigNumberMul(const char *str1, const char *str2, char *ptr, int ptrSize)
{
/*
**  iStr1Len:存储第一个字符串
**  iStr2Len:存储第二个字符串
**  iMaxLen :两个字符串中最长的长度
**  i、j    :循环
**  iCarry  :进位标志位
*/
int   iStr1Len , iStr2Len , iMaxLen , i , j , iCarry = 0 ;

/* 测量两个字符串长度 */
iStr1Len = strlen(str1) ;
iStr2Len = strlen(str2) ;
/* 将ptr存储区域的数据全部清零 */
memset(ptr, 0, ptrSize) ;
/* 用数据一的低位到高位逐位和数据二相乘 */
for ( i = 0 ; i < iStr1Len ; i++ ) {
  /* 如果字符串1中有不是数字,则退出 */
  if ( (!isdigit(str1[iStr1Len - 1 - i])) ) {
   return 0 ;
  }
  /* 从低位向高位逐位相乘 */
  for ( j = 0 ; j < iStr2Len ; j++ ) {
   /* 如果字符串2中有不是数字,则退出 */
   if ( (!isdigit(str2[iStr2Len - 1 - i])) ) {
    return 0 ;
   }
   /* 确保相乘之积能存储下 */
   assert((i+j) < ptrSize) ;
   /* 逐位相乘 */
   iCarry += (str1[iStr1Len-1-i]-'0')*(str2[iStr2Len-1-i]-'0')+ptr[i+j] ;
   ptr[i+j] = iCarry % 10 ;
   iCarry /= 10 ;
  }
  /* 处理进位 */
  for ( ; iCarry != 0 ; j++ ) {
   assert((i+j) < ptrSize) ;
   iCarry += ptr[i+j] ;
   ptr[i+j] = iCarry % 10 ;
   iCarry /= 10 ;
  }
}
i = ptr[iStr1Len+iStr2Len-1] ? (iStr1Len+iStr2Len) : (iStr1Len+iStr2Len-1) ;
for ( j = 0 ; j < i ; j++ ) {
  ptr[j] += '0' ;
}
/* 将结果从高位到低位输出 */
for ( j = 0 ; j < --i ; j++ ) {
  char cTemp  = ptr[j] ;
       ptr[j] = ptr ;
    ptr = cTemp  ;
}
return 1 ;
}

    其实大整数的加减乘除法很多公司都喜欢用来作为机试题目,作为今年找工作的亲们得好好看一下。其实笔试和机试都只是一种考核大家能力的形式,或许或多或少可能不能完全衡量一个人,但是企业要在几天内决定是否录用你,考试还是最直接的办法。你要是能通过你的三寸不烂之舌把HR搞定,我朱兆祺也佩服你。或许哪天我会邀请你来做我的首席销售员。呵呵。

回复

举报

苍青的野兽 2013-8-7 19:27:43
学习了,很受用!!
回复

举报

dz1027719307 2013-8-8 06:30:06
赞                                                
回复

举报

haozix521 2013-8-8 13:18:16
9月份考试的孩子们伤不起啊                                             
回复

举报

langlibaidi 2013-8-8 17:31:42
好东西!!!!!!!!!!!!!!
回复

举报

eefon 2013-8-8 20:19:29
{:12:}{:12:}{:12:}{:12:}{:12:}
回复

举报

韦珍 2013-8-9 10:49:37
如果能打包下载的话那该都好啊
回复

举报

valenstory 2013-8-9 21:32:48

好东西,和大家分享了。。。。。。。
回复

举报

◤緈運de涙◥ 2013-8-10 00:55:31
非常感谢楼主!!
回复

举报

zzq宁静致远 2013-8-10 08:20:17
haozix521 发表于 2013-8-8 13:18
9月份考试的孩子们伤不起啊

9月份考试什么?
回复

举报

zzq宁静致远 2013-8-10 08:21:26
苍青的野兽 发表于 2013-8-7 19:27
学习了,很受用!!

四年的总结,如果你们不受用那就是我无能
回复

举报

haozix521 2013-8-10 12:06:09

计算机二级考试                                                                                
回复

举报

zzq宁静致远 2013-8-11 08:14:10
本帖最后由 zzq宁静致远 于 2013-8-11 08:37 编辑

第十七节  算法之二分查找

C语言程序的经典与否很大在于算法是否经典,这一节开始朱兆祺带领大家学习C语言算法篇。
就拿二分查找下手。


// text.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
int BinarySeach(int *iArray, int key, int n)
{
int iLow  = 0 ;
int iHigh = n - 1;
int iMid;
//大家想想这是循环呢?还是递归呢。
while (iLow <= iHigh) {
  iMid = (iHigh + iLow)/2;
  if (iArray[iMid] > key) {
   iHigh = iMid - 1 ;
  }  else if (iArray[iMid] < key) {
   iLow = iMid + 1 ;
  }  else{
   return iMid ;
  }
}
}

//测试程序
int main(int argc, char* argv[])
{
int a[10]={1,2,3,4,5,6,7,8,9,10};
printf("%d\n" , BinarySeach(a,6,10));
return 0;
}

递归调用就是函数对自身的调用,但是一定要慎重使用,递归涉及到栈是否会溢出等问题,还有就是算法是否合适,并非说任何时候都是适合的。
我记得谭浩强的《C……》中用递归算法来解决阶乘的问题,我就疑惑了,使用循环解决岂不是更简单明了。


回复

举报

xp918127 2013-8-11 09:04:54
辛苦大牛了,感谢分享
回复

举报

你丶是我的命 2013-8-11 11:31:24
914121299@qq.com  发一份  谢谢
回复

举报

tialng 2013-8-11 13:03:27
牛 只能说牛 很牛 非常牛
回复

举报

yxk-168 2013-8-11 13:07:57
{:20:}{:20:}{:20:}{:20:}{:20:}
回复

举报

yxk-168 2013-8-11 14:24:58
单片机好难学,,貌似逻辑思维要细。
回复

举报

yxk-168 2013-8-11 20:55:10
此贴不顶对不起楼主与大伙
回复

举报

白发和尚 2013-8-11 20:55:19
好贴!一定要顶!
回复

举报

评论

高级模式
您需要登录后才可以回帖 登录 | 注册

发经验
关闭

站长推荐 上一条 /10 下一条

快速回复 返回顶部 返回列表