C语言小问题集锦

8 篇文章 0 订阅
1 篇文章 0 订阅
//***********************************************************************//
/*****************************************************
*文件名:
*创建者:Paulliam
*创建时间:2021-05-26
*文件说明:
******************************************************/
//***********************************************************************//
/*****************************************************
*文件名:
*创建者:Paulliam
*创建时间:2021-05-26
*文件说明:
******************************************************/
//***********************************************************************//
/*****************************************************
*文件名:指针自加 *p++与(*p)++,*(p++)的区别
*创建者:Paulliam
*创建时间:2021-05-26
*文件说明:
*p++:值为arr[0],即1,该语句执行完毕后,p指向arr[1] 为5
(*p)++:先*p,即arr[1]=5,然后5+1,该语句执行完毕后arr[1] =6 
*(p++):效果等同于*p++
******************************************************/
#include<stdio.h>
int main(void)
{
    int arr[5]={1,5,10,15,20};
    int *p=arr;
    int a,b,c;
    a=*p++;    //先取p指向的单元的值,再参与赋值运算,最后对指针加一
    printf("%d  %d\n",a,*p);

    b=(*p)++;    //先取p指向的单元的值,然后参与运算(赋值运算),最后对该单元的值加一
    printf("%d  %d\n",b,*p);
    c=*(p++);    //等同*p++,先取p指向的单元的值,再参与赋值运算,最后对指针加一
    printf("%d  %d\n",c,*p);

}
/*
执行结果:
1  5
5  6
6  10
请按任意键继续. . .
*/
//***********************************************************************//
/*****************************************************
*文件名:指针自加 改变指针指向地址 地址传递 改变指针地址
*创建者:Paulliam
*创建时间:2021-05-26
*文件说明:如果要通过调用某个函数,以指针传递的形式改变该指针的指向地址,则应该用'&'对指针取地址后再当做参数调用函数 
******************************************************/
#include <stdio.h>
#include <stdlib.h>

typedef unsigned char uint8_t;

uint8_t* get_which_dot(uint8_t **src, uint8_t dot_num,uint8_t separator)
{
	uint8_t dot =0;
	uint8_t* ret =NULL;

	while(**src)
	{
		if(**src == separator)
		{
			if(++dot == dot_num){
				ret = *src+1;
				break;
			}			
		}
		//要改变一级指针的指向位置,则用符号'*'对二级指针取内容,即可调整一级指针的指向地址 
		(*src)++;	//将*src所指的数据的值加一,即将传递进来的实参pr加一 
					//*src++ 等效于 *(src++) ,表示取src所指单元的值,然后src指向下一单元,即src自加1 
	}
	return ret;
}

int main(int argc, char *argv[]) {
	uint8_t str[50] ={0};
	uint8_t *pr = str;
	int a[4][4];
	int num=0;
	int i=0;
	printf("请输入一个字符串:");
	scanf("%s",str);
	printf("your str = %s\n",str);
	printf("str address before= %#x\n",str);
	printf("pr address before= %#x\n",pr);
	for(i=0;i<10;i++)
	{
		printf("str[%d] address = %#x, %c\n",i,&str[i],str[i]);
	}
	num = atoi((void *)get_which_dot(&pr, 2, ',')); 
	printf("your num = %d\n",num);
	printf("pr address after= %#x\n",pr);
			
	printf("\naddr of int a is:\n%#x,%#x\n",a,*a+1);//a,地址若为0x0012ff08,则指向其16个元素;
	printf("%#x,%#x\n",&a[0],&a[1]);//a,地址若为0x0012ff08,则指向其16个元素;
	printf("%#x,%#x\n",&a[0][0],&a[0][1]);
	return 0;
}

/*
执行结果:
请输入一个字符串:1,2,3,4,5,6
your str = 1,2,3,4,5,6
str address before= 0x22fe00
pr address before= 0x22fe00
str[0] address = 0x22fe00, 1
str[1] address = 0x22fe01, ,
str[2] address = 0x22fe02, 2
str[3] address = 0x22fe03, ,
str[4] address = 0x22fe04, 3
str[5] address = 0x22fe05, ,
str[6] address = 0x22fe06, 4
str[7] address = 0x22fe07, ,
str[8] address = 0x22fe08, 5
str[9] address = 0x22fe09, ,
your num = 3
pr address after= 0x22fe03

addr of int a is:
0x22fdb0,0x22fdb4
0x22fdb0,0x22fdc0
0x22fdb0,0x22fdb4
请按任意键继续. . .
*/
//***********************************************************************//
/*****************************************************
*文件名:韦根协议 奇校验 偶检验 奇偶校验 wiegand
*创建者:Paulliam
*创建时间:2018-07-05
*文件说明:
******************************************************/
//功能:把数组封包成韦根26的格式,并发送出去
// 原理是把每个字节的低4位取出,来计算这个字节的值
//入口:str=要封包的数组,
//出口:DATA0P3.0;DATA1=P3.1
//设计:大鹏,大鹏艾迪,2006/4/11
 
void delay_100us(void)
{
    //-------------------------延时100us
    TR0 = 0;
    TH0 = (65536 - 78)/256; //定时100us
    TL0 = (65536 - 78)%256;
    TF0 = 0;
    ET0 = 0;
    TR0 = 1;
    while (!TF0) { ;}
}
void delay_1500us(void)
{
    TR0 = 0;
    TH0 = (65536 - 1382)/256; //定时1500us
    TL0 = (65536 - 1382)%256;
    TF0 = 0;
    ET0 = 0;
    TR0 = 1;
    while (!TF0) { ;}
}
void WG_send_bit_1(void)
{
    WG_DATA1 = 0;
    //----------------------延时100us
    delay_100us();
    WG_DATA1 = 1;
    //-------------------------------延时一个发送周期
    delay_1500us();    
}
void WG_send_bit_0(void)
{
    WG_DATA0 = 0;
    //----------------------延时100us
    delay_100us();
    WG_DATA0 = 1;
    //-------------------------------延时一个发送周期
    delay_1500us();    
}
 
void send_wiegand26(uchar *str)
{
    //| wiegand[0] | wiegand[1] | wiegand[2] |
    //| *str *(str + 1) | *(str + 2) *(str + 3)| *(str + 4) *(str + 5)|
    uchar data i;
    uchar data check_temp; //韦根包奇偶效验中间暂存
    bit data even; //韦根包前12位偶效验
    bit data odd; //韦根包后12位齐效验
    uchar data wiegand[3]; //韦根包数据24位
 
 
    //--------------------------------端口方向定义
    P3M0 = 0x00; //普通I/O口
    P3M1 = 0x00;
    //================================数组到韦根包的转化
    wiegand[0] = wiegand[0]|((*str)<<4);//原理是把每个字节的低4位取出,来计算这个字节的值
    wiegand[0] = wiegand[0]|(*(str+1)&0x0f);
    wiegand[1] = wiegand[1]|(*(str+2)<<4);
    wiegand[1] = wiegand[1]|(*(str+3)&0x0f)
    wiegand[2] = wiegand[2]|(*(str+4)<<4);
    wiegand[2] = wiegand[2]|(*(str+5)&0x0f);
 
    //--------------------------------计算前12位1的个数是否为偶数,为偶效验用
    check_temp = wiegand[1]&0xf0;
    check_temp ^= wiegand[0];
    check_temp ^= check_temp>>4;
    check_temp ^= check_temp>>2;
    check_temp ^= check_temp>>1;
    even=!(check_temp&1);
 
    //--------------------------------计算后12位1的个数是否为偶数,为奇效验用
    check_temp = wiegand[1]&0x0f;
    check_temp ^= wiegand[2];
    check_temp ^= check_temp>>4;
    check_temp ^= check_temp>>2;
    check_temp ^= check_temp>>1;
    odd=check_temp&1;
 
    //================================启动发送,用定时器做时间延时
    //--------------------------------韦根 输出端初始化
    WG_DATA0 = 1;
    WG_DATA1 = 1;
    //--------------------------------发送偶效验
    if(even)
    {
        WG_send_bit_1();
    }
    else
    {
        WG_send_bit_0();
    }
    //-------------------------------发送24位数据
    for(i = 0;i<24;i++)
    {
        //---------------------------韦根 输出端初始化
        if((wiegand[0])&0x80)
        {
            WG_send_bit_1();
        }
        else
        {
            WG_send_bit_0();
        }
        (*(long*)&wiegand[0]) <<= 1;
    }
    //==============================发送奇效验位
    if(odd)
    {
        WG_send_bit_1();
    }
    else
    {
        WG_send_bit_0();
    }
}

//***********************************************************************//
/*****************************************************
*文件名:动态分配多维数组、动态分配二维数组
*创建者:Paulliam
*创建时间:2018-04-10
*文件说明:
******************************************************/
传统的解决方案是分配一个指针数组, 然后把每个指针初始化为动态分配的 
“列”。以下为一个二维的例子: 

     #include  <stdlib.h> 

         int  **array1  =  malloc(nrows   * sizeof(int  *)); 
         for(i  = 0;  i < nrows;   i++) 
              array1[i]  =  malloc(ncolumns   * sizeof(int)); 

     当然,  在真实代码中,  所有的malloc 返回值都必须检查。你也可以使用 
sizeof(*array1) 和sizeof(**array1) 代替sizeof(int *) 和sizeof(int)。 

    你可以让数组的内容连续, 但在后来重新分配列的时候会比较困难, 得使用一 
点指针算术: 

         int  **array2  =  malloc(nrows   * sizeof(int  *)); 
         array2[0]   = malloc(nrows   * ncolumns   * sizeof(int)); //先获取整个分配空间的首地址,即第一个元素的首地址
         for(i  = 1;  i < nrows;   i++) 
              array2[i]  =  array2[0]  + i  * ncolumns; 

    在两种情况下, 动态数组的成员都可以用正常的数组下标arrayx[i][j] 来访问 
(for 0 <= i <nrows 和0  <= j <ncolumns)。 

    如果上述方案的两次间接因为某种原因不能接受, 你还可以同一个单独的动 
态分配的一维数组来模拟二维数组: 

     int *array3   = malloc(nrows   * ncolumns  *  sizeof(int)); 

    但是, 你现在必须手工计算下标, 用array3[i * ncolumns + j] 访问第i, j 个成 
员。使用宏可以隐藏显示的计算, 但是调用它的时候要使用括号和逗号, 这看起来 
不太象多维数组语法, 而且宏需要至少访问一维。 

    另一种选择是使用数组指针: 

     int (*array4)[NCOLUMNS]    =  malloc(nrows   * sizeof(*array4)); 

    但是这个语法变得可怕而且运行时最多只能确定一维。 
//***********************************************************************//
/*****************************************************
*文件名:判断指针是否为空
*创建者:Paulliam
*创建时间:2017-07-01
*文件说明:
******************************************************/
if(!p) 等价于 if(p == 0)
if(p)  等价于 if(p !=  0)	
!expr  本质上等价于 (expr)?0:1 
//***********************************************************************//
/*****************************************************
*文件名:
*创建者:Paulliam
*创建时间:2017-07-01
*文件说明:
******************************************************/
//定义链表结构体类型、链表指针
struct node {
char *item;          //数据域
struct node *next;   //指针域
};
typedef struct node *NODEPTR;   //NODEPTR是一个指针变量,还是一个指针类型

extern int func();   //申明外部函数func()
int (*fp)() = func;  //定义函数指针,并赋初值

//***********************************************************************//
/*****************************************************
*文件名:成员运算符 取地址运算符
*创建者:Paulliam
*创建时间:2017-07-01
*文件说明:
******************************************************/
//申明:
typedef struct
{
    u8  CilentFloor[8];  //访客联动开放的楼层
	u16 CilentTime;      //访客联动楼层开放时长
}ElemType;
typedef struct
{
    ElemType *queue; //指向存储队列的数组空间    //---*****------该数组下面的成员都应该是变量---********---
	u16 front, rear;  //front:指向队首元素的前一个空位置 rear:指向队尾元素
	u16 len;          //当前队列中元素个数-最多元素个数为 MaxSize-1 //超过65535个的时候,系统将出错
	u16 MaxSize;      //数组空间可存储最多元素个数为 MaxSize-1
}Queue;

//调用:
ErrorStatus Memset(u8 *mem, u8 data, u32 len);
ElemType item;
u16 time;

Memset(&item.CilentFloor[0], 0, 8);  //&item.CilentFloor[0]表示取数组元素首地址,成员运算符"."优先级高于取地址运算符“&”
time = Que.queue[(Que.front+1)%Que.MaxSize].CilentTime--;  //最后一个是成员运算符".",而不是指向结构体成员运算符“->”

//***********************************************************************//
/*****************************************************
*文件名:变量强制转换为地址指针
*创建者:Paulliam
*创建时间:2017-12-30
*文件说明:
******************************************************/
#define     __IO    volatile                  /*!< defines 'read / write' permissions   */
typedef __IO uint16_t vu16;
//读取指定地址的半字(16位数据)
//faddr:读地址(此地址必须为2的倍数!!)
//返回值:对应数据.
u16 STMFLASH_ReadHalfWord(u32 faddr)
{
	return *(vu16*)faddr;   //把形参变量faddr强制转换为一颗指向数据类型为vu16的指针,此处返回指针指向地址空间存储的数据
}
//***********************************************************************//
/*****************************************************
*文件名: 浮点数 赋值 整型
*创建者:Paulliam
*创建时间:2017-07-01
*文件说明:
******************************************************/
	u16 adcx;
	float temp;
	temp=(float)adcx*(3.3/4096);
	adcx=temp;	//	比如,浮点数值为1.423 ,那么该赋值操作,会将整数部分1赋值给16位无符号整型数据adcx
//***********************************************************************//
/*****************************************************
*文件名:大端小端
*创建者:Paulliam
*创建时间:2017-07-01
*文件说明:
******************************************************/
//判断大端小端模式
int checkEndion( void )
{
    union check
    {
        int i;
        char ch;
    }c;
    c.i = 1;
    return (c.ch ==1);
}
/*变量 i 占 4 个字节,但只有一个字节的值为 1,另外三个字节的值都为 0。如果取出低地址上的值为 0,毫无疑问,这是大端模式;如果取出低地址上的值为 1,毫无疑问,这是小端模式。*/

//大小端模式转换
#define u32(x)
{
            u32 __x = (x);
            ((u32)(
                        (((u32)(__x) & (u32)0x000000ffUL) << 24) |
                        (((u32)(__x) & (u32)0x0000ff00UL) << 8) |
                        (((u32)(__x) & (u32)0x00ff0000UL) >> 8) |
                        (((u32)(__x) & (u32)0xff000000UL) >> 24) ));
}
//***********************************************************************//
/*****************************************************
*文件名:SPI程序范例
*创建者:Paulliam
*创建时间:2017-08-05
*文件说明:串行数据收发
******************************************************/
//定义:
void RFID_Delay_us(u32 i)
{     
    i = (i*6);
    while( i--){}
}
#define   macRC522_DELAY()  RFID_Delay_us ( 1 )  //@@@@@@@@@@@@@@@@宏定义一个带参函数的调用@@@@@@@@@@@@@//

#define          macRC522_SCK_0()             GPIO_ResetBits( macRC522_GPIO_SCK_PORT, macRC522_GPIO_SCK_PIN )
#define          macRC522_SCK_1()             GPIO_SetBits ( macRC522_GPIO_SCK_PORT, macRC522_GPIO_SCK_PIN )

#define          macRC522_MOSI_0()            GPIO_ResetBits( macRC522_GPIO_MOSI_PORT, macRC522_GPIO_MOSI_PIN )
#define          macRC522_MOSI_1()            GPIO_SetBits ( macRC522_GPIO_MOSI_PORT, macRC522_GPIO_MOSI_PIN )

#define          macRC522_MISO_GET()          GPIO_ReadInputDataBit ( macRC522_GPIO_MISO_PORT, macRC522_GPIO_MISO_PIN )
/*
 * 函数名:SPI_RC522_SendByte
 * 描述  :向RC522发送1 Byte 数据
 * 输入  :byte,要发送的数据
 * 返回  : RC522返回的数据
 * 调用  :内部调用
 */
void SPI_RC522_SendByte ( u8 byte )
{
    u8 counter;
		
    for(counter=0;counter<8;counter++)
    {     
			if ( byte & 0x80 )
					macRC522_MOSI_1 ();
			else 
					macRC522_MOSI_0 ();

			macRC522_DELAY(); //1 us
		
			macRC522_SCK_0 ();

			macRC522_DELAY();
			 
			macRC522_SCK_1();

			macRC522_DELAY();
			 
			byte <<= 1; 
			
    } 	
}

/*
 * 函数名:SPI_RC522_ReadByte
 * 描述  :从RC522发送1 Byte 数据
 * 输入  :无
 * 返回  : RC522返回的数据
 * 调用  :内部调用
 */
u8 SPI_RC522_ReadByte ( void )
{
	u8 counter;
	u8 SPI_Data;
	
	for(counter=0;counter<8;counter++)
	{
			SPI_Data <<= 1;
	 
			macRC522_SCK_0 ();

		    macRC522_DELAY();
		
			if ( macRC522_MISO_GET() == 1)
			{ SPI_Data |= 0x01; }

			macRC522_DELAY();

			macRC522_SCK_1 ();
	
			macRC522_DELAY();
			
	}
	
	return SPI_Data;
	
}
//***********************************************************************//
/*****************************************************
*文件名:单片机IO扩展--74HC595实验	并转串
*创建者:Paulliam
*创建时间:2017-07-27
*文件说明:
******************************************************/
//---------------
//              源码范例1
// 函数功能		   : 向74H595发送一个字节的数据
// 代码来源    :STC平台 keil环境    
//----------------
void Hc595SendByte(u8 dat)
{
	u8 a;

	SRCLK = 1;
	RCLK = 1;

	for(a=0;a<8;a++)		 //发送8位数
	{
		SER = dat >> 7;		 //从最高位开始发送
		dat <<= 1;

		SRCLK = 0;			 //发送时序
		_nop_();
		_nop_();
		SRCLK = 1;	
	}
	RCLK = 0;
	_nop_();
	_nop_();
	RCLK = 1;
}
//----------------
//              源码范例2
//参数: udata: 更新数据,从最后字节开始,低位在前(与S50存储结构有关)。
//      numb : 字节数
// 代码来源        :STM32 
//----------------
#define PinHC595_SCK_L      GPIO_ResetBits(GPIOB,GPIO_Pin_10)
#define PinHC595_SCK_H      GPIO_SetBits(GPIOB,GPIO_Pin_10)
#define PinHC595_RCK_L      GPIO_ResetBits(GPIOB,GPIO_Pin_11)
#define PinHC595_RCK_H      GPIO_SetBits(GPIOB,GPIO_Pin_11)
#define PinHC595_SDI_L      GPIO_ResetBits(GPIOB,GPIO_Pin_1)
#define PinHC595_SDI_H      GPIO_SetBits(GPIOB,GPIO_Pin_1)

void    Updata_595(u8 *udata, u8 numb)
{   
    u8 i,j;
    PinHC595_SCK_L;
    PinHC595_RCK_L;
    //delayms(1);
    
    for(j=numb; j>0; j--)
    {
        for(i =0; i<8; i++)
        {
            if((udata[j-1]>>i)&0x01)  { PinHC595_SDI_H; }
            else                    { PinHC595_SDI_L; }
            
            PinHC595_SCK_H;
            //delayus(1);
            delayms(1);
            PinHC595_SCK_L;
            //delayus(1);
            delayms(1);
        }
    }

    PinHC595_RCK_H;
    //delayus(1);
    delayms(1);
    PinHC595_RCK_L;
}
//***********************************************************************//
/*****************************************************
*文件名:单片机IO扩展--74HC165实验	串转并
*创建者:Paulliam
*创建时间:2017-07-26
*文件说明:
******************************************************/
//---------------
//              源码范例1
// 函数功能		   : 使用165读取一个字节数据
// 代码来源    :STC平台 keil环境    
//----------------
sbit    IN_PL   = P1^6;    //锁存-上升沿触发 锁存数据
sbit    IN_Data = P1^7;    //数据通过P1.7脚移进单片机内处理
sbit    SCK    = P3^6;	   //串行移位时钟
u8 Read74HC165(void)
{  
  u8 i;
  u8 indata;
		
   IN_PL = 0;
   _nop_();        //短暂延时 产生一定宽度的脉冲
   IN_PL = 1;	   //将外部信号全部读入锁存器中
   _nop_(); 
              
   indata=0;   //保存数据的变量清0  
   for(i=0; i<8; i++)
    { 
	  indata = indata<<1;	   //左移一位
	  SCK = 0;   //时钟置0	 
      _nop_();
	  indata |= IN_Data;       //【串行数据最先传输的是字节的最高位,有别于来自 STM32 的源码】
      SCK = 1;   //时钟置1	  
	} 
   
   return(indata);	 
}

//---------------
//描述: 检测电梯编号
//              源码范例2
// 函数功能		   : 使用165读取一个字节数据
// 代码来源        :STM32 
//----------------
void    GetLiftNumber(void)
{
    u8 sernumb =0,i;
    
    //锁存 1 次
    PinADDR_CLK_L; PinADDR_CLK_L;
    PinADDR_SH_L;  PinADDR_SH_L;
    PinADDR_CLK_H; PinADDR_CLK_H;
    PinADDR_SH_H; PinADDR_SH_H;
    //防出错 锁存 2 次
    PinADDR_CLK_L; PinADDR_CLK_L;
    PinADDR_SH_L;  PinADDR_SH_L;
    PinADDR_CLK_H; PinADDR_CLK_H;
    PinADDR_SH_H; PinADDR_SH_H;

    //先读BIT7
    if(PinADDR_IN) { sernumb |= 0x80; }
    PinADDR_CLK_L; PinADDR_CLK_L;

    //再读后7BIT
    for(i=0; i<7; i++)
    {
        //上升沿输出数据
        sernumb >>=1; 
        PinADDR_CLK_H; PinADDR_CLK_H;
        if(PinADDR_IN) { sernumb |= 0x80; }  //【这里体现出,串行数据最先传输的是字节的最低位,有别于来自STC的源码】
        PinADDR_CLK_L; PinADDR_CLK_L;
        
    }

    return sernumb;
}

//***********************************************************************//
/*****************************************************
*文件名:PIC单片机学习笔记
*创建者:Paulliam
*创建时间:2017-07-18
*文件说明:
******************************************************/
/*
通用异步收发传输器(Universal Asynchronous Receiver/Transmitter)

Enhanced Universal Synchronous Asynchronous Receiver Transmitter增强型通用同步异步收发器(EUSART)

usart(Universal Synchronous Asynchronous Receiver Transmitter)通用同步异步收发机

Master Synchronous Serial Port (MSSPx),主同步串行端口
Serial Peripheral Interface (SPI),串行外设接口
Inter-Integrated Circuit (I2C),内部集成电路
	


TRISx 方向控制寄存器的相关位置1,表示输入
PORTx 端口控制寄存器的相关位置1,表示输出高电平;否则,输出低电平
ANSELx 的相关位置1,表示输入模式下的模拟输入
LATx 数据锁存器?

*/

//***********************************************************************//
/*****************************************************
*文件名:Keil uVision4 编译器代码编辑经验总结
*创建者:Paulliam
*创建时间:2017-07-14
*文件说明:
******************************************************/
/*
1,
	//void charging(uint32_t time)  //充电
	//charging(90*60*100);//奇葩!参数传递的时候只能传递该乘法计算结果的低两字节
    charging(540000);  //手动计算出结果后,再传递参数调用函数就不会出错
	
	
*/
//***********************************************************************//
/*****************************************************
*文件名:STM32平台开发学习经验总结
*创建者:Paulliam
*创建时间:2017-07-14
*文件说明:
******************************************************/
/*
1,做除法运算的时候,被除数不要超过一个字节的大小	
	if(i%(1024/8)==0)
	{ ATMEL_flash_read(addr+(i*8), 1024, tranbuff); }


*/
//***********************************************************************//
/*****************************************************
*文件名:STC15芯片烧录
*创建者:Paulliam
*创建时间:2017-07-01
*文件说明:
******************************************************/
/*
1,烧录脚上不能接任何电容或者其他元件,可能导致烧录失败
*/

//***********************************************************************//
/*****************************************************
*文件名:芯片资料阅读技巧
*创建者:Paulliam
*创建时间:2017-07-01
*文件说明:
******************************************************/
/*
【HOLTEK合泰芯片】eg:HT95R33
1,看门狗
  1)时钟源,可能有多个选择,需要在配置选项(开发环境->工具->配置选项)中去配置。
     包括内部自带的时钟源WDTOSC(滴答一次应该是65us)、系统时钟的四分频fSYS/4
  2)自带内部看门狗定时器 震荡器相关介绍在板块 “Oscillator ”一章
2,在合泰Holtek单片机平台,函数名和宏名大小写不要完全一样,否则编译出错,非法.
3,该单片机只适合老版本的V2编译器
  1)char *rainbow[] = { “red”, “orange”, “yellow” }; //编译器V2不支持
  2)对于函数指针,目前enhanced Holtek C只支持全局的const函数指针,且所指函数不能带有参数
		fun() 
		{ 

			 return 1; 

		} 
		int (*const p)() =fun; //全局且要初始化  
  3)Holtek C并不能取得const常量的地址
		const int ldc = 0; 
		void main() 
		{ 
			 int *a; 
			 a = &ldc; //不能通过 
		}
  3)对无符号数的位移运算,无论左移右移都都会将移入的那位清零;而对于有符号数,
	 右移将保留符号位(即最高位),左移将清零最低位。
  4)内建函数:
    内建延时函数: void _delay(unsigned long tick) 延时 tick 个指令周期 (instruction cycle)
	void _clrwdt( ); //CLR WDT 
	void _clrwdt1( ); //CLR WDT1 
	void _clrwdt2( ); //CLR WDT2 
	void _halt( ); //HALT 
	void _nop( ); //NOP 	 
  5)循环移位点亮LED灯
	for( cnt = 0 ; cnt < 8 ; cnt++ ) //  循环,共执行 8 次点亮 LED的动作 
	{ 
	  status = (1 << cnt) ; //  第一次是PA0,第二次是PA1,… 的LED被点亮 
	 _pa = status ; // 输出到端口A,点亮一个LED及熄灭其它 LED 
	}   
4,无法调整中断优先级
5,在中断函数被服务的时候,各种中断标志位会自动清零,同时关闭总中断,并禁止响应其他中断
6,引脚默认为输入,IO口电平默认为低
7,引脚上拉、看门狗开闭等等的配置不是在程序中,而在 菜单->工具->配置选项 中。	
8,IO口数据输出不能不能直接取反(如:_pa3 = ~_pa3;)!!!!!!!!!!不然波形不对,
9,看门狗时钟分频配置为_wdts = 0x00;(0x01、0x02)这三个参数时,会导致系统时钟工作异常,即不工作
		
		
微控制器程序的内存宽度 ???
  
*/
//***********************************************************************//

//***********************************************************************//
/*****************************************************
*文件名:按键处理程序
*创建者:Paulliam
*创建时间:2017-06-26
*文件说明:
******************************************************/
if(K1==0)		//检测按键K1是否按下
{
	Delay10ms();	//消除抖动
	if(K1==0)
	{
		SetPlace++;
		if(SetPlace>=7)
			SetPlace=0;					
	}

	while((i<50)&&(K1==0))	 //检测按键是否松开  ---显然是支持连按
	//while(!k1);							---显然是不支持连按
	{
		Delay10ms();
		i++;
	}
	i=0;
}
//***********************************************************************//
/*****************************************************
*文件名:延时函数
*创建者:Paulliam
*创建时间:2017-06-29
*文件说明:
******************************************************/

void delay(unsigned int count) 
{ 
	while ( count != 0 ) 
		count-- ; 
}

void delay (unsigned int cycle) 
{ 
	unsigned int count ; 
	for( count = cycle ; count > 0 ; count-- )
		; 

} 

//***********************************************************************//
/*****************************************************
*文件名:goto 跳转函数
*创建者:Paulliam
*创建时间:2017-06-14
*文件说明:
******************************************************/
void main()
{
	uint8_t i;
	for(i=0;i<512;i++)
	{
		if(IapReadByte(IAP_ADDRESS+i) != 0xff)
			goto Error;
	}
	while(1);
	
  Error:
    return;
	
}


//***********************************************************************//
/*****************************************************
*文件名:位定义
*创建者:Paulliam
*创建时间:2017-
*文件说明:
******************************************************/
typedef union{
	u8 val;
	struct{
		u8 Bit0:1;
		u8 Bit1:1;
		u8 Bit2:1;
		u8 Bit3:1;
		u8 Bit4:1;
		u8 Bit5:1;
		u8 Bit6:1;
		u8 Bit7:1;
		};
}uint8Val;

uint8Val Flag1;  //定义标志
#define Switch_Flag       Flag1.Bit0
#define Trickle_charge_Flag       Flag1.Bit1
#define DOG_Flag       Flag1.Bit2

typedef union{
    unsigned short val;
    struct{
        unsigned char LB;
        unsigned char HB;
    };
    struct{
        unsigned char b0:1;
        unsigned char b1:1;
        unsigned char b2:1;
        unsigned char b3:1;
        unsigned char b4:1;
        unsigned char b5:1;
        unsigned char b6:1;
        unsigned char b7:1;
        unsigned char b8:1;
        unsigned char b9:1;
        unsigned char b10:1;
        unsigned char b11:1;
        unsigned char b12:1;
        unsigned char b13:1;
        unsigned char b14:1;
        unsigned char b15:1;
    };
}uint16Val;
-----------------------------------------------------------------------
typedef struct {
	unsigned char : 5;			//缺省,未定义靠前的是字节低位
	unsigned char __rtcen : 1;
	unsigned char : 1;
	unsigned char __rtcto : 1;
} __rtcc_bits;

typedef struct {
	unsigned char __pd0 : 1;//最低位
	unsigned char __pd1 : 1;
	unsigned char __pd2 : 1;
	unsigned char __pd3 : 1;
	unsigned char __pd4 : 1;
	unsigned char __pd5 : 1;
	unsigned char __pd6 : 1;
	unsigned char __pd7 : 1;//最高位
} __pd_bits;
typedef union {
	__pd_bits bits;		//既可以是位的类型
	__sfr_byte byte;	//又可以是字节类型 //typedef unsigned char __sfr_byte;
} __pd_type;
//***********************************************************************//
/*****************************************************
*文件名:宏中"#"和"##"的用法
*创建者:Paulliam
*创建时间:2017-05-20
*文件说明:
******************************************************/
1、一般用法 
我们使用#把宏参数变为一个字符串,用##把两个宏参数贴合在一起. 
用法: 
#include<cstdio> 
#include<climits> 
using namespace std; 
#define STR(s)     #s 
#define CONS(a,b)  int(a##e##b) 

int main() 
{ 
    printf(STR(vck));           // 输出字符串"vck" 
    printf("%d ", CONS(2,3));  // 2e3 输出:2000 
    return 0; 
} 

2、填充结构 
#define  FILL(a)   {a, #a} 
enum IDD{OPEN, CLOSE}; 
typedef struct MSG{ 
  IDD id; 
  const char * msg; 
}MSG; 

MSG _msg[] = {FILL(OPEN), FILL(CLOSE)}; 
相当于: 
MSG _msg[] = {{OPEN, "OPEN"}, 
              {CLOSE, "CLOSE"}};
			  
3、记录文件名 
#define  _GET_FILE_NAME(f)   #f 
#define  GET_FILE_NAME(f)    _GET_FILE_NAME(f) 
static char  FILE_NAME[] = GET_FILE_NAME(__FILE__); 			  

4,
#define Conn(x,y) x##y	//表示x连接y
#define ToChar(x) #@x	//加上单引号
#define ToString(x) #x	//加上双引号

int n = Conn(123,456); /* 结果就是n=123456;*/
char* str = Conn("asdf", "adf"); /*结果就是 str = "asdfadf";*/
char a = ToChar(1);结果就是a='1';
char* str = ToString(123132);就成了str="123132";
//***********************************************************************//
/*****************************************************
*文件名:
*创建者:Paulliam
*创建时间:2017-05-20
*文件说明:
******************************************************/
1,防止一个头文件被重复包含 
#ifndef COMDEF_H 
#define COMDEF_H 
  //头文件内容 
#endif 

2,重新定义一些类型,防止由于各种平台和编译器的不同,而产生的类型字节数差异,方便移植。 
typedef  unsigned char      boolean;     /* Boolean value type. */
typedef  unsigned long int  uint32;      /* Unsigned 32 bit value */
typedef  unsigned short     uint16;      /* Unsigned 16 bit value */
typedef  unsigned char      uint8;       /* Unsigned 8  bit value */
typedef  signed long int    int32;       /* Signed 32 bit value */
typedef  signed short       int16;       /* Signed 16 bit value */
typedef  signed char        int8;        /* Signed 8  bit value */

3,求最大值和最小值 
 #define  MAX( x, y ) ( ((x) > (y)) ? (x) : (y) )
 #define  MIN( x, y ) ( ((x) < (y)) ? (x) : (y) )

4,得到指定地址上的一个字节或字 
#define  MEM_B( x )  ( *( (byte *) (x) ) )
#define  MEM_W( x )  ( *( (word *) (x) ) )

5,得到一个结构体中field所占用的字节数 
#define FSIZ( type, field )  sizeof( ((type *) 0)->field )

6,得到一个field在结构体(struct)中的偏移量 
#define FPOS( type, field )   /*lint -e545 */ ( (dword) &(( type *) 0)-> field ) /*lint +e545 */

7,按照LSB格式把两个字节转化为一个Word 
#define  FLIPW( ray ) ( (((word) (ray)[0]) * 256) + (ray)[1] )

8,按照LSB格式把一个Word转化为两个字节 
#define  FLOPW( ray, val )   (ray)[0] = ((val) / 256); (ray)[1] = ((val) & 0xFF) 

9,得到一个变量的地址(word宽度) 
#define  B_PTR( var )  ( (byte *) (void *) &(var) )
#define  W_PTR( var )  ( (word *) (void *) &(var) )

10,得到一个字的高位和低位字节 
#define  WORD_LO(xxx)  ((byte) ((word)(xxx) & 255))
#define  WORD_HI(xxx)  ((byte) ((word)(xxx) >> 8))

11,返回一个比X大的最接近的8的倍数 
#define RND8( x )       ((((x) + 7) / 8 ) * 8 )

12,将一个字母转换为大写 
#define  UPCASE( c ) ( ((c) >= 'a' && (c) <= 'z') ? ((c) - 0x20) : (c) )

13,判断字符是不是16进值的数字 
#define  HEXCHK( c ) ( ((c) >= '0' && (c) <= '9') ||\
                       ((c) >= 'A' && (c) <= 'F') ||\
((c) >= 'a' && (c) <= 'f') ) 

14,判断字符是不是10进值的数字 
#define  DECCHK( c ) ((c) >= '0' && (c) <= '9')

15,防止溢出的一个方法 
#define  INC_SAT( val )  (val = ((val)+1 > (val)) ? (val)+1 : (val))

16,返回数组元素的个数 
#define  ARR_SIZE( a )  ( sizeof( (a) ) / sizeof( (a[0]) ) )

17,返回一个无符号数n尾的值MOD_BY_POWER_OF_TWO(X,n)=X%(2^n) 
#define MOD_BY_POWER_OF_TWO( val, mod_by ) \ 
           ( (dword)(val) & (dword)((mod_by)-1) )

18,对于IO空间映射在存储空间的结构,输入输出处理 
  #define inp(port)         (*((volatile byte *) (port)))
  #define inpw(port)        (*((volatile word *) (port)))
  #define inpdw(port)       (*((volatile dword *)(port)))
  #define outp(port, val)   (*((volatile byte *) (port)) = ((byte) (val)))
  #define outpw(port, val)  (*((volatile word *) (port)) = ((word) (val)))
  #define outpdw(port, val) (*((volatile dword *) (port)) = ((dword) (val)))

19,使用一些宏跟踪调试 
A N S I标准说明了五个预定义的宏名。它们是: 
_ L I N E _ 
_ F I L E _ 
_ D A T E _ 
_ T I M E _ 
_ S T D C _ 

如果编译不是标准的,则可能仅支持以上宏名中的几个,或根本不支持。记住编译程序 
也许还提供其它预定义的宏名。 
_ L I N E _及_ F I L E _宏指令在有关# l i n e的部分中已讨论,这里讨论其余的宏名。 
_ D AT E _宏指令含有形式为月/日/年的串,表示源文件被翻译到代码时的日期。 
源代码翻译到目标代码的时间作为串包含在_ T I M E _中。串形式为时:分:秒。 
如果实现是标准的,则宏_ S T D C _含有十进制常量1。如果它含有任何其它数,则实现是 
非标准的。 
可以定义宏,例如: 
当定义了_DEBUG,输出数据信息和所在文件所在行 
#ifdef _DEBUG 
#define DEBUGMSG(msg,date) printf(msg);printf("%d%d%d",date,_LINE_,_FILE_)
#else 
      #define DEBUGMSG(msg,date)  
#endif 
 
20,宏定义防止使用是错误 
用小括号包含。 
例如:#define ADD(a,b) (a+b) 
用do{}while(0)语句包含多语句防止错误 
例如:#difne DO(a,b) a+b;\ 
                   a++;
应用时:if(….) 
          DO(a,b); //产生错误 
        else 
解决方法: #difne DO(a,b) do{a+b;\ 
                   a++;}while(0)
//***********************************************************************//
/*****************************************************
*文件名:STM32断言、参数输入合法校验、宏定义
*创建者:Paulliam
*创建时间:2017-4-25
*文件说明:
******************************************************/
//-------------定义-----
void assert_failed(u8* file, u32 line) 
{ // User can add his own implementation to report the file name and linenumber, 
// printf("Wrong parameters value: file %s on line %d\r\n", file,line);
//#pragma message("_x86 macro activated!") //如果宏定义了_x86 ,就显示本条编译信息														
// Infinite loop 
while(1) { } 
}
#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
#define IS_TIM_Mode(TIM_Mode) (((TIM_Mode) == TIM_16BitAutoReload) || \
                                   ((TIM_Mode) == TIM_16Bit) || \
                                   ((TIM_Mode) == TIM_8BitAutoReload))
//-------------调用-----								   
assert_param(IS_TIM_Mode(TIMx->TIM_Mode));
//***********************************************************************//
/*****************************************************
*文件名:8位、16位、32位数据别名定义
*创建者:Paulliam
*创建时间:2017-4-22
*文件说明:
******************************************************/
typedef unsigned char uint8_t;
typedef signed char int8_t;
typedef unsigned int uint16_t;
typedef signed int int16_t;
typedef unsigned long uint32_t;
typedef signed long int32_t;

//***********************************************************************//
/*****************************************************
*文件名:
*创建者:Paulliam
*创建时间:2016-
*文件说明:
******************************************************/
   for(Gi=0;Gi<num;Gi++)        //计算校验和
   {CheckSum=((uint8_t)(CheckSum+arry[Gi])); } //强制类型转换,只取相加和的最低字节
//***********************************************************************//
/*****************************************************
*文件名:宏定义一个变量
*创建者:Paulliam
*创建时间:2017-03-08
*文件说明:
******************************************************/
/*-------------------------------------------------
uart.h文件中:
--------------------------------------------------*/
#define Uart1_Length    (uart_rx[1]+4)        //总数据长度,宏定义居然可以这样用:将一个可变的数组元素定义成一个宏
/*-------------------------------------------------
uart.c文件中:
--------------------------------------------------*/
#include "uart.h"	
// * 描  述 : UART1中断服务函数
uint8_t idata uart_rx[10]={2,3,5};       //UART缓存
uint8_t xdata uart_rx_cnt =0;             //UART接收计数
void Uart1() interrupt 4 using 1
{    
    if (uart_rx_cnt>=Uart1_Length)            //校验数据长度,这里,Uart1_Length替换成3+4
	   ...
}

//***********************************************************************//
/*****************************************************
*文件名:定时器中设置周期循环状态
*创建者:Paulliam
*创建时间:2016-
*文件说明:
******************************************************/
void Timer0_10ms(void) interrupt 1 //10ms中断@11.0592MHz
{
	if(0 == time_count%100){ //循环周期为100个time_count,即1000ms
		//循环周期中的状态1,时间占空比为80%
	}
	if(80 == time_count%100){
		//循环周期中的状态2,时间占空比为20%
	}
		
	time_count++;			
}
//***********************************************************************//
/*****************************************************
*文件名:
*创建者:Paulliam
*创建时间:2016-
*文件说明:
******************************************************/
//当程序使用定时器中断方式后,中断请求标志TF0最好不要用在程序中,
//当程序跳入中断处理函数后,中断请求标志会被自动清零
uint32_t time_count=0; //软件定时
uint32_t time_play=0;
bit led;
void main()           
{     
    init();     	    
    led = 0;      //熄灭绿灯

    while(1)
    {
        
        //if(1 == TF0 && 0==time_count%50) //此处最好不用TF0,而改用自定义标志time_play!=time_count
        if(time_play!=time_count && 0==time_count%50)
        {
            //TF0 = 0;
            led = ~led;
            P14 = led;       //切换灯的亮灭     
            //display(time_count);             
            time_play =  time_count;
        }
        display(time_count);             
	}
}

void Timer0_10ms(void) interrupt 1 //10ms中断@11.0592MHz
{
    time_count++;

}
//***********************************************************************//
/*****************************************************
*文件名:代码换行,宏定义换行,字符串换行
*创建者:Paulliam
*创建时间:2016-12-26
*文件说明:
******************************************************/
const char Help_Text[]="You Should Send Information In The Following Format:\r\n\
1.Set The List Administrator:\r\n\
SZ\n\
#number1\n\
#number2\n\
2.Add The List Administrator:\nSZ+#number;\n\
3.Query List Administrators:\nCX";
//***********************************************************************//
/*****************************************************
*文件名:宏定义一个函数
*创建者:Paulliam
*创建时间:2016-12-24
*文件说明:
******************************************************/
//**头文件中:
#define Call_Id_SetLow()   do { LATF2 = 0; } while(0)
//**源文件中调用:
Call_Id_SetLow();  //加个分号即可
//***********************************************************************//

/*****************************************************
*文件名:全局变量,外部变量,extern 【方法2】
*创建者:Paulliam
*创建时间:2016-12-26
*文件说明:
******************************************************/
//-----------------------1-------------------------------------//
//**把需要的外部变量定义在点C源文件中,却在其对应头文件中声明为外部变量,如以下Eusart1.h
extern volatile uint8_t eusart1RxCount; //声明
//---------------------2调用示例---------------------------------------//
//**在Eusart1.c中定义并调用,也可以在其他源文件中包含此头文件,进而实现调用
#include "eusart1.h"
volatile uint8_t eusart1RxCount;        //定义  
//***********************************************************************//
/*****************************************************
*文件名:全局变量,外部变量,extern 【方法1】
*创建者:Paulliam
*创建时间:2016-
*文件说明:
******************************************************/
//-----------------------1-------------------------------------//
//**把需要的外部变量定义在头文件中,并声明为外部变量,如以下ds1307.h
#ifndef _DS1307_H_
#define _DS1307_H_

struct Clock
{
	unsigned char Hours;                 
	unsigned char Minutes;               
}Clock_Time;                    //定义

extern struct Clock Clock_Time; //声明    *********此处重点******

#endif
//---------------------2调用示例---------------------------------------//
//**若某源文件需要使用ds1307.h中外部变量Clock_Time,则包含头文件ds1307.h即可
//如源文件DS1370.c文件中
#include"ds1307.h"
void DS1307_Init()
{
		Clock_Time.Hours=0x08;//初始小时
		Clock_Time.Minutes=0x08;//初始分

}
//***********************************************************************//
/*****************************************************
*文件名:计算一个8位变量中含1的个数
*创建者:Paulliam
*创建时间:2016-12-07
*文件说明:编写一个函数fun(),其中不能定义变量,返回传进参数中1的个数
******************************************************/
#include <stdio.h>
unsigned char fun(unsigned char x);
void main(int argc,char *argv[])
{
	unsigned char num;
	num = (unsigned char)atoi(argv[1]);
	
	printf("the number is: %d",fun(num));		
}

unsigned char fun(unsigned char x)
{
	if(x == 0) return 0;
	if(x & 0x01)
		return 1+fun(x >> 1);
	else
		return 0+fun(x >> 1);
}
//***********************************************************************//
/*****************************************************
*文件名:宏定义调用,宏定义函数调用
*创建者:Paulliam
*创建时间:2016-11-7
*文件说明:
******************************************************/
//宏定义:
#define SSC_RFMR_MSBF_OFFSET			 7
/* Bit manipulation macros */
#define SSC_BIT(name)					\
	(1 << SSC_##name##_OFFSET)
	
调用例子:
value = SSC_BIT(RFMR_MSBF);
调用结果便如同:
value = (1 << SSC_RFMR_MSBF_OFFSET); //即用RFMR_MSBF替换##name##	
//***********************************************************************//
/*****************************************************
*文件名:宏定义打印
*创建者:Paulliam
*创建时间:2016-
*文件说明:
******************************************************/
//-----宏定义打印信息------
#define TRACE_ERROR(...)      { printf("-E- " __VA_ARGS__); } //__VA_ARGS__ 是printf的相干参数
//----调用打印宏------
TRACE_ERROR("USART_Read: Timed out.\n\r");
//--如果不使用某打印宏定义则可以定义为 Empty macro
#define TRACE_ERROR(...)      { }
//***********************************************************************//

/*****************************************************
*文件名:枚举、结构体、别名
*创建者:Paulliam
*创建时间:2016-
*文件说明:
******************************************************/
//-----定义结构体的同时,定义他的别名-------
typedef struct {

   /// Size of the descriptor in bytes.
   unsigned char bLength;
   /// Descriptor type (USBDESC_DEVICE_QUALIFIER or "USB device types").
   unsigned char bDescriptorType;
   /// USB specification release number (in BCD format).
   unsigned short bcdUSB;        

} USBDeviceQualifierDescriptor; // GCC

//-----对定义的结构体变量赋初值
const USBDeviceQualifierDescriptor qualifierDescriptor = {

    sizeof(USBDeviceDescriptor),
    1, 
    0 /* 最后一个不需要加逗号 */
};
//***********************************************************************//

/*****************************************************
*文件名:枚举类型enum定义方法
*创建者:Paulliam
*创建时间:2016-
*文件说明:枚举类型的值默认为 unsigned char ???????
******************************************************/
typedef enum Mixer_Devices { //枚举类型名居然可以跟其别名一模一样
	Mixer_Device_VOLUME = 0,	/* 第一个要赋初值 */
	Mixer_Device_LINE,			
	Mixer_Device_OMUTE,		
	Mixer_Device_NRDEVICES		/* 最后一个不需要加逗号 */
}Mixer_Devices;  //枚举类型名居然可以跟其别名一模一样

//定义
typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus;

typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;
#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE))

typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus;
//调用示例:
ErrorStatus FireCheck(void)
{
    if( Fireline.state=='L' )
    { return SUCCESS; }
    else
    { return ERROR; }
}
//***********************************************************************//

/*****************************************************
*文件名:宏定义在编译中的使用,判断某宏定义是否已经定义
*创建者:Paulliam
*创建时间:2016-09-22
*文件说明:
******************************************************/
#define NOTRACE
#if defined(NOTRACE) //如果已经宏定义了NOTRACE,则在编译时,显示一条错误信息如下:
#error "Error: NOTRACE has to be not defined !" //错误信息
#endif

#ifdef _x86
#pragma message("_x86 macro activated!") //如果宏定义了_x86 ,就显示本条编译信息
#endif
//***********************************************************************//

/*****************************************************
*文件名:宏定义、define
*创建者:Paulliam
*创建时间:2016-
*文件说明:
******************************************************/
#if defined(BOARD_USB_UDP) //等效如下:
#if defined BOARD_USB_UDP  //也等效为:
#ifdef BOARD_USB_UDP

#if !defined HSE_VALUE  //等效如下:
#if !defined(HSE_VALUE)  //也等效为:
#ifndef HSE_VALUE

#define HT95R33_EN  1
//#define HT95R33_EN  0
#if HT95R33_EN
  ...             //如果为真,则编译
#endif 
#if !HT95R33_EN
  ...             //如果不为真,则编译
#endif

#if 1  //或者 #ifdef XXX
  ...
#elif 1
  ...
#else
  ...
#endif


#if !defined (USE_STM3210B_EVAL) &&  !defined (USE_STM3210E_EVAL) &&  !defined (USE_STM3210C_EVAL) &&  !defined (USE_STM32100B_EVAL) &&  !defined (USE_STM32100E_EVAL)
 //#define USE_STM32100B_EVAL  
 //#define USE_STM3210B_EVAL
 //#define USE_STM3210E_EVAL
 //#define USE_STM3210C_EVAL
 #define USE_STM32100E_EVAL 
#endif

#ifdef USE_STM3210B_EVAL
//...
#elif defined (USE_STM3210E_EVAL) || defined (USE_STM32100E_EVAL)
//...
#endif
//***********************************************************************//
/*****************************************************
*文件名:字符串转十六进制数、字符转十六进制、小写字母转大写字母
*创建者:Paulliam
*创建时间:2016-8-12
*文件说明:要求 strlen(buf) 为偶数
******************************************************/
调用形式:
unsigned char num_color[2];
unsigned char buf[10]={'\0'}; //只能将buf[0]赋值‘\0’
StrToHex(num_color, buf, strlen(buf)/2);
//要求pbSrc中的字符必须是0到9,a到f,或者A~F
void StrToHex(BYTE *pbDest, BYTE *pbSrc,  int nLen)
{
	char h1,h2;
	BYTE s1,s2;
	int i;

	for (i=0; i<nLen; i++)
	{
		h1 = pbSrc[2*i];
		h2 = pbSrc[2*i+1];

		s1 = toupper(h1) - 0x30;//toupper小写字母转大写字母,其他字符原样返回
		if (s1 > 9) 
		s1 -= 7;

		s2 = toupper(h2) - 0x30;
		if (s2 > 9) 
		s2 -= 7;

		pbDest[i] = s1*16 + s2;
	}	
}
//***********************************************************************//
/*****************************************************
*文件名:
*创建者:Paulliam
*创建时间:2016-8-12
*文件说明:
******************************************************/
write或者ioctl中都得使用copy_from_user(),
Ioctl方式,使用细节:
应用层:
typedef struct led_bag{…
…}LED;
LED led;
#define MEM_W _IOW(MEM_MAGIC,1,LED  *)//指定arg的类型是 LED  *
ioctl(fd, MEM_W, &led ); //传递的命令以参数形式传给驱动

驱动层:
int mem_ioctl(struct inode *node, struct file *filp, unsigned int cmd, unsigned long arg)
{…
copy_from_user(reg_base, (LED __user * )arg, 6); //应用程序传递下来的arg必须强制转换成copy_from_user要求的类型
…
}

unsigned long copy_from_user(void *to, const void __user *from, unsigned long n); //void 意味着任何类型都可以,不过要做转换
//***********************************************************************//
/*****************************************************
*文件名:open flag、标志
*创建者:Paulliam
*创建时间:2016-8-12
*文件说明:
******************************************************/
	open("/home/test/txt",O_RDWR|O_CREAT|O_TRUNC,0755);//如果文件不存在,则创建他,并在写入之前,先清空,0755是用户的权限
//***********************************************************************//
/*****************************************************
*文件名:字符数组初始化、字符数组赋初值、字符数组清零、清空字符数组
*创建者:Paulliam
*创建时间:2016-8-12
*文件说明:
******************************************************/
方法一:
typedef struct pid {
	long pid_mem;
	char pid_name[30];	
	char pid_num[10];
}PID_STU;
PID_STU three[3]={  //位于mem.h
	{0,"pid_name0","pid_num0"},
	{0,"\0","\0"},
	{0,"pid_name2","pid_num2"},
	//{0,"\0","\0"},
};
方法二:
char buf_pid[30] = "\0"; 
char buf[20] = {'\0'}; //只能将buf[0]赋值‘\0’
char buf[20] = {'\0','\0'}; //只是对最前两个赋值‘\0’
memset(buf_pid, 0, sizeof(buf_pid)); //先清空字符数组的缓
//***********************************************************************//
/*****************************************************
*文件名:多文件包含
*创建者:Paulliam
*创建时间:2016-8-12
*文件说明:
******************************************************/
#ifndef _mem_h
#define _mem_h

typedef struct pid {
	long pid_mem;
	char pid_name[30];	
	char pid_num[10];
}PID_STU;

void pid_memory(const char *path, PID_STU *three0, PID_STU *three1, \
	PID_STU *three2);

#endif
//***********************************************************************//
//***********************************************************************//
subnet 192.168.126.0 netmask 255.255.255.0{
	option routers  192.168.126.1;   
	option broadcast-address 192.168.126.255;
	option subnet-mask  255.255.255.0;
	filename "pxelinux.0";	
	next-server 192.168.126.149;
}

//***********************************************************************//


option space PXE;
option PXE.mtftp-ip               code 1 = ip-address;
option PXE.mtftp-cport            code 2 = unsigned integer 16;
option PXE.mtftp-sport            code 3 = unsigned integer 16;
option PXE.mtftp-tmout            code 4 = unsigned integer 8;
option PXE.mtftp-delay            code 5 = unsigned integer 8;
option PXE.discovery-control      code 6 = unsigned integer 8;
option PXE.discovery-mcast-addr   code 7 = ip-address;
class "pxeclients" {
match if substring (option vendor-class-identifier, 0, 9) = "PXEClient";
option vendor-class-identifier "PXEClient";
vendor-option-space PXE;
option PXE.mtftp-ip 0.0.0.0;
filename "pxelinux.0";
next-server 192.168.126.149;
}
ddns-update-style interim;
ignore client-updates;
allow booting;
allow bootp;
#ddns-updates on;
subnet 192.168.126.0 netmask 255.255.255.0 {
option routers                  192.168.126.1;
option broadcast-address 192.168.126.255;
option subnet-mask              255.255.255.0;
#option domain-name-servers      202.106.0.20;
option time-offset              28800;
pool {
range                   192.168.126.3 192.168.126.253;
default-lease-time      200;
max-lease-time          400;
allow                   members of "pxeclients";
}
}

//***********************************************************************//
//导师版本
option space PXE;
option PXE.mtftp-ip     code 1 = ip-address;
option PXE.mtftp-cport     code 2 = unsigned integer 16;
option PXE.mtftp-sport     code 3 = unsigned integer 16;
option PXE.mtftp-tmout     code 4 = unsigned integer 8;
option PXE.mtftp-delay     code 5 = unsigned integer 8;
option PXE.discovery-control     code 6 = unsigned integer 8;
option PXE.discovery-mcast-addr     code 7 = ip-address;

ddns-update-style interim;
ignore client-updates;
allow booting;
allow bootp;
class "pxeclients"{
	match if substring (option vendor-class-identifier,0,9)="PXEClient";
	vendor-option-space PXE;
	option PXE.mtftp-ip 0.0.0.0;
	filename "pxelinux.0";	
}

subnet 192.168.126.0 netmask 255.255.255.0{
DHCPDARGS=eth0;
	option routers  192.168.126.1;   
	option broadcast-address 192.168.126.255;#right
	option subnet-mask  255.255.255.0;
	
	option nis-domain  "domain.org";
	option domain-name  "domain.org";
	
	option time-offset  -18000;
	range dynamic-bootp  192.168.126.10 192.168.126.254;# 252?????????
	
	default-lease-time 3000;
	max-lease-time 6000;	
}
EOF

//***********************************************************************//
/*****************************************************
*文件名:添加注释
*创建者:Paulliam
*创建时间:2016-7-27
*文件说明:
******************************************************/
//在实际工作中,往往遇到这种情况:代码经过多次修改,已经添加过/*…*/组合。这样如果再次添加就不能完全将代码注释掉,如下:
   /*/*a = 1;
    b = 100;*/
    c = 200;*/
    //实际上,黄色部分并没有被注释掉,也就是说第二次添加的注释信息没有起到应有的作用。
	
	//解决办法 :
	#if 0
	/*a = 1;
    b = 100;*/
    c = 200;
	#endif

//***********************************************************************//
/*****************************************************
*文件名:读取某个pid的占用内存
*创建者:Paulliam
*创建时间:2016-7-26
*文件说明:/home/test/
******************************************************/
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/fcntl.h>
#include<unistd.h>
#include<stdlib.h>
#include<dirent.h>
#include<string.h>

typedef struct pid {
	char pid_name[30];
	long pid_mem;
}PID_STU;

void main()
{
	
	int fd;   
    char buf[4+1]; 	
	
	PID_STU buf_stu;  //用于缓存读到的进程的占用内存和名字
	char buf_pid[30]; //缓存进程的名字或者VmRSS
	int i_pid; //用于计数	
	
	printf("\n\n");
	
	fd = open("/proc/2236/status",O_RDONLY);   
    if(fd < 0)
        printf("open file fail!\n");    
	
	while(1 == read(fd,buf,1)) 
	{	
		if(':' == buf[0])
		{
			lseek(fd,-5,SEEK_CUR);
			read(fd,buf,4);
			lseek(fd,1,SEEK_CUR);  //重定位要紧跟read后
			buf[4]='\0';	
			
			if(0 == strcmp("mRSS",buf))
			{
				i_pid = 0;				
				read(fd,buf,1);									
				while('\n' != buf[0]) //判断mRSS行的开始和结束
				{							
					if(buf[0] >= '0' && buf[0] <= '9')  //
					{
						buf_pid[i_pid] = buf[0];
						i_pid++;
					}														
					read(fd,buf,1);
				}
				buf_pid[i_pid] = '\0';
				
				buf_stu.pid_mem = atol(buf_pid);
				printf("%d\n",buf_stu.pid_mem);
			}						
			
		}
	}
	
		
	close(fd);	
		
}


/*****************************************************
*3文件名:读取某个pid的名字
*创建者:Paulliam
*创建时间:2016-7-26
*文件说明:/home/test/
******************************************************/
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/fcntl.h>
#include<unistd.h>
#include<stdlib.h>
#include<dirent.h>
#include<string.h>

typedef struct pid {
	char pid_name[30];
	long pid_mem;
}PID_STU;

void main()
{
	
	int fd;   
    char buf[4+1]; 	
	
	PID_STU buf_stu;  //用于缓存读到的进程的占用内存和名字
	char buf_pid[30]; //缓存进程的名字或者VmRSS
	int i_pid; //用于计数	
	
	printf("\n\n");
	
	fd = open("/proc/2423/status",O_RDONLY);   
    if(fd < 0)
        printf("open file fail!\n");    
	
	while(1 == read(fd,buf,1)) 
	{	
		if(':' == buf[0])
		{
			lseek(fd,-5,SEEK_CUR);
			read(fd,buf,4);
			lseek(fd,1,SEEK_CUR);  //重定位要紧跟read后
			buf[4]='\0';	
			
			if(0 == strcmp("Name",buf))
			{
				i_pid = 0;				
				read(fd,buf,1);									
				while('\n' != buf[0]) //判断name的开始和结束
				{							
					if('	' != buf[0])  //显示出的空白不一定是空格,有可能是tab
					{
						printf("step 3\n");
						printf("%d\n",buf[0]);
						buf_pid[i_pid] = buf[0];
						i_pid++;
					}														
					read(fd,buf,1);
				}
				buf_pid[i_pid] = '\0';
				
				strcpy(buf_stu.pid_name,buf_pid);
			}						
			
		}
	}
	
	printf("%s\n",buf_stu.pid_name);
		
	close(fd);	
		
}

/*****************************************************
*2文件名:文件读取并显示
*创建者:Paulliam
*创建时间:2016-7-26
*文件说明:/home/test/
******************************************************/
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/fcntl.h>
#include<unistd.h>

void main()
{
    int fd;
    char buf[3+1];
    char *buf1="012345";
    int n;
    
    printf("\n");
    
    fd = open("/home/test/txt",O_RDWR|O_CREAT|O_TRUNC,0755);//如果文件不存在,则创建他,并在写入之前,先清空,0755是用户的权限
    if(fd < 0)
        printf("open file fail!\n"); 
    
    write(fd,buf1,4);    

/*    
    lseek(fd,0,SEEK_CUR);
    printf("lseek %d\n",lseek(fd,0,SEEK_CUR));
*/    

    lseek(fd,0,SEEK_SET);
    while((n = read(fd,buf,3)) == 3)
    {
    buf[n] = '\0';
    printf("%s",buf);    
    }
    buf[n] = '\0';
    printf("%s",buf);
    
    
    printf("last read num %d\n",n);
    
    close(fd);
}

/*****************************************************
*1文件名:文件读取并显示
*创建者:Paulliam
*创建时间:2016-7-25
*文件说明:
******************************************************/
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/fcntl.h>
#include<unistd.h>

void main()
{
    int fd;
    char buf[3+1];    
    int n;
    
	fd = open("/proc/meminfo",O_RDONLY);   
    if(fd < 0)
        printf("open file fail!\n");      

    lseek(fd,0,SEEK_SET);
    while((n = read(fd,buf,3)) == 3)
    {
    buf[n] = '\0';
    printf("%s",buf);    
    }
    buf[n] = '\0';
    printf("%s",buf);
      
    printf("last read num %d\n",n);
    
    close(fd);
}


//***********************************************************************//
//比较字符串大小,对字符串进行排序,显示自定义strcmp()和系统函数strcmp()的区别
#include<stdio.h>
#include<string.h>
void main()
{
	char p[][32]={"09005","09003","090054","09001","09006"};
	char pr[][32]={"09005","09003","090054","09001","09006"};
	char temp[32];
	int i,j,t,k,len;
	len=sizeof(p)/sizeof(p[0]);
	printf("the out of order strings:\n");
	for(i=0;i<len;i++){
		printf("%s\n",p[i]);//通过二维数组输出字符串
	}

	for(i=0;i<len-1;i++){
		t=i;
		for(j=i+1;j<len;j++){
			for(k=0;p[t][k]!='\0'&&p[j][k]!='\0';k++){
				if(p[t][k]>p[j][k]){
					t=j;break;
				}
				else if(p[t][k]==p[j][k])
					continue;
				else
					break;
			}
		}
		if(t!=i){
			strcpy(temp,p[i]);
			strcpy(p[i],p[t]);
			strcpy(p[t],temp);

		}

	}
	printf("mine way that change strings:\n");
	for(i=0;i<len;i++){
		printf("%s\n",p[i]);//通过二维数组输出字符串
	}


	for(i=0;i<len-1;i++){
		t=i;
		for(j=i+1;j<len;j++){
			if(strcmp(pr[t],pr[j])>0)
				t=j;
		}
		if(t!=i){
			strcpy(temp,pr[i]);
			strcpy(pr[i],pr[t]);
			strcpy(pr[t],temp);

		}

	}
	printf("function strcmp() that change strings:\n");
	for(i=0;i<len;i++){
		printf("%s\n",pr[i]);//通过二维数组输出字符串
	}
	
}
运行结果:
the out of order strings:
09005
09003
090054
09001
09006
mine way that change strings:
09001
09003
090054//不同点
09005 //不同点
09006
function strcmp() that change strings:
09001
09003
09005 //不同点
090054//不同点
09006
Press any key to continue

//***********************************************************************//
//sizeof,指针数组,数组指针,字符型二维数组
#include<stdio.h>
void main()
{
	char str[][32]={"090232","35423","436547","007674","435478254"},(*pr)[32]=str;
	char *p[]={"090232","35423","436547","007674","435478254"};//指针数组
	int i,j,len;
	len=sizeof(str)/sizeof(str[0]);
	printf("二维数组总大小:%d\n",sizeof(str));
	printf("二维数组某行大小:%d\n",sizeof(str[1]));
	printf("数组指针的大小:%d\n",sizeof(pr));
	printf("数组指针指向某行的大小:%d\n",sizeof(pr[1]));//不常规用法,pr等效于str
	printf("指针数组的大小:%d\n",sizeof(p));//指针数组p中有5颗指针
	printf("数组p的首号元素大小:%d\n",sizeof(p[0]));//元素为指针,即求指针的大小
	printf("the number of the strings is:%d\n",len);
	printf("------------------\n");
	for(i=0;i<len;i++){
		printf("%c,",str[i][1]);//定向访问某个元素
		printf("%s\n",str[i]);//通过二维数组输出字符串
	}
	printf("------------------\n");
	for(i=0;i<len;i++){
		printf("%c,",p[i][1]);//为何这也可以???????????
		printf("%s\n",p[i]);  //通过指针数组输出字符串
	}
	printf("------------------\n");
	for(i=0;i<len;i++){
		printf("%c,",pr[i][1]);//为何这也可以???????????
		printf("%c,",*(*(pr+i)+1));
		printf("%s\n",*(pr+i));//通过数组指针输出字符串
	}
}
运行结果:
二维数组总大小:160
二维数组某行大小:32
数组指针的大小:4
数组指针指向某行的大小:32
指针数组的大小:20
数组p的首号元素大小:4
the number of the strings is:5
------------------
9,090232
5,35423
3,436547
0,007674
3,435478254
------------------
9,090232
5,35423
3,436547
0,007674
3,435478254
------------------
9,9,090232
5,5,35423
3,3,436547
0,0,007674
3,3,435478254
Press any key to continue
//***********************************************************************//
//编写一个C函数search_string(const char *strA,const char *strB,char *strC),该
//函数在两个字符串strA和strB中找到可能的最长的子字符串,放入strC中。如“streamax”和“bigmaxsd”,
//则strC中内容为“max”
#include<stdio.h>
void search_str(char *a,char *b,char *c);
void main()
{
	char stra[32];
	char strb[32];
	char strc[32];
	while(1){
	gets(stra);
	gets(strb);
	search_str(stra,strb,strc);
	puts(strc);
	printf("---------------\n");
	}
	
}
void search_str(char *a,char *b,char *c)
{
	int i,j,k,m,f,count=0,temp=0;
	for(i=0;*(a+i)!='\0';i++)
	{
		for(j=0;*(b+j)!='\0';j++)
		{
			if(*(a+i)==*(b+j))
			{
				count=1;
				for(k=i+1,m=j+1;*(a+k)!='\0' && *(b+m)!='\0';k++,m++)
				{
					if(*(a+k)==*(b+m)){
						count++;
						if(temp<count){
							temp=count;
							f=i;
						}
						continue;
					}
					else{
						if(temp<count){
							temp=count;//temp用来记住最长字符串的长度
							f=i;	//f用来记住最长字符串在字符串a中的起始位置
						}
						break;
					}
				}
			}

		}
	}
	for(i=0;i<temp;i++,f++)
		*(c+i)=*(a+f);
	*(c+i)='\0';
}
运行结果:
streamax
bigmaxsd
max
---------------
dfs
fsddfs
dfs
---------------

//***********************************************************************//
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 16
void main()
{
	unsigned char k,n,f;
	char model[N];
	char (*str)[N];//数组指针
	printf("please input the array model[]:\n");
//	scanf("%s",model);
	gets(model);
	for(k=0;k<strlen(model);k++){
			if(model[k]==']')
			{
				f=k;//标记']'的位置
				break;
			}
		}
	printf("how many strings do you want to get:\n");
	scanf("%d",&n);
	printf("set you wanted number successfully!\n");
	str=calloc(n,N);//动态开辟内存n*N字节
	
	printf("input strings:\n");
	for(k=0;k<n;k++)
	{
		printf("%d:",k+1);
		scanf("%s",*(str+k));
	}
	printf("the saved strings:\n");
	for(k=0;k<n;k++)
	{
		printf("%c,",*(*(str+k)+0));	//*(*(str+k)+0)此精确的表示了第k个字符串中的第0个字符元素
		printf("%s",*(str+k));	//而要输出字符串,则应该是给一个地址,即字符串的首地址
		printf("\n");
	}

	printf("the results:\n");
	for(k=0;k<n;k++)
	{
		unsigned char i,j;
		for(j=0,i=0;*(*(str+k)+i)!='\0'&&model[j]!='\0';i++,j++)
		{
			if(*(*(str+k)+i)==model[j]||*(*(str+k)+i)-model[j]=='a'-'A'||*(*(str+k)+i)-model[j]=='A'-'a')
			{//上面if中三个条件,满足其一即可,即字符匹配不分大小写
				if(model[j+1]=='\0'&&*(*(str+k)+i+1)=='\0')//要求字符串同时结束
				{	printf("%d %s\n",k+1,*(str+k));break;	}
				continue;
			}
			else if(model[j]=='[')
			{
				int flag=1;
				while(model[j]!=']')
				{
					j++;
					flag=1;
					if(*(*(str+k)+i)==model[j]||*(*(str+k)+i)-model[j]=='a'-'A'||*(*(str+k)+i)-model[j]=='A'-'a')
					{
						j=f;   
						break;//方括号中只要满足有一个字符匹配,则直接匹配方括号后面的字符
					}
					else
						flag=0;
				}
				if(flag==0)//方括号里面没有匹配的,则结束内层for循环,即结束匹配第k个字符串,即*(str+k)
					break;
			}
			else
				break;
		}
	}
		
	free(str);
}
运行结果:
please input the array model[]:
a[dfgs]bb
how many strings do you want to get:
3
set you wanted number successfully!
input strings:
1:Adfbb
2:Adbb
3:asb
the saved strings:
A,Adfbb
A,Adbb
a,asb
the results:
2 Adbb
Press any key to continue

//***********************************************************************//
//关于goto语句
#include<stdio.h>
#include<math.h>
void main()
{
	int i=0;
lp:	for(i=0;i<30;i++)	//goto到此for循环时,i++并不执行,而是当做程序第一次进入for循环时处理
	{
		printf("%2d,",i);
		i++;	//for循环的i++应该提到此处
		goto lp;
	}
	printf("\n");
}
运行结果:
  0, 0,  0, 0,  0, 0,  0, 0,  0, 0,  0, 0,  0, 0,  0, 0,  0, 0,.....无限个0
//***********************************************************************//
#include<stdio.h>
#include<math.h>
void main()
{
	int i=0;
lp:	for( ;i<30;i++)	//goto到此for循环时,i++并不执行,而是当做程序第一次进入for循环时处理
	{
		printf("%2d,",i);
		i++;	//for循环的i++应该提到此处
		goto lp;
	}
	printf("\n");
}
运行结果:
 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26
,27,28,29,
Press any key to continue
//***********************************************************************//
//输出目标数据(0-9999),要求它既是平方数,又有两位数字相同
#include<stdio.h>
#include<math.h>
void main()
{
	char a[5];
	int i,j,k,count,flag=0;
	sprintf(a,"%c",121);//121作为字符型数据存入字符数组a[]
	for(i=0;i<3;i++){
		printf("%c,",a[i]);
		printf("%d\n",a[i]);
	}
	printf("********\n");
	sprintf(a,"%d",121);//将121各个数字的ASCII码分别填入数组a[0],a[1],a[2]
	for(i=0;i<3;i++){
		printf("%c,",a[i]);
		printf("%d\n",a[i]);
	}
	printf("********\n");
	for(i=11;i<9999;i++){
		if(sqrt(i)==(int)sqrt(i))
		{
			j=i;
			count=0;
			while(1){
				if(j/10!=0)
				{count++;j/=10;}
				else
				{count++;break;}
			}
			sprintf(a,"%d",i);
			flag=0;
			for(j=0;j<count-1;j++)
			{
				if(flag==1)
					break;
				for(k=j+1;k<count;k++)
				{
					if(a[j]==a[k])
					{
						printf("%4d,",i);//输出目标数据,要求它既是平方数,又有两位数字相同
						flag=1;//由于找到目标数据后,要结束两层for循环,则必须设置一个标志flag
						break;//也可以用goto替换,不过for(i=11;i<9999;i++)应该改成
								//i=11;for( ;i<9999; ) 另外,printf("%4d,",i);后面再加上语句i++;
								//就可以正确完成for循环
					}
				}
			}

		}

	}
	printf("\n");

}

运行结果:
y,121
 ,0
?,-52
********
1,49
2,50
1,49
********
 100, 121, 144, 225, 400, 441, 484, 676, 900,1156,1225,1444,1521,1600,1681,2025,
2116,2209,2500,3136,3364,3600,3844,3969,4225,4489,4624,4900,5625,5776,5929,6400,
6561,6889,7225,7744,8100,8281,8464,8836,9409,
Press any key to continue
//***********************************************************************//
//数组指针
#include<stdio.h>
#define M 20
void main()
{
	//int a[M][M]={{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15},{16,17,18,19,20},{21,22,23,24,25}};
	char ch[][M]={"DSGFDS","dfshgs32","sdfgh436"};//数组
	char (*str)[M];//数组指针
	int i;
	str=ch;
	for(i=0;i<3;i++){
			printf("%s,",*(str+i));//打印各字符串,*(str+i)为一字符串首地址
			printf("\n");
	}
}
运行结果:
DSGFDS,
dfshgs32,
sdfgh436,
Press any key to continue
//***********************************************************************//
//数组指针
#include<stdio.h>
#define M 20
void main()
{
	//int a[M][M]={{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15},{16,17,18,19,20},{21,22,23,24,25}};
	char ch[][M]={"DSGFDS","dfshgs32","sdfgh436"};//数组
	char (*str)[M];//数组指针
	int i,j;
	str=ch;
	for(i=0;i<3;i++){
		for(j=0;j<M;j++){
			printf("%c,",*(*(str+i)+j));//取出各个单字符元素,通过数组指针访问单个元素
		}
		printf("\n");
	}
}

//***********************************************************************//
//数组指针
#include<stdio.h>
#define M 5
void main()
{
	int a[M][M]={{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15},{16,17,18,19,20},{21,22,23,24,25}};
	int (*p)[M],sum=0;
	int i,j;
	p=a;
	for(i=0;i<M;i++){
		for(j=0;j<M;j++){
			printf("%2d,",a[i][j]);
		}
		printf("\n");
	}
	for(i=0;i<M;i++)
		sum=sum+*(*(p+i)+i);//通过数组指针访问单个元素
	printf("%d\n",sum);
}
//***********************************************************************//
//在上限个数范围内,在数组中输入一定数量的元素,并排序
#include<stdio.h>
#include<string.h>
int bubble_sort(int array[],int n)//冒泡排序法
{
	int i,j,flag,temp;
	int swapped=1;
	for(i=0;i<n-1;i++){
		flag =1;
		swapped=1;
		for(j=0;j<n-i-1;j++){
			if(array[j]>array[j+1]){
				temp=array[j];
				array[j]=array[j+1];
				array[j+1]=temp;
				flag=0;
				swapped=0;
			}
		}
		if(flag==1){
			return swapped;//返回1表示已经排序好
		}
	}
}

void main()
{
	int array[20];
	int i,n,k;
	printf("please input numbers:\n");
	for(i=0;i<20;i++){
		scanf("%d",&array[i]);
		if(array[i]==0)		//以输入数字0为结束输入标志
			break;
	}
	if(i<19)
		printf("break\n");
	n=i;	//记录当前n的值,即记住需要排序的元素个数

	k=bubble_sort(array,n);
	printf("1=false,0=true,so result=%d\n",k);
	for(i=0;i<n;i++){
		printf("%5d",array[i]);
	}
	printf("\n");
}
运行结果:
please input numbers:
12 2 5 2 1 34 44 334 34 0 45
break
1=false,0=true,so result=1
    1    2    2    5   12   34   34   44  334
Press any key to continue


//关于字符串复制覆盖的问题
#include <stdio.h>
#include<string.h>
void main()
{
	char s1[10]="a123d";//"a123d"字符串的长度不能超过s1预定的长度,否则
	char s2[10]="abcdefg";//打印或者复制的时候,字符串s1将在连续空间后面找到一个'\0'作为其结束标志
	strncpy(s2,s1,strlen(s1));//将s1字符串中前strlen(s1)个字符复制并覆盖s2前strlen(s1)个字符
	printf("%s\n",s2);	//用strlen计算字符串长度总是以遇到‘\0’为结束标志
}
运行结果:
a123dfg
Press any key to continue
//***********************************************************************//
#include <stdio.h>  
int main()   
{   
	int a[5]={9876,0123,4567,8901};//"0123"为八进制数,数组首地址为0x0012ff34
	int *ptr;//
	printf("%08x\n",a);
	printf("%08x\n",&a);
	ptr=(&a+3);//&a+1的值为0x0012ff35,但强制转换后赋值给ptr,其值却
	printf("%08x\n",(&a+3));//单位步长20个字节,跨越三个步长,共60个字节
	printf("%08x\n",ptr);//是0x0012ff70,正好为数组a末尾的下一个地址
    return 0;   
}
运行结果:
0012ff34
0012ff34
0012ff70
0012ff70
Press any key to continue
//***********************************************************************//
#include <stdio.h>  
int main()   
{   
	int a[5]={9876,0123,4567,8901};//"0123"为八进制数,数组首地址为0x0012ff34
	int *ptr;//
	ptr=(int *)(&a+1);//&a+1的值为0x0012ff35,但强制转换后赋值给ptr,其值却
	printf("%x\n",ptr);//是0x0012ff38,正好为数组a末尾的下一个地址

    return 0;   
}
//***********************************************************************//
//二维数组的大小
#include<stdio.h>
int main()
{
	int a[4][4];
	printf("%d,%d,%d\n",sizeof(a),sizeof(*a+1),sizeof(a[0]));//a,地址若为0x0012ff08,则指向其16个元素;
									//*a+1,为一指针,地
								//址为0x0012ff0c,而仅仅指向a[1][0]这个元素;a[0]则指向第0行的四个元素
	return 0;
}
运行结果:
64,4,16
Press any key to continue
//***********************************************************************//
//关于移位操作
#include<stdio.h>
#include<string.h>
void main()
{
	int x=0x0ff0;
	printf("%x\n",x<<4);//将会输出移位后的数据,但x的值不改变
	printf("%04x\n",x);//以宽度4输出十六进制数,不足4位宽度时,左边补上0
	printf("%x\n",x<<=4);
	printf("%x\n",x);

}

//***********************************************************************//
//sizeof和strlen
#include<stdio.h>
#include<string.h>
void main()
{
	char str[]="0123456789";//str空间大小11个字节,长度为10
	char *p=str;
	printf("%d,%d,%d,%d\n",sizeof(str),strlen(str),sizeof(p),strlen(p));
					//sizeof(p),即求指针的大小为4个字节
}
运行结果:
11,10,4,10
Press any key to continue
//***********************************************************************//
#include<stdio.h>
#include<string.h>
void main()
{
	char str1[]="1\\tmp012\012";//转义字符'\012'等同于'\n',即换行
	char str2[]="2\\tmp012";
	char str3[]="3tmp012";
	char str4[]="4tmp012\n";//换行
	char str5[]="5tmp012\r";//回车
	char str6[]="6xxx";//打印效果注意和str5的效果做比较
	char str7[]="7tmp012\v";//
	char str8[]="8tmp012\b";//退格
	char str9[]="9tmp012\x03";
	char str10[]="10tmp012\000";
	char str11[]="11tmp012\0016";//八进制001被转义为相应的ASCII码,即笑脸,
	char str12[]="12tmp012\005345"; //从\开始顺次取三个相连的数字作为转义字符,345直接显示
	printf("%d\n",strlen(str1));//重点验证字符串长度
	printf("%d\n",strlen(str2));
	printf("%d\n",strlen(str3));
	printf("%d\n",strlen(str4));
	printf("%d\n",strlen(str5));
	printf(str1);
	printf("\n");
	printf(str2);
	printf("\n");
	printf(str3);
	printf("\n");
	printf(str4);
	printf("\n");//str4的打印后会两次换行
	printf(str5);//str5字符串先打印,在回车到行首,即插入点又移到打印行的开头,若又打印字符,则
//	printf("\n");//部分或者全部覆盖之前的,若不打印或换行,则不会覆盖
	printf(str6);//str6显示的位置其实正是str5的位置
	printf("\n");
	printf(str7);
	printf("\n");
	printf(str8);
	printf("\n");
	printf(str9);
	printf("\n");
	printf(str10);
	printf("\n");
	printf(str11);
	printf("\n");
	printf(str12);
	printf("\n");
}

运行结果:
9
8
7
8
8
1\tmp012

2\tmp012
3tmp012
4tmp012

6xxx012
7tmp012
8tmp012
9tmp012.
10tmp012
11tmp012.6
12tmp012.345
Press any key to continue
//***********************************************************************//
//枚举变量的枚举值为递增的序号数值,定义时可以赋给初值,没赋初值的枚举值按照前面最近所赋初值为基数递增推导
#include <stdio.h>  
typedef enum app{
app_min=0,
aa=app_min,
bb,
cc,
max=0x34567890,
dd=max
}t;

void main(void)   
{   
  t x1=app_min;
	printf("%d\n",x1);  
	x1=aa;
	printf("%d\n",x1);
		x1=bb;
	printf("%d\n",x1);
		x1=cc;
	printf("%d\n",x1);
		x1=max;
	printf("%d\n",x1);

}
//***********************************************************************//
#include <stdio.h>  
void Test_SDI(void);
void Camera_Test(void);
struct {
	void (*fun)(void);//函数指针
	char *tip;
}CmdTip[] = {
				{ Test_SDI, "Test SD Card" } ,
				{ Camera_Test, "Test CMOS Camera"},
				{ 0, 0}						
			};
void main()   
{   
  char i;
  for(i=0; CmdTip[i].fun!=0; i++)
  {
	 printf("%d : %s,0x%x,", i, CmdTip[i].tip,&CmdTip[i].fun);
    (*CmdTip[i].fun)();
	printf("\n");
  }
  printf(",0x%x",&Test_SDI);
  printf(",0x%x",Test_SDI);
  printf("\n");

}
void Test_SDI(void)
{
  printf("SDI");
}

void Camera_Test(void)
{
  printf("Camera");
}
//***********************************************************************//
#include<stdio.h>
#include<string.h>
void main()
{
	char str1[]="abcdefgh";//str空间大小9个字节,长度为8
	char str2[]={'a','b','c','d','e','f','g','h','\0'};
	char str3[]={'a','b','c','d','e','f','g','h'};
	char str4[]="abcdef\0gh";
	char str5[]={'a','b','c','d','e','f','\0','g','h'};
	char *p1=str1;
	char *p2=str2;
	char *p3=str3;
	char *p4=str4;
	char *p5=str5;
	printf("str1:%d,%d,%d,%d\n",sizeof(str1),strlen(str1),sizeof(p1),strlen(p1));
					//sizeof(p),即求指针的大小为4个字节
	printf("str2:%d,%d,%d,%d\n",sizeof(str2),strlen(str2),sizeof(p2),strlen(p2));
	printf("str3:%d,%d,%d,%d\n",sizeof(str3),strlen(str3),sizeof(p3),strlen(p3));
	printf("str4:%d,%d,%d,%d\n",sizeof(str4),strlen(str4),sizeof(p4),strlen(p4));
	printf("str5:%d,%d,%d,%d\n",sizeof(str5),strlen(str5),sizeof(p5),strlen(p5));
}
//result:
str1:9,8,4,8
str2:9,8,4,8
str3:8,16,4,16//str3最后没有'\0',故出错,长度为16 ,是因为strlen()在内存中寻找以'\0'作为结束标志
str4:10,6,4,6
str5:9,6,4,6
Press any key to continue
//***********************************************************************//
#include<stdio.h>
#include<string.h>
void main()
{
	
	char str2[]={'r','o','c','k','c','h','i','p','s'};  //长度9
	printf("%s\n",str2);//打印时以遇到'\0'为结束标志
	printf("%d\n",strlen(str2));//用strlen()计算字符串长度总是以遇到‘\0’为结束标志
						//所以结果出错
}
运行结果:
rockchips烫虉.
15
Press any key to continue
//***********************************************************************//
//字符串长度问题
#include <stdio.h>  
int main()   
{   
	char str1[]="rockchips";							//长度9,大小为10
	char str2[]={'r','o','c','k','c','h','i','p','s'};  //长度9
	int n1=sizeof(str1)/sizeof(str1[0]);
	int n2=sizeof(str2)/sizeof(str2[0]);

	int n3=sizeof(str1);
	int n4=sizeof(str2);

	printf("n1=%d,n2=%d\n",n1,n2);
	printf("n3=%d,n4=%d\n",n3,n4);

    return 0;   
}
运行结果:
n1=10,n2=9
n3=10,n4=9
Press any key to continue
//***********************************************************************//
//小端存储
#include <stdio.h>  
int main()   
{   
    int a=0x12345678;   
	char b=(char)a;
	printf("高字节地址为:0x%x\n",&a);//小端存储,0x12ff44地址对应数据78,0x12ff45对应数据56,0x12ff46对应34....
	printf("高字节地址为:0x%x\n",&b);//0x12ff40
	printf("高字节地址为:0x%x\n",b);//0x78,强制转换取最低字节数据
    return 0;   
}
//***********************************************************************//
//程序中各种变量的存储位置和程序返回变量的问题 - - 博客频道 - CSDN_NET
#include <stdio.h>  
char *returnStr()   
{   
//    char *p="hello world!";  //"hello world!"是一个字符串常量,存放在只读数据段,指针返回后,内容不被释放
//	char p[]="hello world!"; //"hello world!"是局部变量存放在栈中,函数返回时,会被释放清空
	static char p[]="hello world!"; //"hello world!"是一个局部静态变量,此处是允许的,返回后,内容不被释放
    return p;   
}   

int main()   
{   
    char *str=NULL;   
    str=returnStr();   
    printf("%s\n", str);   
    return 0;   
}
//***********************************************************************//
//字节对齐,本地变量
#include<stdio.h>
int main() 
{ 
int a; 
char b; 
int c; 
printf("0x%x\n",&a); 
printf("0x%x\n",&b); 
printf("0x%x\n",&c); 
return 0; 
} 
//***********************************************************************//
//变量存储位置
#include <stdio.h> 
int g1=0, g2=0, g3=0; 
int main() 
{ 
static int s1=0, s2=0, s3=0; 
int v1=0, v2=0, v3=0; 
printf("0x%x\n",&v1); //打印各本地变量的内存地址(地址递减) 栈中、动态数据区、运行时分配
printf("0x%x\n",&v2); 
printf("0x%x\n\n",&v3); 
printf("0x%x\n",&g1); //打印各全局变量的内存地址(地址递增) 静态数据区、编译时分配
printf("0x%x\n",&g2); 
printf("0x%x\n\n",&g3); 
printf("0x%x\n",&s1); //打印各静态变量的内存地址(地址递增) 静态数据区、编译时分配
printf("0x%x\n",&s2); 
printf("0x%x\n\n",&s3); 
return 0; 
} 
//***********************************************************************//
//位域,结构体,字节对齐
#include<stdio.h>
struct sttest{
	char a;
	short c[3];
	char *b;
/*	union {
		char c,d;
		unsigned e:2,f:1;
	};
	struct sttest *link;
*/
};
void main()
{
	char c;
	c=sizeof(struct sttest);
	printf("struct sttest的大小:%d\n",c);
}
运行结果:
struct sttest的大小:12
Press any key to continue
/*
字节对齐的细节和编译器实现相关,但一般而言,满足三个准则:
	原则1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
备注:编译器在给结构体开辟空间时,首先找到结构体中最宽的基本数据类型,然后寻找内存地址能被该基本数据
类型所整除的位置,作为结构体的首地址。将这个最宽的基本数据类型的大小作为上面介绍的对齐模数。
	原则2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之
间加上填充字节(internal adding);
备注:为结构体的一个成员开辟空间之前,编译器首先检查预开辟空间的首地址相对于结构体首地址的偏移是否是本
成员的整数倍,若是,则存放本成员,反之,则在本成员和上一个成员之间填充一定的字节,以达到整数倍的要求,
也就是将预开辟空间的首地址后移几个字节。
	原则3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节
(trailing padding)。
备注:结构体总大小是包括填充字节,最后一个成员满足上面两条以外,还必须满足第三条,否则就必须在最后填充
几个字节以达到本条要求。
*/
//***********************************************************************//
#include<stdio.h>
typedef struct bb
{
 int id;             //偏移地址[0]....[3]
 double weight;      //[8].....[15]      原则2
 float height;      //[16]..[19],总长要为8的整数倍,补齐[20]...[23]     原则3
}BB;

typedef struct aa
{
 char name[2];     //[0],[1]
 int  id;         //[4]...[7]          原则2

 double score;     //[8]....[15]    
 short grade;    //[16],[17]        
 BB b;             //[24]......[47]          原则2
}AA;

int main()
{
  AA a;
  printf("%d  %d\n",sizeof(a),sizeof(BB));
  return 0;
}
运行结果:
48  24
Press any key to continue
//***********************************************************************//
//32位系统下,各种数据类型的大小
#include<stdio.h>
struct sttest{
	unsigned int e:2,f:1;
	int a;
};
   int Num;
   char *pc;
   int *pint;
   short sDate;
   char cha[2];
   short sBa[4];
   long double ld;
   //unsigned int e:2,f:1;

void main()
{
  char c;
  c=sizeof(int);
  printf("int型大小:%d\n",c);

  c=sizeof(unsigned int);
  printf("unsigned int型大小:%d\n",c);

  c=sizeof(char);
  printf("char型大小:%d\n",c);

  c=sizeof(short);
  printf("short型大小:%d\n",c);

  c=sizeof(long);
  printf("long型大小:%d\n",c);

  c=sizeof(float);
  printf("float型大小:%d\n",c);

  c=sizeof(double);
  printf("double型大小:%d\n",c);

  c=sizeof(long double);
  printf("long double型大小:%d\n",c);

  c=sizeof(ld);
  printf("ld的大小:%d\n",c);

  c=sizeof(cha);
  printf("char型的数组cha[2]大小:%d\n",c);

  c=sizeof(sBa);
  printf("short型的数组sBa[4]大小:%d\n",c);
  c=sizeof(sBa[4]);
  printf("sBa[4]大小:%d\n",c);//针对单个元素
  c=sizeof(&sBa);
  printf("&sBa大小:%d\n",c);
  c=sizeof(&sBa[0]);		//?????????
  printf("&sBa[0]大小:%d\n",c);

  c=sizeof(pc);
  printf("char型的指针大小:%d\n",c);
  c=sizeof(*pc);		//针对数据的取值
  printf("*pc的大小:%d\n",c);

  c=sizeof(pint);
  printf("int型的指针大小:%d\n",c);

  c=sizeof(struct sttest);
  printf("结构体 struct sttest型的大小:%d\n",c);
 
}

运行结果:
int型大小:4
unsigned int型大小:4
char型大小:1
short型大小:2
long型大小:4
float型大小:4
double型大小:8
long double型大小:8
ld的大小:8
char型的数组cha[2]大小:2
short型的数组sBa[4]大小:8
sBa[4]大小:2
&sBa大小:8
&sBa[0]大小:4
char型的指针大小:4
pc指针指向的数据的大小:1
int型的指针大小:4
结构体 struct sttest型的大小:8
Press any key to continue
//***********************************************************************//
//数组指针和指针数组的区别 - jack_Meng - 博客园
#include<stdio.h>
int main()
{
  	char a[10]={'a','b','c','d'};
  	char (*p1)[5]= &a;				//将数组a[]的整个数组首地址地址赋给数组指针p1
  	char (*p2)[5]=(char (*)[5])a;	//将数组首元素的地址a先强制转换为整个数组的首地址,再赋给p2

  	printf("a=%d\n",a);
  	printf("a=%c\n",a[0]);
  	printf("p1=%c\n",**p1);
  	printf("p2=%c\n",**p2);
  	printf("p1+1=%c\n",**(p1+1));//指针加一,步长跨越5个字节
  	printf("p2+1=%c\n",**(p2+1));
	printf("p2+1=0x%x\n",**(p2+2));

    printf("p2+0=%c\n",*(*p2+0));
    printf("p2+1=%c\n",*(*p2+1));
	printf("p2+2=%c\n",*(*p2+2));
	printf("p2+3=%c\n",*(*p2+3));
	printf("p2+4=%d\n",*(*p2+4));

  	return 0;
}
//***********************************************************************//
#include<stdio.h>
void main(void)
{
    int p[4] = {0x31,0x32,0x33,0x34};//调试时,指针的地址可以查看
	int a=0x41;//调试时,变量的地址不可查看
}
//***********************************************************************//
//无符号数和有符号数之间的算法结果-如果2个操作数中有unsigned类型的默认将两个数都当做unsigned进行处理,
//结果也是无符号的数据.答案是“>26”
#include<stdio.h>
void main()
{
  unsigned int a=6;
  int b=-20;
  (a+b<=6)?puts("<=6"):((a+b<=14)?puts("<=14"):((a+b<=26)?puts("<=26"):puts(">26")));
}

#include<stdio.h>
void main()
{
  unsigned int a=6;
  int b=-20;
  int c=-20;
  printf("a+b=%d\n",a+b);

  b=~b;//按位取反和数值求反 b=-b; 不一样,前者小1,因为无论正负数,在内存中都以补码形式存在
  c=-c;//数值求反
  printf("c=%X\n",c);
  printf("a+b=%d\n",a+b);

  b++;
  printf("a+b=%d\n",a+b);
  (a+b<=6)?puts("<=6"):((a+b<=14)?puts("<=14"):((a+b<=26)?puts("<=26"):puts(">26")));
}
//***********************************************************************//
/*关于反汇编的堆栈使用,相关解释在百度知道雨林沐*/
#include<stdio.h>
long test(int a,int b)
{
a = a + 1;
b = b + 100;
return a + b;
}
void main()
{
printf("%d\n",test(1000,2000));
}
//***********************************************************************//
/*关于“堆栈”的问题*/
#include <stdio.h>
#include <string.h>
struct C
{
int a;
int b;
int c;
};
int test2(int x, int y, int z)
{
printf("hello,test2\n");
return 0;
}
int test(int x, int y, int z)
{
int a = 1;
int b = 2;
int c = 3;
struct C st;
printf("addr x = %u\n",(unsigned int)(&x));
printf("addr y = %u\n",(unsigned int)(&y));
printf("addr z = %u\n",(unsigned int)(&z));
printf("addr a = %u\n",(unsigned int)(&a));
printf("addr b = %u\n",(unsigned int)(&b));
printf("addr c = %u\n",(unsigned int)(&c));
printf("addr st = %u\n",(unsigned int)(&st));
printf("addr st.a = %u\n",(unsigned int)(&st.a));
printf("addr st.b = %u\n",(unsigned int)(&st.b));
printf("addr st.c = %u\n",(unsigned int)(&st.c));
return 0;
}
int main(int argc, char** argv)
{
int x = 1;
int y = 2;
int z = 3;
test(x,y,z);
printf("x = %d; y = %d; z = %d;\n", x,y,z);
memset(&y, 0, 8);
printf("x = %d; y = %d; z = %d;\n", x,y,z);
return 0;
}
//***********************************************************************//
/*关于“#line”的应用*/
#include<stdio.h>
int main(void)
{
#line 98 "a.c"
printf("%s %d\n",__FILE__,__LINE__); //第98行
printf("%s %d\n",__FILE__,__LINE__); //99
printf("%s %d\n",__FILE__,__LINE__); //100
printf("-=-=-=-=-=-=-=-=-=-=-=-\n"); //101
printf("%s %d\n",__FILE__,__LINE__); //102
return 0; //101
}
//***********************************************************************//
#include<stdio.h>
void GetMemory(char **p, int num) 
{
*p = (char *)malloc(num);
}
void main(void)
{
char *str = NULL;
GetMemory(&str, 100);
strcpy(str, "hello");
printf(str);
}
//***********************************************************************//
#define SQ(y) ((y)*(y))
void main()
{
 int i=1;
 while(i<=5)
 {
  printf("%d\n",SQ(i++));
 }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值