C/C++

2023-11-04

课程介绍

参考:麦子学院-嵌入式C语言高级

本套课程的定位

前导课程:掌握简单C语言的基本语法
计算机程序语言的学习思路?
基本程序设计思想+语言工具的特性
基本程序设计思想:
数据类型、运算符、条件分支、循环设计
面向对象的设计
C语言工具的特性:
比如操作底层,尤其是内存地址的寻址及操作,指针的使用
掌掘C语言的设计思路,比普通的语法要重要的多
万变不离其宗,掌掘C语言的核心规律。

本套读程的想法

不是教程,是一种嵌入式C语言思想和设计的交流
什么时候用?
怎么用?
为什么要这样设计?

推荐教程

C语言深度解剖(第2版》 解开程序员面试笔试的秘密
C专家编程
程序员面试宝典《第4版)
C和指针

偏重嵌入式方向的使用

嵌入式课程的特点

2-1 : GCC的使用及其常用选项介绍【重点】

掌握C语言如何变成机器指令的过程
gcc工具的几个常用选项的意义
【难点】
C编译过程中在gcc工具上的体现
【实验考核】
自己编写程序,利用gcc工具集验证每一步的执行效果
举例说明gcc选项的意义:
gcc -I gcc -L
gcc -E gcc -S gcc -c

Gcc概述

c语言的编译过程
可参考:C/C++|物联网开发入门+项目实战|C语言基础|C语言的预处理及编译过程分析-学习笔记(2)

C语言常见错误举例

预处理错误;

include “name” 当前目录
include 系统库(环境变量)

not find

示例
从abc1.h中引入字符char_c

#include <stdio.h>
#include "abc1.h"

int main()
{
    char  c=char_c;
    printf("c(char)=%c,c(int)=%d,c_change(char)=%c,c_change(int)=%d,c_change(HEX)=%#x\n",c,c,c+32,c+32,c+0x20);
    return 0;
}

输出:
E:\temp>cd “e:\temp” && gcc 2.c -o 2 && "e:\temp"2
2.c:2:18: fatal error: abc1.h: No such file or directory
compilation terminated.
显然无此文件(文件名错误),改为include “abc.h”,运行正常。
而一般地,将头文件一般放在inc目录下。
建立inc,并把abc.h移入inc:
在这里插入图片描述

1、方法1:修改inclue为#include “./inc/abc.h”;
2、方法2:gcc -I ./inc 2.c -o 2

编译错误

语法错误,

链接错误

打包出错,原材料不够 undefined reference

寻找标签是否实现了,链接时是否加入一起链接
示例

#include <stdio.h>
#include "abc.h"

void fun(void);
int main()
{
    char  c=char_c;
    printf("c(char)=%c,c(int)=%d,c_change(char)=%c,c_change(int)=%d,c_change(HEX)=%#x\n",c,c,c+32,c+32,c+0x20);

    fun();
    return 0;
}

main函数中引用了一个fun函数,但没有fun函数的实现,故链接器collect2.exe时出错,

提示:
E:\temp>gcc -I ./inc 2.c -o 2 && "e:\temp"2
C:\Users\Vera\AppData\Local\Temp\ccRNGpif.o:2.c:(.text+0x4b): undefined reference to `fun’
collect2.exe: error: ld returned 1 exit status
解决方法1:不声明,删除fun()的定义并直接实现一个空函数:

void fun(void)
{

}

方法2:2.c不变,新建立abc.c存放fun()的函数实现,如:
abc.c

void fun(void)
{

}

执行程序:>gcc -I ./inc -o 2 2.c abc.c #将所有用到的原材料放在输出文件之后
方法3:分别编译再拼接

E:\temp>gcc -c -I./inc -o a.o 2.c
E:\temp>gcc -c  -o b.o abc.c

分别编译完成后的文件都输出在当前目录下:

gcc -o 2 a.o b.o

原材料多了(重复定义) multiple definition

解决思路:多次实现了标签,只保留一个标签实现
在2个文件中都实现fun()函数,并重新编译,链接:

E:\temp>gcc -c -I./inc -o a.o 2.c

E:\temp>gcc -c  -o b.o abc.c

E:\temp>gcc -c -I./inc -o a.o 2.c

E:\temp>gcc -o 2 a.o b.o

提示错误:
E:\temp>gcc -o 2 a.o b.o
b.o:abc.c:(.text+0x0): multiple definition of `fun’
a.o:2.c:(.text+0x0): first defined here
collect2.exe: error: ld returned 1 exit status

宏的使用

预处理的使用

#include 包含头文件,并在当前位置展开
#deine 宏(替换),不进行语法检查,编译时才检查
#define 宏名 宏体 加括号
#define ABC (5+3)
#define ABC(x) (5+(x)) //宏函数

预定义宏(方便调试)

(C语言编译器或gcc定义)
前后2个下划线
FUNCTIO
LINE
FILE

示例

#include <stdio.h>

int main()
{

     //本行执行的函数名,所在文件名,本行的行号
    printf("the %s,%s,%d\n",__FUNCTION__,__FILE__,__LINE__);

    return 0;
}

输出:
E:\temp>cd “e:\temp” && gcc 2.c -o 2 && "e:\temp"2
the main,2.c,7

改示例为

#include <stdio.h>

int fun()
{
    int a;

     //本行执行的函数名,所在文件名,本行的行号
    printf("the %s,%s,%d\n",__FUNCTION__,__FILE__,__LINE__);

    return 0;
}

int main()
{
    fun();

    return 0;
}

输出(实际调用的函数名称和所在行号):
E:\temp>cd “e:\temp” && gcc 2.c -o 2 && "e:\temp"2
the fun,2.c,8

条件预处理

#ifdef #else #endif
调试版本

发行版本
示例
原始代码:

#include <stdio.h>

int main()
{
    printf("=========================\n",__FILE__);

    printf("hello world!\n");

    return 0;
}

debug期间允许__FILE__行显示,但发行版本中不显示,怎么实现:

#include <stdio.h>

int main()
{
#ifdef  ABC

    printf("=========================\n",__FILE__);

#endif

    printf("hello world!\n");

    return 0;
}

未定义ABC时,不打印:

E:\temp>cd “e:\temp” && gcc 003.c -o 003 && "e:\temp"003
hello world!

需要显示调试信息时,只要在#ifdef ABC之前定义ABC即可。
在这里插入图片描述
但是该方法还是要修改源文件,不是很方便,故引入gcc -D:cpp之前增加define
如:gcc -DABC -o build 003.c 相当于编译前引入: #define ABC。

宏展开下的#、##

# 字符串化
## 连接符号
#define ABC(x) #x
#define ABC(x) day##x //day和x进行连接

示例

#include <stdio.h>
#define ABC(x)    #x //字符串化
#define DAY(x)    myday##x //字符串在当前位置展开,可以执行调用前,后缀
int main()
{
    int a;
    int myday1 = 10;
    int myday2 = 20;
     //本行执行的函数名,所在文件名,本行的行号
    // printf("the %s,%s,%d\n",__FUNCTION__,__FILE__,__LINE__);
    printf(ABC(ab\n));   //相当于:"ab\n"
    printf("the day is %d\n",DAY(1)); //前缀或者后缀以隐藏方式调用。
    printf("the day is %d\n",DAY(2));
    return 0;
}

在这里插入图片描述
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C/C++ 的相关文章

随机推荐

  • 实时数仓建设

    数据智性就显得尤为重要 快速的获取数据反馈能够帮助公司更快的做出决策 更好的进行产品迭代 实时数仓在这一过程中起到了不可替代的作用 一 实时数仓建设的背景 传统意义上的数据仓库主要处理T 1数据 即 今天产生的数据分析结果明天才能看到 随着
  • AD Release 10 PCB 中的常见问题及解决办法

    作为一名新手小白 刚开始进行PCB设计的时候会遇到各种问题 以下是我遇到过的问题及解决办法 希望对大家有用 不正确的地方也请大家多多指正 谢谢 1 silkscreen over component pads 这个报错是说丝印层的文字和焊盘
  • android 移动网络开关打开_手把手教你>> 打开5G开关,畅享极速好网!

    5G小贴士 现在买5G手机的人越来越多 但是你知道吗 5G手机要使用5G网络 必须要打开这个开关 不然就会导致买了5G手机 却用不上5G网络今天小编教你让你的5G手机发挥真正实力 Follow me 各位小伙伴们注意了 想要使用5G网络 必
  • 用 pytorch 进行分类(二分类,多分类)

    import numpy as np import sklearn import torch import torch nn as nn from torch autograd import Variable import torch nn
  • 【Unity】记录一个Findobjectoftype有关的bug

    场景 在写一个多人联机的FPS游戏时 本地启动时 主角是有后坐力的 但是客户端射击没有后坐力 感觉很奇怪 不能房主不开挂其余人全是挂吧 于是打算找一下问题所在 这里计算后坐力的思路是这样的 在鼠标控制的脚本中进行计算后坐力 触发的方法Fir
  • 【HTTP】http重定向301/302/303/307

    一 概述 重定向常常和请求转发放在一起讨论 前者是两次不相关的请求 后者是一次请求服务器端转发 然而本文并不讨论两者的区别 而是HTTP 1 0规范和HTTP 1 1规范中关于重定向的区别 以及实际使用中的情况 重定向实际使用是一个响应码
  • K8S 微服务内存溢出如何排查

    场景 晚上做稳定性压测 早上回来发现内存溢出 2022 06 08 08 29 10 273 ERROR 7 alina utility 2 org apache catalina core StandardServer Error sen
  • mysql中ceil是什么意思_MySQL ceil()函数

    CEIL X CEILING X 该函数返回的最小整数值 但不能小于X 请看下面的例子 mysql gt SELECT CEILING 3 46 CEILING 3 46 4 1 row in set 0 00 sec mysql gt S
  • 【华为OD机试 2023 B卷

    华为OD统一考试A卷 B卷 新题库说明 2023年5月份 华为官方已经将的 2022 0223Q 1 2 3 4 统一修改为OD统一考试 A卷 和OD统一考试 B卷 你收到的链接上面会标注A卷还是B卷 请注意 根据反馈 目前大部分收到的都是
  • LeetCode压缩字符串

    给你一个字符数组 chars 请使用下述算法压缩 从一个空字符串 s 开始 对于 chars 中的每组 连续重复字符 如果这一组长度为 1 则将字符追加到 s 中 否则 需要向 s 追加字符 后跟这一组的长度 压缩后得到的字符串 s 不应该
  • 用Python做一个高山滑雪小游戏

    介绍一款好玩的游戏的开发 该游戏名为高山滑雪 改编自 Computer Programming for Kids and other Beginners 的第25章 游戏效果 游戏的基本界面如下 滑雪者由高山上滑下 玩家通过键盘上的左右方向
  • 有序序列判断-c++

    题目描述 输入一个整数序列 判断是否是有序序列 有序 指序列中的整数从小到大排序或者从大到小排序 输入描述 第一行输入一个整数N 3 N 50 第二行输入N个整数 用空格分隔N个整数 输出描述 输出为一行 如果序列有序输出sorted 否则
  • 基于SSL的虚拟专用网络

    基于SSL的虚拟专用网络 基于安全套接层协议 Security Socket Layer SSL 建立远程安全访问通道的虚拟专用网络技术 像简单虚拟专用网络通过安装软件客户端的方式进行安全远程访问服务器虽然与基于硬件形式的相比更便于使用 但
  • Python OpenCV GrabCut进行前景分割和提取

    Python OpenCV GrabCut进行前景分割和提取 1 效果图 1 1 边界框GrabCut效果图 1 2 Mask GrabCut效果图 2 GrabCut原理 2 1 GrabCut是什么及步骤 2 2 grabCut img
  • 信捷服务器Z相信号,信捷plc标记与中断处理小知识

    信捷plc标记与中断处理小知识 有关信捷plc的编程知识 在信捷plc中标记P I用于分支与中断 标记I一般用于中断功能 包括外部中断 定时中断等场合 分支用的标记 P 用于条件跳转或子程序的跳转目标 一 标记P I 标记P I用于分支与中
  • kotlin框架

  • RuntimeError: Attempting to deserialize object on a CUDA device but torch.cuda.is_available()

    今天在调试yolov7时遇到由题所示报错 Traceback most recent call last File d 1 yolov7 main train py line 609 in
  • linux设备驱动之构造和运行模块

    构造和运行模块 今天开始学习 linux设备驱动程序 第三版这本书 在看到第二章的构造和运行模块的时候 我在linux平台上做了一个小测试 下面就让我说下 在宿主机上安装开发工具和下载linux源码 要求版本号和目标机上的linux内核版本
  • UDP 协议的实现

    pragma pack 1 define ETH ALEN 6 struct ethhdr t unsigned char h dest ETH ALEN destination eth addr unsigned char h sourc
  • C/C++

    课程介绍 参考 麦子学院 嵌入式C语言高级 本套课程的定位 前导课程 掌握简单C语言的基本语法 计算机程序语言的学习思路 基本程序设计思想 语言工具的特性 基本程序设计思想 数据类型 运算符 条件分支 循环设计 面向对象的设计 C语言工具的