查看原文
其他

C语言学的好不好,先上两道题

妮mo 达尔闻说 2021-01-17

不想错过我的推送,记得右上角-查看公众号-设为星标,摘下星星送给我!

“多放点C语言的,我司走过校招,几乎所有高校毕业生C语言功底实在是…”
之前我们在做秋招笔试经分享系列时,有一位大厂研发工程师恳切留言。越是基础的东西,越容易忽视,题目看得懂,答案却怎么也想不起来。
不信看看下面的题:(答对有奖
问题1:问以下函数的输出结果?
int main(){int a[5]={1,2,3,4,5};int *ptr=(int *)(&a+1);printf("%d,%d",(a+1),(ptr-1));}

问题2:问以下程序的输出结果是什么?

void Exchg(int *px, int *py) { int tmp=*px; *px=*py; *py=tmp; } void main() { int a=4; int b=6; Exchg(&a,&b); printf(“a=%d,b=%d/n”, a, b); }
请在留言区评论,最先给出正确答案的同学,赠送一块STM32板卡。
纵观绝大部分的公司招聘硬件工程师的要求,我们发现公司对是否设计过开发板、是否掌握一种EDA工具,是否可以熟练掌握一种MCU,是否熟悉C语言编程及语法,这些都有明确的要求。
针对C语言编程及语法,我们专门用2个小时时间强化,在正在进行的17节毕设技能系列课程中,达尔闻邀请了资深嵌入式工程师陈强(现为高校老师)助力讲解。


重点讲解:C程序结构、嵌入式C与设备地址、数据类型、变量/常量、运算符、函数的用法、指针等。(点击原文查看完整

◆ C程序结构

以STM32F103的标准库为例,先认识嵌入式C与设备地址。
嵌入式C开发的本质是对设备地址的操作:控制/数据寄存器:CPU功能,控制/数据寄存器:MCU外设、RAM:变量&堆栈、Flash:程序&常量、Flash首地址:复位&中断向量。

点击可放大

◆ 数据类型

1、基本数据类型

- char 字符型,占用一个字节,可以存放本地字符集中的一个字符

- int 整型,通常反映了所用机器中整数的最自然长度

- float 单精度浮点型

- double 双精度浮点型

2、限定符

- short int 16位整型 /long int 32位整型

- Signed 有符号 /unsigned  无符号

3、位、字节、字

1GB=1024MB     1MB=1024KB 

1KB=1024Byte   1Byte=bit

4、内存编址以字节为单位

32位CPU支持的寻址空间为2^32Byte=4GB

5、用户自定义类型

如数组类型,结构体类型,函数类型等,最常用的如 typedef,struct


◆ 定义变量及使用范围

int countvoid math_op(){  int i;  static int j;  if(count==0)      j=0;  j=count;  j=j+1;}int main(){   count=0;   while(1)   {     math_op();     count++;    } }
在上面的这段代码中,i为局部变量,先声明后使用,函数起始处,执行语句前声明仅在函数内部有效,不同函数可多次定义;count为全局变量,仅定义一次,使用前加extern 声明,所有函数可访问,可随意修改,有风险; j为静态变量,限定作用域于本文件或本函数使用,一直占用存储空间,不管函数是否被调用都不会消失。

◆ 定义常量

常量的分类:

- 数值常量,如125,-50

- 字符常量,如 ‘a’,转义字符\0\n \r \f

- 字符串常量,如”hello”,存储空间会多一个结束标记’\0’

- 符号常量,如宏定义#define,值不能改变也不能被赋值

- 枚举常量,常量值可自动生成,第一个为0,依次加1

下面的代码中,PI就被定义为常量,值为3.14159。

#include <stdio.h>/*定义符号常量PI的值为3.14159*/#define PI 3.14159enum boolean {NO,YES}; /*枚举常量*/int main(void){    printf("+125 \n"); /*输出+125并换行*/    printf("-50 \n"); /*输出-50并换行*/    printf("a \n"); /*输出a并换行*/    printf("Hello \n"); /*输出Hello并换行*/    printf("半径为10圆周长:%f \n",2*PI*10); /*计算圆的周长*/    printf("\n"); /*输出0并换行*/    return 0; /*程序无错误安全退出*/}


◆ 函数的声明及用法

void math_op(int a, int b); /*函数声明*/void math_op(int a, int b); /*函数定义*/{  return(a + b);}int main(){ int a=1,b=2;   int count= math_op(a,b); /*函数调用*/   return 0;}
定义函数:函数名是该函数在内存中的首地址,因此可以用函数名来调用执行该函数。函数参数不宜太多,参数多时可使用struct函数内使用全部变量有风险,尽量使用参数传递和返回值来和外界交互数据。
函数声明:为了给编译器提供原型参考,编译时以进行参数的静态类型检查。函数声明放在调用之前,一般放在源文件开头或头文件中,即在源文件.c中定义函数,在头文件.h中声明。编译器编译程序时以源文件为单位,在哪个文件中调用就要在该文件中声明。

函数的调用机制:调用一个函数时,系统发生进行如下动作:

(1)开辟该调用函数的栈空间

(2)将当前的运行状态压栈

(3)将返回地址压栈

(4)在栈内为传参分配空间

(5)在栈内为函数内局部变量分配空间,执行被调用函数

当被调用函数结束后,进行返回时,系统进行的动作刚好与函数调用时相反:

(1)释放栈内局部变量空间

(2)释放栈内传参空间

(3)退栈,得到返回地址,程序跳转调用处等待

(4)退栈,得到调用前运行状态,恢复调用前运行状态

(5)释放该调用函数栈空间

函数参数的传递方式:

点击可放大

◆ 指针与数组

指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。

int i=1;int *p=&i;*p=*p+1;printf(“i=%d,*p=%d”,i,*p);
输出结果:i=2,*p=2。
在上面的代码中, p=&i,表示指针变量p指向变量i,使用&取地址运算符进行关联的;代码*p=*p+1表示改变指针变量p指向的变量的值,使用的*指针运算符间接访问变量i。

数组在创建时,我们必须定义数组的类型和大小,数组的大小不能为0,数组中的元素类型都是相同的。

&grade[3]=&grade[0] + 3 * 4
上面表达式的含义是gradep[3]的地址等于grade[0]地址加上12。写成以下的通式:数组中下标为N元素的地址 = 数组的首地址 + N * sizeof(DataType)

例如:

int grade[5]; /*定义array为包含5个整型数据的数组*/int *p; /*定义p为指向整型变量的指针变量*/p=&grade[0];
以上我们介绍了C语言中最基础,但也是最重要的部分,只有掌握这些定义、用法,在我们设计过程中才不会出错。
在陈强老师的这节课中,还涉及了另外一种编程语言-Verilog,使用FPGA的基础语言,具体内容可以查看阅读原文观看
提醒:得捷17节毕设系列课程下节课由复旦大学博士小黄老师讲解AI人工智能入门,请在10月22日(下周二)下午3:00锁定达尔闻,提前占位听课。
别忘记在文末留言回答开头的两道问题,领取你的STM32开发板哦。
END

得捷-毕业设计17节免费课程高能回顾:

开篇介绍:毕业设计“包过”秘籍,附板卡白piao

毕设第1课:如何选题,哪类毕设适合自己 

毕设第2课:毕设读题案例分析

毕设第3课:毕设开发平台选择

毕设第4/5课:2小时用AD19画STM32核心板

课程福利:

硬件免费送:定制PCB尺;Seeed Uino 数块;Xilinx PYNQ粉板;STM32板卡等

获取方式:(请注意:活动已结束)邀请好友关注得捷电子官方微信(必须使用下面二维码关注,否则无法统计),将好友关注截图和昵称发给妮姐(微信/QQ:459888529)。

奖品:(邮费需到付)邀请75人即可获得价值600元STM32L496G-DISCO一块;
邀请50人即可获得价值514元STM32F469I-DISCO一块;邀请30人即可获得价值113元UCLEO-STM32F401RE一块;邀请10人即可获得价值43.5元得捷电子定制PCB尺子一把。注意:关注不可取消!奖品将在10月底陆续发出。


戳原文,查看课程全部详情!
Modified on

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存