C语言面试

首先先看这篇博客,不是我自己的但是能有不少帮助,这里部分算抄袭这位大牛的博客:http://blog.csdn.net/jxnu_xiaobing/article/details/12561141

  • 定义一个宏,宏能判断出两个数中的最小值。
正确答案:
#define MIN(A,B)  ( (A) <= (B) ? (A) : (B) )       
错误答案:
#define MIN(A,B)  (A) <= (B) ? (A) : (B)   或者   #define MIN(A,B)  ( A <= B ? A : B )
  • for循环中括号内各分号前的数据可以省略,但是括号内的分号是不可以省略。
  • 单链表逆序:
循环算法:
LINK_NODE *reverse_link(LINK_NODE *head)
{
    LINK_NODE *next;
    LINK_NODE *previous = NULL;
    while(head != NULL)
    {
        next = head -> next;
        head -> next = previous;
        previous = head;
        head = next;
    }
    return previous;          //到最后previous是头结点,head为NULL
}

递归算法:
才疏学浅。这个链表逆序递归其实并不难要花些时间看,不过是值得的
LINK_NODE *ReverseLink2(LINK_NODE *head)
{
    LINK_NODE *newHead;
    if((head == NULL) || (head->next == NULL))
            return head;
            
    newHead = ReverseLink2(head->next); /*递归部分*/
    head->next->next = head;  /*这段代码相当于”角色互换“:将原本的 A->B 变为 A<-B(B->A) */
    head->next = NULL;        /*将”角色互换“后进一步变换:NULL<- A <-B*/
    
    return newHead;
}

分析:分析递归应从递归的最深层分析,以上程序相当于满足(head != NULL) && (head->next != NULL)将会执行递归,也就是现将最末尾两个节点”角色互换“,然后又一次递归将倒数二、三个节点”角色互换“,依次内推。
  • 在32为编译器下int 4字节,double 8字节,float 4字节,short int 2字节,long int 4字节。
  • strlen是求字符串长度,这个长度不包括结束符'\0'。

  • 指针定义时一定要赋初值,未初始化的指针即是野指针,不安全。

  • 数组的指针(*a)[ ]    指针数组*a[ ]。

  • c中struct结构体中是不能包含函数的,要实现类似功能我们只能用函数指针。但是c++中struct可以含函数

  • '\n' 而不是'/n '。

  • 段错误是多是指针长度不一致导致的。

  • const int &a = b;   其中 & 是引用声明符,表示 a 是 b 的引用,即 a 是 b 的别名,若修改 a 那么 b 的值也会随之改变。其实它们都是指的同一地址的数据,只不过给这个地址取了两个名字。

float b = 1.0f;
int &a = b;
结果是:b = 1,a = 1065353216
  • 带参宏的参数是没有参数类型的。

  • static定义的局部变量只初始化一次,下次进入函数使用该局部变量为上次更改的值。未使用static定义的变量每次进入函数都会初始化一次。

  • volatile:表示某个变量可能被意想不到的改变,这样声明以后编译器每次使用这个变量都会重读这个变量,而不是从备份寄存器中去读取。

  • 涉及宏的地方不要使用++或者--。

  • 裸板中中断是没有参数和返回值的,因为中断都是硬件调用的,没有硬件会给中断函数传参和接收中断的返回值。但是带有操作系统的中断服务程序是允许带参数和返回值的。中断中是不允许浮点数运算的,首先许多编译器和处理器中浮点数是不可以重入的,但是中断会重复执行;其次中断要求短而有效,计算浮点数降低效率。

  • 当表达式中存在有符号数和无符号数时,所有数都自动转换为无符号数。

  • 一个比较有意思的面试题:n!阶乘结尾有多少个零?

  • 计算出n!结果后判断是不行的,结果太大会溢出。正确思路应该是去判断 n~1之间所有数的特点,这之间的所有数统称为“子值”吧。

           n! 结尾零个数的判断:(1)“子值”本身结尾的0的个数。(2)“子值”之间相乘产生的新值结尾的0个数。

           要判断上述两个条件成立:

        (1) 先试想:判断n能被5整除多少次,即n/5就好了嘛,因为这表示"子值"结尾有0 和 "子值"相乘产生0。是否可行看第二点。

        (2) 试想是正确的,但是考虑不周,其只能判断结尾产生一个0的个数,还需要考虑判断结尾产生多个0的情况。来个假设嘛,判断产生1个0的个数只要"n/5",那产生2个0是不是"n/5/5"就好呢?其实就是这么简单的。多个0便依次类推。

        代码如下:

int CountZero(int N)
{
    int ret =0;
    while(N)
    {
        ret+=N/5; 
        N/=5;
    } 
    return ret;
}

分析:上述第一次循环即是N/5,表示:“子值”结尾有1个0 或 “子值”间相乘产生的新值结尾有1个0 的个数。
第二次循环即是N/5/5,表示:“子值”结尾有2个0 或 “子值”间相乘产生的新值结尾有2个0 的个数。剩下的循环依次类推了。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值