C语言学习篇(程序类)


  1. 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)
    #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL 
    注解:
    1)#define 语法的基本知识(例如:不能以分号结束,括号的使用,等等);
    2)直接写出你是如何计算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的;
    3)意识到这个表达式将使一个16位机的整型数溢出-因此要用到长整型符号L,告诉编译器这个常数是的长整型数;
    4)如果你在你的表达式中用到UL(表示无符号长整型),那么你有了一个好的起点。记住,第一印象很重要。

  2. 写一个"标准"宏MIN ,这个宏输入两个参数并返回较小的一个
    #define MIX(A,B) ( (A) <= (B) ? (A) : (B) )

    注解:
    1)三重条件操作符的知识。这个操作符存在C语言中的原因是它使得编译器能产生比if-then-else更优化的代码;使用括号。

  3. 预处理器标识#error的目的是什么?
    答:#error 停止编译并显示错误信息。

  4. 用变量a给出下面的定义
    1)一个指向指针的的指针,它指向的指针是指向一个整型数;int **a;
    2)一个指向有10个整型数数组的指针;int (*a)[10];
    3)一个指向函数的指针,该函数有一个整型参数并返回一个整型数;int (*max_function)(int a);
    4)一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数;int (*a[10])(int);

  5. 给定一个整型变量a,写两段代码,第一个设置a的bit 3,第二个清除a 的bit 3。在以上两个操作中,要保持其它位不变。(位操作题)
     

    #define BIT3 (0x01<<3)
    static int a;
    void set_bit3(void)
    {
        a |= BIT3;
    }
    
    void clear_bit3(void)
    {
        a &=~BIT3;
    }

    6.设置一绝对地址为0x67a9的整型变量的值为0xaa55。(固定内存操作题)

int *ptr;
ptr = (int*)0x67a9;
*ptr = 0xaa55;

7. 中断是嵌入式系统中重要的组成部分,这导致了很多编译开发商提供一种扩展——让标准C支持中断。具代表事实是,产生了一个新的关键字__interrupt。下面的代码就使用了__interrupt关键字去定义了一个中断服务子程序(ISR),请评论一下这段代码的。

__interrupt double compute_area (double radius)  

{

double area = PI * radius * radius;

 printf("\nArea = %f", area);

return area;

 }

这个函数有太多的错误了,以至让人不知从何说起了:

1)  ISR 不能返回一个值。如果你不懂这个,那么你不会被雇用的。

2) ISR 不能传递参数。如果你没有看到这一点,你被雇用的机会等同第一项。

3)   在许多的处理器/编译器中,浮点一般都是不可重入的。有些处理器/编译器需要让额处的寄存器入栈,有些处理器/编译器就是不允许在ISR中做浮点运算。此外,ISR应该是短而有效率的,在ISR中做浮点运算是不明智的。

4)  与第三点一脉相承,printf()经常有重入和性能上的问题。如果你丢掉了第三和第四点,我不会太为难你的。不用说,如果你能得到后两点,那么你的被雇用前景越来越光明了

请找出下面代码中的所有错误 (题目不错,值得一看)  //说明:以下代码是把一个字符串倒序,如“abcd”倒序后变为“dcba”  

#include"string.h"   
int main(void)   
{   
	char* src="hello,world";   
	char* dest=NULL;   
	int len=strlen(src);   
	dest=(char*)malloc(len);      
	char* d=dest;   
	char* s=src[len];           
	while(len--!=0)   
	d++=s--;          
	printf("%s",dest);   
	return 0;   
}

解答:

// 找出错误,一共有4个错误;   
int main()   
{   
 char* src = "hello,world";   
 int len = strlen(src);   
 char* dest = (char*)malloc(len+1);//要多分配一个空间    
  char* d = dest;   
 char* s = &src[len-1];          //指向最后一个字符  
 while( len-- != 0 )   
  *d++=*s--;   
 *d = 0;           //尾部要加’\0’   
 printf("%sn",dest);    
  free(dest);        // 使用完,应当释放空间,以免造成内存汇泄露
  dest = NULL;   //防止产生野指针 
  return 0;  
}

// 改进该函数提高效率: (方法一需要额外的存储空间,效率不高.) 不错的想法
#include <stdio.h>
#include <string.h>
main()
{
char str[]="hello,world";
int len=strlen(str);
char t;
for(int i=0; i<len/2; i++)
{
t=str[i];
str[i]=str[len-i-1]; //小心一点
str[len-i-1]=t;
}
printf("%s",str);
return 0;
}
  •  请问p1+5= ? ; p2+5= ? ;
    unsigned char *p1;
    unsigned long *p2;
    p1=(unsigned char *)0x801000; 
    p2=(unsigned long *)0x801000;

    解答:0x801005(char占一位,相当于加上5位) 0x801014(long占4位,相当于加上20位);  

  • 设有以下说明和定义,则语句 printf("%d",sizeof(struct data)+sizeof(max));的执行结果是?
     

    typedef union
    {
     long i;
     int k[5];
     char c;
    }DATE;  
    struct data
    {
       int cat;
       DATE cow;
       double dog;
    } too;  
     DATE max;   
    printf("%d",sizeof(struct data)+sizeof(max)); 

    考点:区别struct与union.(一般假定在32位机器上),DATE是一个union, 变量公用空间. 里面最大的变量类型是int[5], 占用20个字节. 
    // 所以它的大小是20. data是一个struct, 每个变量分开占用空间. 
    // 依次为int4 + DATE20 + double8 = 32. 所以结果是 20 + 32 = 52. 
    引申:char 占1字节,short占 2 字节,int 、float、long 都占 4 字节,只有double 占8 字节

  • 找出以下代码的错误
     

    
    int main()
    {
    char a;
    char *str=&a;
    strcpy(str,"hello");
    printf(str);
    return 0;
    }

    答:没有为str分配内存空间,将会发生异常
    问题出在将一个字符串复制进一个字符变量指针所指地址。虽然可以正确输出结果,
    但因为越界进行内在读写而导致程序崩溃。
    Strcpy的在库函数string.h中。程序的主要错误在于越界进行内存读写导致程序崩溃

  • 结构体“ -> ”和“ . ”的区别
     

    //声明一个Struct example_struct的为结构体类型
    typedef struct  
    { 
    int  a;
    char b;
    char c[20];
    }example_struct;
    example_struct A;//定义一个example_struct类型的变量A
    example_struct *P;//定义一个example_struct类型的指针变量P
    P=&A;//将结构体变量A的地址赋给指针变量P

    //区别如下
    //结构体变量A后跟点“ . ”
    A.a=1; //赋值 1
    A.b=1;
    A.c[0]=1;
    //指针p是结构体变量A的地址,后跟" -> "
    p->a=1;
    p->b=1;
    p->c=1;
    //(*p)相当于结构体变量A,后跟点" . "
    (*p).a=1;
    (*p).b=1;
    (*p).c=1;
    //注意,括号不能省略,因为点.的优先级高于星号*

  • 把变量的某位置零,定义一个变量 a =0x9f( 10001 1111) ,对bit2 置零
     
int a = 0x9f;
a &=~(1<<2);
  • 将4个uint8_t 类型的变量合成一个uint32 类型的变量
uint8_t temp0 =0,temp1 = 0,temp2 = 2,temp3 =0;
uint32_t temp = 0;
temp= (temp0<<24)|(temp1<<16)|(temp2<<8)|temp3;
  •  获取数组的变量的个数(当数组没有明确定时),如int a[5],个数为5.
  //此处定义了数组为15个,但没有明确给出大小
 uint8_t length;
  uint8_t data[] ={0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22};
 
  length=sizeof(data)/sizeof(data[0]);//数组占内存总空间,除以单个元素占内存空
  printf("data[] length=%d\r\n",length);//输出为15
  • 编写用C语言实现的求n阶阶乘问题的递归算法:
    long int fact(int n)
    {
    if(n==0||n==1)
       Return 1;
    else
     return n*fact(n-1);  //在此重入
    }

     

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值