C语言高级
zhandoushi1982
这个作者很懒,什么都没留下…
展开
-
循环发送递增数据的方法 && BCD码和ASCII码的转换
在一些测试程序中,有时需要通过一个循环发送数据来查看反馈结果,才能取得适合的正确参数。比如I2C写某数据的时候,如果有调试工具可以通过调节写入参数得到准确的某个寄存器值;如果没有调试工具,可以通过一个循环写数据来观察反馈值来获得准确值。 如下:int cm3623_write_ps(){ u8 buf = 0x01,i; ...原创 2011-12-06 23:16:11 · 2008 阅读 · 0 评论 -
C语言解析文本的程序 && sscanf/sprintf
很多时候软件用到解析一个文本的场合,比如解析一个TXT文件,将有用的数据读出来并进行处理;或者读一个流文件,找出对应的值取出来。实例如下,一个调试文本是如下格式:// R, Gr, Gb, B per light source 0F12 4819 //,16,0},/* Clock0, System clock 58MHz, PVI clock 48Mhz, (Preview)原创 2012-03-12 14:31:03 · 3523 阅读 · 1 评论 -
有序表的二分查找
需要注意两点:二分查找与二叉排序树是有区别的;传数组当参数时,要把数组长度一起做参数传入。(1)二分查找的程序 int Binarey_Search(int *Array,int length,int Data)//数组中查找Data,数组长度length{原创 2011-08-14 22:42:12 · 5548 阅读 · 0 评论 -
C语言位操作中的置0和置1
<br /> C语言中,有时需要进行置位操作,比如针对其中的某些位。这样做的目的是既达到了目标,又不会影响其它位。常用的置位操作如下:<br />#define setbit(x,y) x|=(1<<y) //将X的第Y位置1<br />#define clrbit(x,y) x&=~(1<<y) //将X的第Y位清0<br /> 举个例子:<br />int main(int argc, char* argv[])<br />{<br /> unsigne原创 2011-01-11 23:03:00 · 18586 阅读 · 1 评论 -
相对路径的使用&&调用.C中的函数
在实际的编程工作中,除了调用系统定义的头文件之外,还要调用自定义的头文件。前者很多时候是编译器会指定头文件所在的文件夹路径,.C文件中只需要#include 就可以了;而自定义头文件的调用,很多时候是调用其他目录下,这时就需要采用相对路径来指明,比如:#include "../../DRIVERS/NLED/nled_pdd.h"。每一个“..”表示返回上一层目录,路径层级的跳转是从.C文件所在的那层开始。原创 2010-12-27 09:12:00 · 1822 阅读 · 0 评论 -
C开发中堆和栈的差别
(1)栈区(stack)— 由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。 例如,声明在函数中的一个局部变量int b;系统自动在栈中为b开辟空间。只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。比如:char* AllocStrFromStack(){ char pstr[100]; retu原创 2010-04-12 17:02:00 · 1096 阅读 · 0 评论 -
#error和#progma && 宏定义换行符“\”
(1),#error 编译程序时,只要遇到 #error 就会跳出一个编译错误,既然是编译错误,要它干嘛呢?其目的就是保证程序是按照你所设想的那样进行编译的。下面举个例子:程序中往往有很多的预处理指令#ifdef XXX...#else...#endif 当程序比较大时,往往有些宏定义是在外部指定的(如makefile),或是在系统头文件中指定的,当原创 2010-04-12 17:40:00 · 1830 阅读 · 0 评论 -
二维数组存储字符串的补充 && 数组首元素地址和整个数组地址
首先用一个实例来说明二维数组的第一维单元存储的是第二维的地址。如下: 三行输出结果是一样的,都是[0][0]元素的地址,也就是说二维数组名和第一维单元都表示数组首址,也是00元素的地址。相当于纵向一维的每个元素存的是第二维的索引地址。 关于字符串有个实例情况说明:char *aa[2]={“abcd”,”ABCD”},显然这是指针数组的模式,所以数组的两个元素其实是原创 2010-08-05 21:20:00 · 8863 阅读 · 0 评论 -
字符型常量
(1)哪些是字符型常量。BCA,"a"B,'//'C,'W'D,''结果是:A是字符串;B是字符,以%C输出是/,可见第一个/是转义符号;C是字符;D不是,两个引号间啥都没有。(2)哪些是字符型常量。BCDA,CH =‘a+b’;B,CH=’/0’;C,CH=’7’+'9’;D,CH=17+19;下面分别做解释如下:A的运算结果是b,且有警告;B结果是空格,/0是字符串的结尾符,所以本身是个字符,本质是ASCII为0的NUL字符,直接用printf("%c",0);结果也是空格;C的结果是两个字符的ASCI原创 2010-06-11 22:52:00 · 7222 阅读 · 0 评论 -
两个字节合并成一个字
(1)今天在写程序的时候,无意间发现了一个问题。两个字节合并成一个字,怎么运算。我是采用的以下方式:高字节UA,低字节UB,则合并结果是:UA int main(int argc, char* argv[]){ unsigned char ua = 0x66,ub = 0x77; printf("data is 0x%x /n", (ua&0x03)原创 2010-06-30 22:09:00 · 14090 阅读 · 1 评论 -
char数组存字符串 && unsigned char数组存字符串 && 数组当形参 && ASCII控制字符不被输出
(1)字符串拷贝char * strcpy(char * dest,const char *src){ char *tmp = dest; while ((*dest++ = *src++) != '/0') return tmp;}(2)字符串拷贝(带长度)char * strncpy(char * dest,con原创 2010-05-07 16:59:00 · 3288 阅读 · 0 评论 -
整型数转成字符,以及itoa,atoi
(1)将整型数12345转单字符输出,需强记几个字符的ASCII码:NULL的是0;0的是0X30;A的是0X41;a的是0X61。程序如下:int main(int argc, char* argv[]){ unsigned int num=12345,temp=0; unsigned char Array[5]={0,0,0,0,0}; Array[0]原创 2011-06-07 22:47:00 · 4030 阅读 · 2 评论 -
CRC16调用函数
inline 关键字用来定义一个类的内联函数,引入它的主要原因是用它替代C中“表达式形式的宏定义”。表达式形式的宏定义如下一例:#define ExpressionName(Var1,Var2) (Var1+Var2)*(Var1-Var2),为什么要取代这种形式呢?1, 首先谈一下在C中使用这种形式宏定义的原因,C语言是一个效率很高的语言,这种宏定义在形式及使用上像一个函数,但它使原创 2009-12-19 21:59:00 · 2237 阅读 · 1 评论 -
避免多重载入
编辑程序很多时候会出现重定义的错误,为了避免出错,需要理顺。(1)通常我们会采用#include “*.h”的方式载入某个*.C对应的.H文件,如果要避免该.H文件被不同文件载入多次,需要在.H文件头尾用 #ifndef ***_h#define ***_h………………#endif这样的话,只要载入了一次,***_h就是被定义过了的,就算其他地方想载入第二次,预编译原创 2009-09-27 10:59:00 · 1392 阅读 · 0 评论 -
C程序中main参数argv和argc && getopt和getopt_long函数
命令行界面的程序,通常都需要输入命令行参数帮助程序执行。main是最典型的此类应用。#include #include int main(int argc, char *argv[]){ int count; printf("The command line has %d arguments: \r\n", argc - 1); for(count = 1; cou转载 2010-03-15 20:02:00 · 2604 阅读 · 0 评论 -
用数组实现堆栈 && 判断接收到的数据是否连续
<br /> 用数组方法实现堆栈,栈顶在上,栈底在下。<br />struct _Stack{<br /> Item* elem; //数组元素<br /> int top; //栈顶<br /> int nMax; //大小<br />};<br />typedef struct _Stack Stack;<br />typedef Stack* pStack;<br /> <br />pStack Stack转载 2011-01-16 00:08:00 · 1855 阅读 · 0 评论 -
C语言中的随机数 && 商余函数ldiv && 长数据分段发送的方法
在C语言中,rand()函数可以用来产生随机数,但它是一个伪随机数。它的产生结果是根据一个数,我们可以称它为种子为基准以某个递推公式推算出来的一系列数,当这系列数很大的时候,就符合正态公布,从而相当于产生了随机数。当计算机正常开机后,这个种子的值是定了的,除非你破坏了系统;为了改变这个种子的值,C为此提供了srand()函数,它的原形是void srand( int a)。 rand()会返回一系列随机数值,为0至RAND_MAX之间的随机数值,而RAND_MAX定义在stdlib.h原创 2011-04-14 23:34:00 · 2211 阅读 · 0 评论 -
负数在计算机中的表示
<br /> 我们已经知道计算机中,所有数据最终都是使用二进制数表达。我们也已经学会如何将一个10进制数如何转换为二进制数。我们仍然没有学习一个负数如何用二进制表达。比如,假设有一int类型的数,值为5,那么,我们知道它在32位计算机中表示为:00000000 00000000 00000000 00000101。在计算机中,负数以其正值的补码形式表达。<br /> 什么叫补码呢?这得从原码,反码说起。原码:一个整数,按照绝对值大小转换成的二进制数,称为原码。反码:将二进制数按位取反,所得的新二原创 2010-06-11 22:36:00 · 3126 阅读 · 0 评论 -
C语言支持的四种变量存储类型 && 变量在内存中的位置
一)auto:auto称为自动变量(局部变量)。局部变量是指在函数内部说明的变量(有时也称为自动变量)。所有的非全程变量都被认为是局部变量,所以auto实际上从来不用。局部变量在函数调用时自动产生,但不会自动初始化,随函数调用的结束,这个变量也就自动消失了。下次调用此函数时再自动产生,还要再赋值,退出时又自动消失。二)static:static称为静态变量。根据变量的类型可以分为静态局部变量和静态原创 2010-03-28 22:42:00 · 11810 阅读 · 2 评论 -
C/C++语言void及void指针深层探索
<br />(1)许多初学者对C/C++语言中的void及void指针类型不甚理解,因此在使用上出现了一些错误。本文将对void关键字的深刻含义进行解说,并详述void及void指针类型的使用方法与技巧。<br />(2)void。void的字面意思是“无类型”,void *则为“无类型指针”,void *可以指向任何类型的数据。void几乎只有“注释”和限制程序的作用,因为从来没有人会定义一个void变量,让我们试着来定义:void a;这行语句编译时会出错,提示“illegal use of type转载 2010-09-20 22:33:00 · 1356 阅读 · 0 评论 -
enum与typedef enum的用法
一,两者的用法 枚举类型定义用关键字enum标识,形式为: enum 标识符 { 枚举数据表};枚举数据(枚举常量)是一些特定的标识符,标识符代表什么含义,完全由程序员决定。数据枚举的顺序规定了枚举数据的序号,从0开始,依次递增。enum status{ copy, delete};枚举类型status仅有两个数据,一个是copy,一个原创 2010-03-23 22:26:00 · 55884 阅读 · 10 评论 -
#ifdef和#if defined的差别
注意两者都有个define的作用,区别在于使用方式上。前者的通常用法是:#ifdef XXX ....#else ....#endif 只能在两者中选择是否有定义。对于后者,常用法是:#if defined xxx1 .... #elif defined xxx2 ....#elif defined xxx3 ....原创 2010-02-23 11:41:00 · 37675 阅读 · 3 评论 -
assert断言的使用
程序一般分为Debug 版本和Release 版本,Debug 版本用于内部调试,Release 版本发行给用户使用。assert(表达式); 的意思是:当表达式为真时,程序继续运行,如果表达式为假,那程序就会停止运行,并提示错误信息。注意:assert是一个宏,只在debug版本中起作用,在release版本中,该语句是不起任何作用的。 以下为一个使用了断言的C源程序tes原创 2009-12-01 22:28:00 · 1696 阅读 · 0 评论 -
do{} while(0)的使用
如果你做过linux,你就会发现在很多地方的宏定义会用到:#define XXX_XXXX do{xxxx;xxx;}while(0)为什么这种执行一次的语句要有这种方式来实现。当然有原因! 为了看起来更清晰,这里用一个简单点的宏来演示:#define SAFE_DELETE(p) do{ delete p; p = NULL} while(0)假设这里去掉do...原创 2009-12-01 23:00:00 · 1158 阅读 · 0 评论 -
##黏贴符号的使用
在C语言中会碰到一些用到##的地方。比如:#define CONFIG_S3C_GPIO_SPACE 8 //可忽略#define S3C64XX_GPIO_A_NR (8)#define S3C64XX_GPIO_A_START 0........#define S3C64XX_GPIO_NEXT(__gpio) ((__gpio##_ST原创 2009-11-17 23:44:00 · 1738 阅读 · 0 评论 -
中断服务程序的要求
中断是嵌入式系统中重要的组成部分,但是在标准C中不包含中断。许多编译开发商在标准C上增加了对中断的支持,提供新的关键字用于标示中断服务程序 (ISR),类似于__interrupt、#program interrupt等。当一个函数被定义为ISR的时候,编译器会自动为该函数增加中断服务程序所需要的中断现场入栈和出栈代码。 中断服务程序需要满足如下要求: (1)不能返回值; (2)不能原创 2009-11-04 18:58:00 · 2048 阅读 · 0 评论 -
VOLATILE的用法
volatile的本意是“易变的”,使用它的目的是如何避免编译器进行优化。由于访问寄存器的速度要快过RAM,所以编译器一般都会作减少存取外部RAM的优化,而不必要的优化可能对程序的执行存在影响。比如:static int i=0;int main(void){ ... while (1) { if (原创 2009-09-24 19:29:00 · 1157 阅读 · 0 评论 -
const的用法
const是一个C语言的关键字,它限定一个变量不允许被改变。使用const在一定程度上可以提高程序的安全性和可靠性,另外,在观看别人代码的时候,清晰理解const所起的作用,对理解对方的程序也有一些帮助。下面以一些实例来说明其用法及用途的差别:1, 为什么象下面的例子用const变量来初始化数组,ANSI C的编译器会报告错误呢?const int n = 5;int a[n];答案是原创 2010-03-27 21:49:00 · 1330 阅读 · 0 评论 -
怎么样运算64位整型数据
<br /> C语言中本身是自带表示64位数据运算的。用long long来定义,%lld来定义输出格式。_int64则是微软自带的数据类型,用%I64来定义输出格式。比如:<br />Long long a = LLONG_MAX;<br />Printf("%lld",a);<br /><br />和<br />_int64 n;<br />Printf("%I64",n);原创 2010-08-05 21:41:00 · 4570 阅读 · 3 评论 -
联合(union)用法
联合(union)在C里面见得并不多,但是在一些对内存要求特别严格的地方,联合又是频繁出现,那么究竟什么是联合?怎么去用?有什么需要注意的地方呢?(1)什么是联合?一种构造类型的数据结构。在一个“联合”内可以定义多种不同的数据类型, 一个被说明为该“联合”类型的变量中,允许装入该“联合”所定义的任何一种数据,这些数据共享同一段内存,已达到节省空间的目的。这是一个特殊的地方,也是联合的特转载 2010-05-26 22:22:00 · 1269 阅读 · 0 评论 -
结构体成员对齐的问题
现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。(1)现象 比如有些平台每次读都是从偶地址开始,如果一个int型(假设为32位系统)如果存放在偶地址开始的地方,那么一原创 2010-05-13 20:20:00 · 1277 阅读 · 0 评论 -
结构体数据结构的位成员
在结构体的实际使用中,可能会用到带冒号的单元分配使用,其占的空间是有变化的,打个比方,如下。typedef unsigned char U8;typedef struct{ U8 B0:1; U8 B1:1; U8 B2:1; U8 B3:1; U8 B4:1; U8 B5:1; U8 B6:1; U8 B原创 2010-05-13 19:54:00 · 1466 阅读 · 0 评论 -
单链表和双向链表
(1)单链表 链表是一种常见的重要的数据结构。它是动态地进行存储分配的一种结构。它可以根据需要开辟内存单元。定义结构体如下:typedef int DATATYPE;typedef struct node{ DATATYPE info; struct node *next;}LINKLIST;建立单向链表:LINKLIST *create() //返回头节原创 2010-05-06 20:48:00 · 1276 阅读 · 0 评论 -
冒泡排序
冒泡排序:从下往上看,依次比较相邻的两个数,将大数放在前面,小数放在后面。即首先比较第1个和第2个数,将大数放前,小数放后。然后比较第2个数和第3个数,将大数放前,小数放后,如此继续,直至比较最后两个数,将大数放前,小数放后,此时第一趟结束,在最后的数必是所有数中的最小数。重复以上过程,仍从第一对数开始比较(因为可能由于第2个数和第3个数的交换,使得第1个数不再大于第2个数),将大数放原创 2010-05-06 20:23:00 · 816 阅读 · 0 评论 -
C++的public,private,protected权限
由于不存在包的概念,因此,C++的protected与java中的protected有所不同,Java中的protected不但子对象可以访问,而且包里的其它地方,也可以显示的通过子对象调用,如package pack1public class A{ protected int a;}package pack1public class B{转载 2010-04-09 20:31:00 · 2598 阅读 · 0 评论 -
数据类型的显式转换和隐式转换
如下面的一段小程序:void main(void){ unsigned char a; unsigned int b; b=100*4; a=b; printf(“%d”,a); while(1);} 如果你是细心的朋友定会发现a的值是不会等于100*4的。是的,a和b一个是char类型一个是int类型,从以前的学原创 2010-04-12 17:58:00 · 2080 阅读 · 0 评论