- 博客(41)
- 资源 (12)
- 收藏
- 关注
原创 从左值和右值的角度分析a++和++a
(a++)返回的是a在+1之前的值,这个值是一个临时的对象。这个临时的对象在(a++)这条语句结束后,马上就结束了生命周期,即右值,而我们不能对一个右值进行自增运算。a++返回的是右值(rvalue),而我们不能对一个右值进行自增操作。所以++(a++)会报错。总之,a++和++a都是一个表达式,表达式返回的都是一个右值,我们不能对一个右值进行自增操作。int a=5,则 ++(a++)的值是?类似于++(++a)也是不对的。
2024-02-11 16:44:17 201
原创 c语言的各类输出函数(带完善更新)
因此,输出结果为2.19e+02,表示218.82631以科学计数法的形式输出,并保留2位小数,总宽度为6个字符,左对齐。需要注意的是:当指定数据宽度小于数据的实际宽度时,对整数,按该数的实际数据宽度输出,对浮点数,相应小数位的数四舍五入。因此,输出结果为12345,因为k的值有5个字符,大于最小宽度2,所以不需要填充空格。%md 以宽度m输出整型数,不足m时,左补空格。%0md 以宽度m输出整型数,不足m时,左补零。%m.nf 以宽度m输出实型小数,小数位为n位。
2024-02-11 15:46:02 523
原创 c语言中的隐式类型转换
我们在实际编程中,不管你是有意的还是无意的,有时候都会让两个不同类型的数据参与运算,编译器为了能够生成CPU可以正常。,如果程序员在程序中没有对类型进行强式类型转换,则编译器在编译程序时就会自动进行隐式类型转换。执行的指令,往往会对数据做类型转换,将两个不同类型的数据转换成同一种数据类型。● 算术运算、逻辑运算、赋值表达式中运算符两侧数据类型不相。遇到上面这几种情况,编译器就会对数据类型进行自动转换,即。● 函数调用过程中,传递的实参和形参类型不匹配时。● 函数返回值类型与函数声明的类型不匹配时。
2024-02-10 20:38:08 509
原创 c语言内存对齐
内存对齐:在计算机中,内存空间按照字节划分,理论上可以从任何起始地址访问任何类型的变量。但实际上在访问特定类型的变量的时候需要从特定的地址开始,这就需要各种类型的数据按照一定的规则在空间上排列,而不是顺序的一个接一个的存放,这就是内存对齐,也叫字节对齐。
2024-02-10 20:30:37 1133
原创 c语言数据类型定义错误导致的数据溢出或者死循环
例如,一个unsigned char类型的数据,它能表示的数据范围为[0,255],当其循环到255最大值时继续加1,这个数就变成了0,开始新的一轮循环,周而复始。为了防止这种问题发生,我们有两种解决方法:可以将函数的参数类型设置为signed int,或者在print_star()函数中对传进来的实。是unsigned int类型,unsigned int类型在递减的时候存在数据溢出的问题,当减到-1时数据发生溢出,
2024-02-10 20:27:29 627
原创 typedef关键词的使用
定义表达式typedef <元素类型关键字><数组类型名>[<常量表达式>];例如:第一条语句定义了一个元素类型为int,含有10个元素的数组类型vector,若不使用typedef保留字,则就变成了数组定义,它只定义了一个元素类型为int、含有10个元素的数组vector。这两种定义有着本质的区别,若定义的是数组vector,系统将为它分配有保存10个整数的存储单元,共40个字节的存储空间;
2024-02-10 20:22:28 396
原创 嵌入式c语言学习笔记:可重入函数与不可重入函数
什么是可重入函数与不可重入函数?在一个多任务环境中,一个函数如果可以被多次重复调用,或者被多个任务并发调用,函数在运行过程中可以随时随地被打断,并不影响该函数的运行结果,我们称这样的函数为可重入函数。相反,如果一个函数不能多次并发调用,在执行过程中不能被中断,否则就会影响函数的运行结果,那么这个函数就是不可重入函数。如何判断一个函数是可重入函数,还是不可重入函数呢?规则很简单,一个函数如果满足下列条件中的任何一个,那么这个函数就是不可重入函数。函数内部使用了全局变量或者局部静态变量;函数返回值是一个
2024-01-09 10:13:02 766
原创 关键字联合体union的定义和使用
联合体的定义和结构体相同。联合体成员共用存储空间,联合体占用的空间=最大长度的数据成员的长度。以上例子,State表示联合体的名字,它相当于声明了一个联合体的模板,以后可以使用union+联合体名来声明一个联合体变量。state_u表示在创建联合体模板(State)的同时定义了一个联合体变量state_u。此外还可以使用typedef重新定义联合体模板(类型)
2024-01-08 17:18:27 627
原创 c11:实现泛型编程
注意:_Generic只能接收单个表达式,如果传入的两个参数类型都不确定 ,_Generic无法处理,_Generic关键字是根据单个表达式的类型来选择代码分支的,而不是多个参数的类型。其中,expression是一个表达式,type1、type2等是类型参数,result1、result2等是对应类型参数的代码分支,default是默认的代码分支。_Generic关键字可以根据不同的类型参数,选择不同的代码分支进行编译,从而实现泛型编程。
2023-12-29 17:09:10 428
原创 嵌入式c语言--strcut位域
有些信息在存储时并不需要占用一个完整的字节,而只需占一个或几个二进制位,例如在存放一个开关量时,只有 0 和 1 两种状态,用一个二进制位即可。为了节省存储空间并使处理简便,C 语言又提供了一种数据结构,称为“位域”或“位段”。所谓“位域”是把一个字节中的二进制位划分为几个不同的区域,并说明每个区域的位数。每个域有一个域名,允许程序按照域名进行操作,这样就可以把几个不同的对象使用一个字节的二进制位域表示。
2023-12-29 14:33:28 411
原创 static关键字
static关键字的作用是将局部变量的存储类型,从自动变量改为静态变量,也就是说这个局部变量不再存储在堆栈或寄存器中,而是在编译的时候由编译器分配一个静态的地址空间,但是这个变量的作用域不受影响,依然仅局限在声明它的函数内部才可以访问。声明为static的局部变量,可能使得它所在的函数变得不可重入。
2023-12-26 10:07:33 357 1
原创 include跟双引号“ “和<>的区别
双引号“ ”的意思是告诉编译器首先在当前目录下搜索需要包含的文件,如果当前目录下没有该文件,则在编译选项指定的系统头文件目录中搜索该文件。
2023-12-26 09:04:19 834
原创 const关键字在c与c++的不同点
c语言中的const表示可读变量,或者是常变量,是一个伪常量。编译器会为其分配内存。常变量不能作为左值。(右值不能出现在表达式的左边,左值即可以出现在表达式的左边,也可以出现在右边,右值通常不能取地址)以下是gcc编译后的运行结果。会发生如下报错:由此可见,c语言中的const修饰的变量只是一个常变量,并不是一个真正的常量。
2023-12-13 09:12:42 51
原创 指针(地址)+1和指针(地址)的二进制表示+1的区别
结论:结构体指针+1表示对该结构体指针偏移一个结构体大小的地址。换句话说,指针加1,结果是对该指针增加1个储存单位大小的长度。如果一个int类型的指针ip,那么ip+1指向的是计算机内存中的下一个整数,它不同于ip所指向地址的下一个内存的位置。那么p+1=0x00027,这与p的二进制表示0x00023+1指向的内容完全不同。从上图可以看出,pf+1和pf的地址差0x0c,也就是结构体fifo的大小。就是对指针偏移所指类型大小的地址。假设p=0x00023;
2023-11-17 15:00:22 521
原创 c语言中,为什么全局变量只能在初始化时赋值,不能定义后再赋值?
简单来讲就是编译阶段不进行赋值运算,只进行初始化,因此编译器认为这是一条错误语句(a=10)。需要注意的是,代码的编译阶段只涉及代码区与全局区,其中代码区是只读的,全局区只能存放数据,a=10这个执行操作在编译阶段完成完成不了。int a与int a=10这两条语句放在编译器中执行,a=10这个赋值操作是具体执行的运算,需要放在计算机内存中去执行。由于编译的时候没法赋值,所以编译器会认为这条语句(a=10)的意思是int a=10,但是int不能省略,因此最终会报错。
2023-11-06 09:03:43 430
原创 基于栈的内存非配--alloca函数
alloca是一个在 C 和 C++ 中可用的函数,用于在栈上动态分配内存空间。它类似于malloc函数,但是分配的内存空间在函数返回后会自动释放,无需显式调用free函数。以下是alloca函数的详细介绍:sizeallocaallocaallocamemsetalloca使用alloca上述示例中,alloca函数用于在函数中动态分配一个包含 10 个int类型元素的数组。然后,数组被初始化并打印出来。在函数返回后,分配的内存空间会自动释放,无需手动释放。需要注意的是,由于alloca。
2023-10-07 13:58:29 2273 4
原创 c99标准支持可变长度数组
可变长数组(variable length array,简称VLA)中的可变长指的是编译期可变,数组定义时其长度可为整数类型的表达式,不再像C90/C++那样必须是整数常量表达式。
2023-10-07 13:54:51 339 1
原创 传参场景下的类型不匹配问题
参数传递过程类似于赋值,因此主函数调用foo,并传参,相当于char **argv赋值给const char **p。这种赋值方式是非法的,关于为什么是非法的,这需要阅读ANSI C标注关于赋值操作需要满足的约束条件。
2023-10-06 22:08:00 66 1
原创 c语言实现继承、多态的方法
作file_system的子类。然后,我们定义了一个指向基类的指针fp,并通过基类指针fp去访问各个子类中同名函数的不同实现,C语言通过这种方法“模拟”了多态。在上面的示例代码中,我们首先定义了一个file_system结构类型,并把它作为基类,使用该结构体类型定义的ext和fat变量可以看。
2023-09-28 11:12:25 138
原创 指针的本质&指针运算
指针的原始初衷用途,其实就是访问一片匿名的动态内存。指针变量自身也是一个变量,和普通变量的不同之处就是:普通变量存放的是一个数,而指针变量存放的是一个地址。无论指针是什么类型,它存放的都是一个地址,只不过这个地址上存放不同类型的数据而已。指针变量无论是什么类型的,它的大小都是4字节,指针变量的大小和系统有关,和类型无关。在一个64位系统中,指针变量存储的是64位地址,因此指针变量的大小也就随之变为8字节。
2023-09-28 11:04:56 61
原创 volatile关键字使用说明
如果flag变量不被声明为volatile,则编译器并不知道flag的值会被别的程序修改,因此在它进行优化的时候,可能会把flag的值先读入某个寄存器,然后等待那个寄存器变为1。(这会导致在其他地方对i的值进行改变了(例如在中断中对i的值进行累加),b读到的值是之前缓存在寄存器中的值,也就是i改变之前的值),而不是重新从 i 里面读。指出 i 是随时可能发生变化的,每次使用它的时候必须从 i的地址中读取,因而编译器生成的汇编代码会重新从i的地址读取数据放在 b 中。,以确保对变量的读写操作的顺序和可见性。
2023-09-27 14:04:32 54 1
原创 (void)变量 用法的说明
变量的值,但仍然保留它的定义。这可能是因为在其他地方的代码中可能会使用。在代码中被使用,防止编译器认为该变量未使用而发出警告。是一个类型转换操作,用于消除编译器警告,确保变量。变量,或者为了保留将来可能需要使用它的可能性。表示我们明确告诉编译器我们有意忽略。,并将其初始化为 16。
2023-09-27 13:51:22 112
原创 关于对内存地址范围和存储空间大小的理解
一个16进制的地址可以存储8个bit。当一个地址被表示为 8 位时,意味着系统可以寻址28256个不同的存储单元或寄存器。每个存储单元或寄存器通常有一个字节(8 位)的容量,因此一个 8 位地址可以用来表示一个字节的存储空间。
2023-09-27 10:39:08 3798 1
原创 ubuntu2020运行repo遇到:/usr/bin/env: ‘python’: No such file or directory
遇到的错误:首先查看python的位置whereis python在/usr/bin目录下有python3.8,说明有oython3.8的软链接,但是没有python2的软链接。repo iit需要python2,所以需要先现在python2,然后再为python2创建软链接sudo apt-get install python2sudo ln -s /usr/bin/python2 /usr/bin/python #在/usr/bin/python目录下为python2创建软连接
2021-11-15 09:59:57 4204
原创 ubuntu2020:Could not get lock /var/lib/dpkg/lock-frontend.
ubuntu发生如下错误:解决方法:sudo rm /var/lib/apt/lists/locksudo rm /var/cache/apt/archives/locksudo rm /var/lib/dpkg/lock*sudo dpkg --configure -asudo apt update
2021-11-15 09:19:49 895
原创 嵌入式交叉编译工具选项说明
PC上的编译工具链为gcc、ld、objcopy、objdump等,他们编译出来的程序在x86平台上运行。要编译出能在ARM平台上运行的程序,必须使用交叉编译工具arm-linux-gcc、arm-linux-ld等。一个C/C++程序要经过预处理、编译、汇编、和连接四个步骤。预处理:以#开头的命令被称为预处理命令,比如#include #if #ifdef等。经过预处理输出一个.i文件。编译:将.i文件翻译成汇编代码,所用到的工位为ccl。汇编:将汇编代码翻译成符合一定格式的机器码,在Linux
2021-08-21 09:37:10 182
转载 Linux /dev/zero
/dev/zero是unix系统中的一个特殊文件,当读取该文件时,他会提供无限的空字符nul。它的一个特殊的用途是提供字符流来初始化数据存储,也就是使用空字符覆盖目标数据。另一个常见的用法是产生一个特定大小的空白文件。 你可以从 /dev/zero 读取任意大小数量的 null 字符。和 /dev/null 不同,/dev/zero 不但可以作为数据黑洞,也可以作为数据源泉。你可以将数据写入 /dev/zero 文件,但实际上不会有任何影响。不过一般我们还是使用 /dev/null 来做这件事。 创建一
2021-08-13 10:54:04 439
原创 C++:指针型常量和常量性指针
指针型常量:*在const后面,例如char const *p 等同于const char p,由于const在之前,所以指针p是可变的,但是指针指向的数据不可变。char str1[]=“hellow”;char str2[]=“money”;const char p1=str1;可以更改p1的指向,比如p1=str2,但是无法通过p1修改str1的内容,比如p1[1]='H’是不对的。而常量型指针:const在后面,例如 char *const p2,此时p2的指向是不可变的,而p2指向的内容
2021-03-19 17:10:51 124
原创 python:list变量前面加星号,字典变量前面加两个星号表示什么意思?
列表前面加星号作用是将列表解开成两个独立的参数,传入函数,字典前面加两个星号,是将字典解开成独立的元素作为形参。a=[12,4]def add(a,b):return a+bc=add(*a)print(“add result:”,c)data = {‘a’ : 4, ‘b’ : 3}print(add(**data))...
2021-03-19 10:09:59 410
原创 在基于FreeRTOS和LWIP的stm32H743上移植snp7
下面是Snap7移植步骤以及遇到的问题和解决方法:工程项目中新建Snap7文件夹,添加Snap源文件,如图:添加Snap7头文件路径到项目中注:在MiscControls一栏加上 --exception点击运行工程,发现会报很多错误,有很多的数据类型未定义,比如u_short,u_int等,直接在相应位置重定义一下typedef unsigned short u_short。定位到错误位置,sockaddr_in在lwip/sockets.h,所以加上这个头文件将snap_
2020-12-07 14:53:50 1515
Drawlos.zip
2021-03-30
FinalVersion.zip
2021-02-28
Anaconda3-2019.07-Windows-x86_64.exe
2020-07-23
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人