常见c语言笔试题嵌入式软件开发

本次进行分享的是嵌入式软件开发中常见的一些c语言知识相关的笔试题
内容来自B站博主:
c语言笔试题嵌入式软件开发视频

1.char *const *(*next)()请对这行代码进行解释

1)首先这题考的知识点有函数指针
2)const 和指针之间的关系(指向常量的指针,以及常量指针)
代码解释:
1、(*next) 中next是一个指针
2、(*next)() next是一个函数指针
3、 char *const 是一个指针 常量指针
综合理解:next是个函数指针,指向一个没有参数的函数,并且这个函数的返回值是一个指针,该指针指向一个类型为char的常量指针。

2、char *(*c[10])(int **p)

1)char pt[10] ;pt是一个数组 ,数组是由10个char指针所组成,Pt是指针数组
2)char (*pt)[10]; pt是指针,pt指针指向了由10个char元素所构成的数组,pt是数组指针
我们理解上面两个知识点在进行分析就简单了。
1、c[10] 是数组
2、*c[10] 是一个指针数组
3、char *()(int **p); c数组中每一个元素都是函数指针,其所指向的函数返回值是char *类型并且函数带一个指向指针的指针(二重指针)。

请问一下代码是否有问题,如果有问题请指出问题
char *s = "AAA";
printf("%s\n",s);
s[0] = 'B';   //不允许操作错误使用
printf("%s\n",s);

从运行的结果我们可以看出,发生了段错误。这是因为我们初始化字符串相当于的一个常量,这个值时只读的 不允许进行操作。

4、嵌入式系统经常具有要求程序员去访问某特定的内存位置要求读取地址的里面的内容或者向该地址写入新值,特别是在嵌入式处理器并发中操作寄存器时这种用法会经常出现。例如在某工程中,耍求设置一绝对内存地址为0x40020800的位置,将该地址里面的内容设置为整型值0x3456。编写代码完成这一任务。

int *pt;
pt = (unsigned long *)0x40020800;
*pt = 0x3456;//方式二
#define ADDR (*(volatile unsigned long *)t0x40020800)
ADDR = 0x3456;

typedef 在c语言中频繁用以声明一个已经存在的数据类型的同义字,也可以使用预处理器做类似的是,思考这样一个例子
#define dps struct s *
typedef struct * tps;
以上两种情况都是定义dps 和tps做为一个指向结构体的指针,拿中方式更好呢?

#define dps struct s*
typedef struct s * tps;//1.情况一
dps p1;    //struct s *p1;
tps p2;    //struct s *p2;
//当我们只定义一个变量的不难发现这两种方式的效果是一样
//2.情况二
dps p1,p2;  //struct s*p1,p2; //p1是结构体指针p2是结构体s的对象
tpd p3,p4; //struct  s*p3,struct s*p4 ;//都是结构体指针//所以第二种方式更好

下面代码是否有问题,如果有问题,那么编译运行后的结果是什么,并说明问题的原因是什么,该怎么修改

#include<stdio.h>char *get_str(void);int main(void)
{char *p = get_str();printf("p = %s\n",p);return 0;
}char *get_str(void)
{//char str[] = "abcd";//char *str = "abcd";return str;
}

从运行结果可以看出我们P指针是一个空指针,那么造成这个的原因是因为我们函数内部所定义的数组进行内存分配时是在栈上的当我们调用这个函数的时候就会分配内存,调用完成后就会回收该内存空间,所以当我们用P指针去接收返回值的时候为一个空指针。修改方法也很简单我们把字符数组改成指针的形式就可以了。因为指针定义的字符串为常量,所存放的空间并不在栈了,而是在数据段中,并不会随着函数的调用完成而去释放完内存,该地址的值发送改变。

什么是大端模式,什么是小端莫斯,编写代码测试你的计算机是大端模式还是小端模式?
关于大小端我们记住这样一个结论就好了,为什么会有大小端之分,大家可以去查看相关的资料介绍,这里就不做解释了。
大端模式:数据的低位存放在高地址中,数据的高位存放在低地址中
小端模式:数据的低位存放在低地址中,数据的高位存放在高地址中。

//代码测试#include <stdio.h>int main(void)
{//方式一union Test{int a;char b;}c;c.a = 1;printf("%d\r\n",c.b);union T{unsigned int n;char arr[4];}t;t.n = 0x12345678;int i = 0;for(i = 0;i<4;i++){printf("&arr[%d] = %p,arr[%d] = 0x%x\r\n",i,&t.arr[i],i,t.arr[i]);}//方式二unsigned int a = 0x12345678;char b = (char *)a;printf("b = 0x%x\r\n",b);return 0;
}

从上面的结果中我们可以看出我使用的计算机的小端模式的存储。

想取出当前计算机系统下无符号整数Int类型的0值和其最大值,评价下面的代码的片段。

unsigned  int zero = 0;
unsigned int copmzero = 0xffff;

首先我们要明白的是32位系统的Int占4个字节,64位系统占8个字节,那么问题来了我们有时不知道自己的系统是多少位的那么直接0xffff就默认了是32位系统,这么做是不严谨的,最好的求无符号的最大值应该是对高0值取反unsigned copmzero = ~0;这样不管是多少位的系统都可以得出正确的答案。

考虑下面的代码,其作用是在数组中查找一个特定的元素,如果将&&写成了&下面两种方式是否都可以实现?


//方式一
i = 0;
while(i < arrsize && arr[i] != x)
//方式二
i = 0;
while(i < arrsize & arr[i] != x)

先写一个测试进行看一下结果

#include<stdio.h>
#define ARRSIZE 10
int main(void)
{//当值只有0 或者1的时候 && &的结果是一样的//如果只是真值则下面两个结果不同 int i = 0;int arr[] = {1,2,3,4,5,6,7,8,9,0};int ret = 5;while(i < ARRSIZE && arr[i] != ret)i++;printf("i = %d\r\n",i);while(i < ARRSIZE & arr[i] != ret)i++;printf("i = %d\r\n",i);   return 0;
}

从结果分析来看,上面两种方式都实现了对特定元素下标的查找,但第二种的结果并不是确定的,当我们变量的结果只有1或0 的时候上面两种方式确实可以等价,但如果判断条件里面是确定的条件时第二种就不行了。
首先&&是逻辑上的与如果左边等式为0了右边的等式就不用判断了这个结果就是为0,&为位与及时左边为0同样还是要看右边的值在进行位与运算

求printf("%d\r\n",printf("%d",printf("%d",a)));的结果//结果
4321

分析:首先输出的是最右边的printf的值此时a时43
printf(“%d”,a); -------------->43
printf(“%d”,printf(“%d”,a)); ------------>432 第一句输出后printf的返回值为输出的元素个数(2)使用在第一句的基础上结果为432
最后一个输出时上面一个Printf的返回值(2)也就是1个元素,因为只有最后一次Printf输出的时候才换行所以结果是4321

举例说明通过#运算符,利用宏参数创建字符串
#include <stdio.h>#define SQUARE(x)  printf("x squre is:%d\n",((x) * (x)))
#define SQUARE2(x)  printf(""#x" squre is:%d\n",((x) * (x)))
//demo4 使用宏参数创建字符串 #int main(void)
{SQUARE(4);SQUARE2(4);SQUARE2(2 + 4);return 0;
}

举例说明"##"运算符的作用
#include <stdio.h>
#define XNAME(n)   x##n// ##预处理的 粘合剂 将2个符号转成一个符号 int main(void)
{//int x1 = 10;int XNAME(1) = 10 ; //x1 ---> int x1 = 10;printf("%d\n",x1); return 0;
}

##进行字符之间的拼接。

阅读下面代码,看这段代码是否有问题,如果有请指出问题

#include <stdio.h>
#include <string.h>#define SIZE 24   //数组大小根据需求进行修改
struct std
{unsigned int id;char *name;//char name[SIZE];unsigned int age;
}per;int main(void)
{per.id = 0001;strcpy(per.name,"Micheal JackSon");//per.name = "Micheal JackSon";per.age = 20;printf("%s\n",per.name);return 0;
}

运行的结果是发送了段错误,究其原因有1》指针为野指针 2》内存空间不足上面定义的char *name本身本身只有4个字节 而我们strcpy赋值所占用的空间是大于这个的。
解决办法:
1》我们直接对name赋值per.name = “Micheal JackSon”;
2》结构体中定义为字符数组的形式,这也是最常用的方法,存放字符串的时候最好使用数组


阅读下面代码,看是否有问题,如果有请指出问题
char *p1 = “ABCABC”;
char *p2 = (char *)malloc(strlen(p1));
strcpy(p2,p1);

代码测试结果是没有问题的,但这段代码是不够严谨的p2在进行空间开辟的使用strlen的大小是6是没有算’\0’结尾字符的,而p1的实际大小是7,进行拷贝的时候可能就会出现问题,所以我们在进行空间开辟的时候要合适,上面代码我们可以改成char *p2 = (char *)malloc(strlen(p1) +1)


在Linux内核代码(版本2.6.22)中有如下定义:
#define offsetof(TYPE,MEMBER) ((size_t)&((TYPE*)0)->MEMBER)请尝试解释下上面这行语句的含义。
1)(TYPE*)0:将0强制类型转换为TPYE类型的指针,p = (TYPE*) 0
2) ((TYPE*)0)->MEMBER—–》p->MEMBER—–>访问MEMBER成员变量
3)&((TYPE*)0)->MEMBER :取出MEMBER成员变量的地址
4)(size_t)&((TYPE*)0)->MEMBER :size_t相当于是类型强制转换,将MEMBER成员变量的地址转换为size_t类型的数据,和Int 类型是等价的
总结:该宏的作用就是求出MEMBER成员变量在TYPE中的偏移量


const关键的作用

1》const定义一个常量,这个常量在定义时必须进行初始化,否则后面就没有机会
2》实际上const定义的变量并不是真正的常量(指针数组可以验证)
3》const和指针的用法
const int *pt;
int const *pt;这两种方式是等价的,都代表pt指针可以指向任意对象,但是不能通过pt指针来修改指向的对象
int *const pt;pt 指针不能指向其他位置,但是可以通过pt指针修改指向位置的值
4》const修改形参

#include <stdio.h>int main(void)
{int i = 10,j = 20;const int *pt;pt = &i;*pt = 20;printf("i = %d\n",i);return 0;
}

#include <stdio.h>int main(void)
{int i = 10,j = 20;const int *pt;pt = &i;pt = &j;printf("pt = %d\n",*pt);return 0;
}

可以修改指针的指针,但是不能修改指向的值

#include <stdio.h>int main(void)
{int i = 10,j = 20;int * const pt ;pt = &i;pt = &j;printf("pt = %d\n",*pt);return 0;
}

指针的指向不可修改,在定义时进行初始化

#include <stdio.h>int main(void)
{int i = 10,j = 20;int * const pt = &i ;*pt = 30;printf("i = %d\n",i);return 0;
}

指向的值可以进行修改

#include <stdio.h>int add(const int *pt1,const int *pt2);int main(void)
{int a= 10,b = 20;int ret = 0;ret = add(&a,&b);printf("ret = %d\n",ret);return 0;
}int add(const int *pt1,const int *pt2)
{//      *pt1 = 20;
//      *pt2 = 30;return (*pt1 + *pt2);
}

做形参时不可去修改值

【常见c语言笔试题嵌入式软件开发1】相关推荐

  1. 【常见c语言笔试题嵌入式软件开发2】

    [常见c语言笔试题嵌入式软件开发2] 内容来自B站博主 C语言笔试嵌入式软件开发视频讲解 1>下面这段代码int main(){fork() || fork();}共创建几个进程 从运行结果来分 ...

  2. Android开发面试经——2.常见Android基础笔试题

     标签: androidAndroid基础Android面试题Android笔试题 2015-03-12 15:04 3361人阅读 评论(3) 收藏 举报  分类: Android开发(29)  版 ...

  3. sql 以a开头的所有记录_#9#猴子聊数据分析之常见的SQL笔试题和面试题(下)

    题目来源 猴子:常见的SQL笔试题和面试题(下)​zhuanlan.zhihu.com 1.SQL语言允许使用通配符进行字符串匹配的操作,其中'%'可以表示:多个字符 2.通过 SQL,如何从 &qu ...

  4. 常见的php笔试题(附答案)搜集整理

    转载链接:http://www.yaojinbu.com/p/139.html 常见的php笔试题(附答案)搜集整理 1.在PHP中,当前脚本的名称(不包括路径和查询字符串)记录在哪个预定义变量中?而 ...

  5. C语言笔试题--从CSDN转发

    C语言笔试题--从CSDN转发 关键字: 工作,C语言 4.static有什么用途?(请至少说明两种) 1.限制变量的作用域 2.设置变量的存储域 7.引用与指针有什么区别? 1) 引用必须被初始化, ...

  6. c语言编写单词位置反转,C语言笔试题答案.docx

    C语言笔试题答案 C语言笔试题答案简答题程序的局部变量存在于(栈)中,全局变量存在于(静态区)中,动态申请数据存在于(堆)中.设有以下说明和定义:typedef union {long i; int ...

  7. 常见的SQL笔试题和面试题:SQL经典50题

    常见的SQL笔试题和面试题(上):经典50题 已知有如下4张表: 学生表:STUDENT(S#,SNAME,SAGE,SSEX) 课程表:COURSE(C#,CNAME,T#) 成绩表:SC(S#,C ...

  8. 东软 c语言笔试题,C语言笔试题及参考答案-东软集团(最新整理)

    <C语言笔试题及参考答案-东软集团(最新整理)>由会员分享,可在线阅读,更多相关<C语言笔试题及参考答案-东软集团(最新整理)(7页珍藏版)>请在人人文库网上搜索. 1.C 语 ...

  9. 网易2018实习生招聘笔试题-JAVA开发实习生

    网易2018实习生招聘笔试题-JAVA开发实习生 如何从有数字规律的网址抓取网页并保存在当前目录?假设网址为 http://test/0.xml,其中这个数字可以递增到100. for(int i=0 ...

  10. c语言面试题下载,C语言笔试题A.doc

    C语言笔试题A 选择题(本大题共25小题,每小题2分,共50分) 1.C语言程序总是从 c 开始执行. A.书写顺序的第一个函数 B.书写顺序的第一条执行语句 C.主函数main D.不确定 2.以下 ...

最新文章

  1. java web手动部署_tomcat手动部署web项目的方法
  2. java新建常量_【Java】常量 - 每日坚果的个人空间 - OSCHINA - 中文开源技术交流社区...
  3. 【数据竞赛】懒人特征筛选算法!
  4. PCB设计必知:布局及设计规范
  5. 【C++】Visual Studio教程(十) - 初步了解 Visual Studio IDE
  6. Java开启/关闭tomcat服务器
  7. 登录不上_《盗贼之海》登录不上?还在傻傻等待,快来让我教教你
  8. linux账号登陆安全性相关命令
  9. 推行法定数字货币,现有支付宝/微信等支付系统,会否被数字货币支付系统替代并超越?
  10. h5离线缓存与浏览器缓存的区别
  11. iOS网络请求架构图URL Loading System
  12. 深度学习简明教程系列 —— 经典模型(合集)
  13. 数二计算机考研大纲2016,2016数二考研大纲.doc
  14. 7教程统计意义_AMOS进行问卷分析效度分析之验证因子分析—杏花开生物医药统计...
  15. 2021/7/27 Ubuntu18.04 安装 PCL记录
  16. 微信小游戏正式发布!什么!审核失败!流量主广告接入指南!
  17. 显示upnp服务器 sonos,蒲公英的上层设备如何开启UPnP及其优点
  18. 五十二度系统维护光盘-驱动篇 1.16.2008
  19. $.ajax返回报错,请求ajax报错 返回readyState0
  20. 一招学会绘制UI图标超椭圆

热门文章

  1. 免费开源字体_7种华丽的免费开源字体以及何时使用它们
  2. 学术第一步:搞清楚SCI、EI、ISTP和中文核心期刊的区别
  3. 计算机组成与系统结构第五版pdf,计算机组成与系统结构1_5习题整理版.pdf
  4. 数据助力防疫,疫情密切接触人员追踪算法赛期待你的加入
  5. visio2010 java类图_UML图及Visio 2010使用总结
  6. 嵌入式linux基础学习全套精品视频教程
  7. 单片机编程软件很简单(19),keil单片机编程软件3点介绍
  8. Java中常见的设计模式
  9. ansys workbench 静力结构分析 高阶教程
  10. apt-cyg 代理设置