
C语言
文章平均质量分 85
zyboy2000
这个作者很懒,什么都没留下…
展开
-
面向对象基础知识
1.引用和指针区别 引用是别名,指针是实体,引用只能定义时被初始化一次,不可变2.作用域:: 1)全局作用域 2)类作用域 3)命名空间作用域3.构造函数,析构函数顺序 1)构造函数:先父类,再子类 2)析构函数:先子类,再父类4.重载构造函数 1)如果没有定义,系统会有默认构造函数,无参数 2)默认构造函数有两种,无参数和有默认参数两种情况 3)...原创 2019-09-01 09:35:59 · 325 阅读 · 0 评论 -
变参宏
宏中"#"和"##"的用法#的功能是将其后面的宏参数进行字符串化操作(Stringfication)。##被称为连接符(concatenator),用来将两个Token连接为一个Token。注意这里连接的对象是Token就行,而不一定是宏的变量。#define debug(arg…) printf(arg)但是,如果变参的个数为0, compiler will co转载 2015-09-10 16:14:35 · 1109 阅读 · 0 评论 -
深入“typedef"
用途一: 定义一种类型的别名,而不只是简单的宏替换。可以用作同时声明指针型的多个对象。比如: char* pa, pb; // 这多数不符合我们的意图,它只声明了一个指向字符变量的指针, // 和一个字符变量; 以下则可行: typedef char* PCHAR; // 一般用大写 PCHAR pa, pb; // 可行,同时声明了两个指向字符变量的指针 虽然: char转载 2009-05-11 10:19:00 · 1369 阅读 · 0 评论 -
Linux进程通信--信号
信号本质信号是在软件层次上对中断机制的一种模拟,软中断 信号来源信号事件的发生有两个来源:硬件来源:(比如我们按下了键盘或者其它硬件故障);软件来源:最常用发送信号的系统函数是kill, raise, alarm和setitimer以及sigqueue函数,软件来源还包括一些非法运算等操作。 int kill(pid_t pid,int signo) 参数:p原创 2009-05-17 17:38:00 · 1048 阅读 · 0 评论 -
环形队列串口(发)应用
环形缓冲区的实现原理:环形缓冲区通常有一个读指针和一个写指针。读指针指向环形缓冲区中可读的数据,写指针指向环形缓冲区中可写的缓冲区。通过移动读指针和写指针就可以实现缓冲区的数据读取和写入。在通常情况下,环形缓冲区的读用户仅仅会影响读指针,而写用户仅仅会影响写指针。如果仅仅有一个读用户和一个写用户,那么不需要添加互斥保护机制就可以保证数据的正确性在设计串口驱动的过程中,要遵循原创 2014-03-20 14:38:07 · 9229 阅读 · 1 评论 -
LWIP 回调函数
在看LWIP时,见到用回调函数,再看某老外公司OPC源代码时,见到用回调函数。看我国内某些代码(我公司软件等)时没用到。于是,我对回调函数产生了很大的好奇。以前,我写VC程序时用到过回调函数,但是没有用C语言来使用。最近,看到国外大量的经典代码中广泛使用了回调函数(LWIP、某两个公司的OPC程序等),都是C语言来实现的,而不是VC windows程序中别人实现自己使用的那种。为了弄明白这种函原创 2012-06-18 22:49:29 · 7439 阅读 · 1 评论 -
(*(void(*)())0) ()讲解
硬件地址跳到0处(*(void(*)())0) (); 预备知识float (*h)();表示h是一个指向返回值float类型的函数的指针(float(*)())表示一个"指向返回值float类型的函数的指针"的类型转换符 假设fp是一个函数指针,那么如何调用fp所指向的函数,调用方法如下: (*fp)(); 按照人们的惯性思维,那么我们可以这转载 2009-05-19 21:51:00 · 10934 阅读 · 1 评论 -
非对齐地址访问问题
ARM,DSP,POWERPC等不支持非对齐地址访问,X86支持非对齐地址访问。 为何要字节对齐? 从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开始存取。 TCPIP协议栈一直采用的uip,感觉不是很好,想采用网上的原创 2009-06-24 09:54:00 · 5876 阅读 · 1 评论 -
结构体字节对齐
为何要字节对齐? 从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开始存取。 MDK 字节对齐关键字 __packedtypedef __packed struct abc{ int a; int b;}st转载 2009-05-09 23:07:00 · 5208 阅读 · 2 评论 -
大端模式和小端模式
大端格式:在这种格式中,字数据的高字节存储在低地址中,而字数据的低字节则存放在高地址中,如图2.1所示: 小端格式:与大端存储格式相反,在小端存储格式中,低地址中存放的是字数据的低字节,高地址存放的是字数据的高字节。如图2.2所示: 请写一个C函数,若处理器是Big_endian的,则返回0;若是Little_endian的,则返回1解答:int chec原创 2009-05-13 09:18:00 · 1212 阅读 · 0 评论 -
C语言通用数据类型链表的实现
可接受任意类型的数据的C语言链表的实现(说白了其实就是链表结构体中有一个void * 类型指针即可) 今天在宣讲会上讲了一下我所写的那个可以接收任意类型的参数类型的链表,感觉还是没有讲清楚,再次整理一下 ,同样的道理我们可以构造出其它的可以接受任意数据类型的结构,如:可接收任意数据类型的栈,可接收任意数据类型的队列,可接收任意数据类型的树················转载 2009-09-24 09:22:00 · 2545 阅读 · 0 评论 -
指针的指针
主要两个用途1)用于改变单个指针变量的值, 通常在调用函数里malloc赋值该指针,在调用函数外free该指针。int change_point(char** errMsg);{ *errMsg=(char*)malloc(100)strcpy(*errMsg,"error test!");}char *zErr ;change_point(&am...原创 2011-11-11 18:45:21 · 901 阅读 · 0 评论 -
关于函数返回值为指针类型的分析
我们平时说的堆栈指的是栈(这里谈的不是数据结构的堆栈,俺没研究)1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其 操作方式类似于数据结构中的栈。 2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回 收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。转载 2011-11-19 22:34:08 · 1963 阅读 · 0 评论 -
例解GNU C之零长数组与变长数组
前言:计算机语言是编译器和程序员交流的依据和规范,GNU C是GCC特有的功能,在Linux内核中被广泛应用。 帮助文档:http://gcc.gnu.org/onlinedocs/gcc-4.6.2/gcc/C-Extensions.html#C-Extensions 1、零长数组 GNU C允许声明长度为零的数组,但它只能被用于结构体的最后一个成员。转载 2016-12-20 09:52:28 · 1214 阅读 · 0 评论 -
linux 循环双链表(list.h)
最近看linux 链表,网上很多代码的讲解,总有点知其然不知其所以然的感觉,我看了下有点自己想法,特记录如下:我们之前学习双链表结构体一般如下typedef struct __Node{ int data; 数据 struct __Node *pre; 指向前一个结点指针 struct __Node *next; 指向下一个结点指针原创 2014-07-01 15:47:22 · 1525 阅读 · 0 评论 -
不可重入函数总结
1.malloc,free, printf均是不可重入函数(意味不能在中断函数或信号处理函数同时调用),但是线程安全函数(意味它可以被多个线程调用)2.函数有static变量,则该函数是不可重入函数满足下面条件之一的多数是不可重入函数:(1)使用了静态数据结构;(2)调用了malloc或free;(3)调用了标准I/O函数;标准io库很多实现都以不可重入的方式使用全原创 2016-04-11 12:59:55 · 5958 阅读 · 0 评论 -
inet_ntoa函数陷阱
今天编程时遇到一个很诡异的问题,是关于inet_ntoa函数的。先看一个测试程序#include stdio.h>#include sys/socket.h>#include netinet/in.h>#include arpa/inet.h>#include string.h>int main(int argc, char* argv[])转载 2016-03-24 18:17:31 · 4250 阅读 · 0 评论 -
如何设置SVN提交时强制添加注释
1. 替换原来配置文件操作:拷贝Global.CF3到“我的文档\Source Insight\Settings”下面---网上找个合适的配置文件2. 在Option里的Document Option(ALT+T)左边有个Screen Font,点进去就可以设置了 ---增大字体,解决汉字上边显示不全问题3. 添加SuperBackspace.em宏,解决汉字删除问题---网上找“Supe转载 2010-08-25 18:33:00 · 3850 阅读 · 0 评论 -
堆和栈的区别
一、预备知识—程序的内存分配 一个由C/C++编译的程序占用的内存分为以下几个部分 1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其 操作方式类似于数据结构中的栈。 2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回 收 。注意它与数据结构中的堆是两回事,分配方式倒是转载 2009-05-12 08:56:00 · 785 阅读 · 0 评论 -
深入“函数指针”
1. 首先,在C语言中函数是一种function-to-pointer的方式,即对于一个函数,会将其自动转换成指针的类型.如:<a class="smalltxt" style="font: 12px song, Verdana; color: #000000; text-decoration: none;" onclick="function onclick(){copyco转载 2009-05-11 10:02:00 · 961 阅读 · 0 评论 -
关键字volatile使用问题
Introduction to the Volatile Keyword认识关键字Volatile • 在内存中进行地址映射的设备寄存器;• 在中断处理程序中可能被修改的全局变量;• 多线程应用程序中的全局变量;例子(1)主程序和中断共享static volatile int i=0;int main(void){...while转载 2009-05-21 13:50:00 · 1478 阅读 · 0 评论 -
lwip--有趣的数组定义(预处理)
在全局定义的宏和在一个函数内部定义的宏有什么不同?是不是和变量的定义含义差不多,作用域不同?还是有其他的什么差别? 宏定义的作用域是同文件内从定义开始起作用 直到取消定义 static u8_t memp_memory[MEM_ALIGNMENT - 1 #define LWIP_MEMPOOL(name,num,size,desc) + ( (num) * (MEMP_S原创 2009-06-29 09:06:00 · 5268 阅读 · 0 评论 -
想成为嵌入式程序员应知道的0x10个基本问题
C语言测试是招聘嵌入式系统程序员过程中必须而且有效的方法。这些年,我既参加也组织了许多这种测试,在这过程中我意识到这些测试能为面试者和被面试者提供许多有用信息,此外,撇开面试的压力不谈,这种测试也是相当有趣的。 从被面试者的角度来讲,你能了解许多关于出题者或监考者的情况。这个测试只是出题者为显示其对ANSI标准细节的知识而不是技术技巧而设计吗?这是个愚蠢的问题吗?如要你答出某转载 2009-05-30 11:51:00 · 1373 阅读 · 1 评论 -
do while(0)在宏定义中的应用
这是一个奇怪的循环,它根本就只会运行一次,为什么不去掉外面的do{..}while结构呢?我曾一度在心里把它叫做“怪圈”。原来这也是非常巧妙的技巧。在工程中可能经常会引起麻烦,而上面的定义能够保证这些麻烦不会出现。下面是解释:假设有这样一个宏定义#define macro(condition) /if(condition) dosomething()现在在程序中这样使用这个宏:if(temp)转载 2009-05-27 16:30:00 · 1581 阅读 · 0 评论 -
变量类型的转换
变量类型的转换 变量的数据类型是可以转换的。转换的方法有两种, 一种是自动转换,一种是强制转换。 自动转换 自动转换发生在不同数据类型的量混合运算时,由编译系统自动完成。自动转换遵循以下规则: 1.若参与运算量的类型不同,则先转换成同一类型,然后进行运算。 2.转换按数据长度增加的方向进行,以保证精度不降低。如int型和long型运算时,先把int量转成long型后再进行运算。 3.所有的浮转载 2009-05-20 10:53:00 · 1533 阅读 · 0 评论 -
const使用详解
const使用详解作者:康建东关于C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,现将本人的一些体会总结如下,期望对大家有所帮助: 一 const基础如果const关键字不涉及到指针,我们很好理解,下面是涉及到指针的情况: int b = 500;const int* a = &b; [1]int const *a = &b; [2]转载 2009-05-20 10:40:00 · 934 阅读 · 0 评论 -
C语言嵌入式系统编程修炼之道——软件架构篇
1.模块划分模块划分的“划”是规划的意思,意指怎样合理的将一个很大的软件划分为一系列功能独立的部分合作完成系统的需求。C语言作为一种结构化的程序设计语言,在模块的划分上主要依据功能(依功能进行划分在面向对象设计中成为一个错误,牛顿定律遇到了相对论),C语言模块化程序设计需理解如下概念:(1) 模块即是一个.c文件和一个.h文件的结合,头文件(.h)中是对于该模块接口的声明;转载 2009-05-12 09:08:00 · 2494 阅读 · 0 评论 -
C语言嵌入式系统编程修炼之道——性能优化篇
1.使用宏定义在C语言中,宏是产生内嵌代码的唯一方法。对于嵌入式系统而言,为了能达到性能要求,宏是一种很好的代替函数的方法。写一个“标准”宏MIN ,这个宏输入两个参数并返回较小的一个: 错误做法:#define MIN(A,B) ( A 正确做法:#define MIN(A,B) ((A)对于宏,我们需要知道三点:(1)宏定义“像”函数;(2)宏转载 2009-05-12 09:55:00 · 1561 阅读 · 0 评论 -
C语言嵌入式系统编程修炼之道——内存操作篇
.数据指针在嵌入式系统的编程中,常常要求在特定的内存单元读写内容,汇编有对应的MOV指令,而除C/C++以外的其它编程语言基本没有直接访问绝对地址的能力。在嵌入式系统的实际调试中,多借助C语言指针所具有的对绝对地址单元内容的读写能力。以指针直接操作内存多发生在如下几种情况:(1) 某I/O芯片被定位在CPU的存储空间而非I/O空间,而且寄存器对应于某特定地址;(2) 两个CP转载 2009-05-12 09:15:00 · 1696 阅读 · 0 评论 -
C“陷阱”
(1)#define问题#define 宏常量,无语法检测,只是字符替换 #define Max(a,b) (a)>(b) ? (a):(b) //错误 Result = Max(i,j) +2; 结果 Result = (a)>(b) ? (a):(b)+2 ===> (a)>(b) ? (a):((b)+2) #defi原创 2009-05-11 09:17:00 · 803 阅读 · 0 评论 -
KEILC51可重入函数及模拟栈浅析
摘要:本文较详细的介绍了keilc51可再入函数和模拟堆栈的一些概念和实现原理,通过一个简单的程序来剖析keilc51在大存储模式下可重入函数的调用过程,希望能为keilc51和在51系列单片机上移植嵌入式实时操作系统的初学者提供一些帮助。 1、关于可重入函数(可再入函数)和模拟堆栈(仿真堆栈) “可重入函数可以被一个以上的任务调用,而不必担心数据被破坏。可重入函数任何时候都可以被中断转载 2009-06-07 18:30:00 · 1914 阅读 · 3 评论 -
内存陷阱
char *Dosomething(){ char i[32*1024]; memset(i,0,32*1024); ........ return i;} 两个重大问题:1. 临时变量通过堆栈实现的(M51除外),太大的临时变量数组会冲掉堆栈2. 返回堆栈中的地址是非常危险地。因为堆栈中的值在退出函数体后无法确定 关于临时变量转载 2009-06-07 20:28:00 · 1496 阅读 · 0 评论 -
C中常量参与运算的问题
最近在开发中,对常量参与运算时候,出了几个问题,特记录如下:1.例子一(KEIL-51) unsigned char recsum,xorsum; recsum == 0xFF; xorsum == 0x00; if(recsum != (xorsum-1)) //这时候不相等 if(recsum != (unsigned char)(xorsum-原创 2009-10-21 09:43:00 · 2071 阅读 · 0 评论 -
指针数组和数组指针的区别
变量类型判断:变量和哪个关键字先结合,该变量就是什么类型。 例如(1)int (*p)[n]; //p先和*结合,故是一个数组指针 ,即指针指向一个数组(2) int *p[n]; //p先和[n]结合,故是一个指针数组,即数组里面的成员是指针以前这两问题一直都不是很清晰,写程序也管不了这么多,只要不出错能跑出结果就行,其实很多用C的程序员对C的基础知识都一知转载 2011-09-26 11:17:37 · 1046 阅读 · 0 评论 -
回车,换行,tab,空格
关于“回车”(carriage return)和“换行”(line feed)这两个概念的来历和区别。在计算机还没有出现之前,有一种叫做电传打字机(Teletype Model 33)的玩意,每秒钟可以打10个字符。但是它有一个问题,就是打完一行换行的时候,要用去0.2秒,正好可以打两个字符。要是在这0.2秒里面,又有新的字符传过来,那么这个字符将丢失。 于是,研制人员想了个办法解决这个问题,就是原创 2011-05-27 09:51:00 · 5284 阅读 · 0 评论 -
函数指针数组
数组类型:int a[n] -----------整型类型的数组int *a[n] -----------指针类型的数组(指针数组)void (*fun[n])(void)---------函数类型的数组(函数指针数组) //定义了N个函数指针元素的数组 在编写D12的控制程序时,遇到了一个数组结构的函数指针,于是我们几个人计论了大半天,最后终于搞懂它的奇妙所在。现将转载 2009-06-04 17:25:00 · 1413 阅读 · 0 评论 -
编程规范(记住!)
下面都清楚吗?数组-->指针数组-->函数指针数组指针-->数组指针指针 -->函数指针 【规则1-2-1】为了防止头文件被重复引用,用ifndef/define/endif 结构产生预处理块。 【建议1-2-2】头文件中只存放“声明”而不存放“定义”,即不要在头文件定义变量等 【建议1-2-3】对于全局变量,在C文件定义,在头文件中extern int g_v转载 2009-05-10 11:17:00 · 898 阅读 · 0 评论 -
#define用法
#define 宏常量,无语法检测,只是字符替换用宏定义--屏蔽代码的作用,比用/* */更有用,特别是要屏蔽代码中有/* */注释的代码#if 0..............#endif 在全局定义的宏和在一个函数内部定义的宏有什么不同?是不是和变量的定义含义差不多,作用域不同?还是有其他的什么差别? 宏定义的作用域是同文件内从定义转载 2009-05-10 11:10:00 · 901 阅读 · 0 评论 -
STM32堆栈
1.堆和栈大小 定义大小在startup_stm32f2xx.sStack_Size EQU 0x00000400 AREA STACK, NOINIT, READWRITE, ALIGN=3Stack_Mem SPACE Stack_Size__initial_sp; Heap Configura原创 2012-05-19 15:43:17 · 25035 阅读 · 5 评论 -
C语言全局变量多文件使用
#include "../driver/ppc860spi.h" --------上级目录采用“..” 定义一个全局变量,想在多个文件中使用,在源文件定义,在头文件声明,需要调用引用该文件即可代码如下: //var.h extern int var ;原创 2011-10-26 20:57:38 · 3273 阅读 · 0 评论