#include <stdarg.h>

转载别人的,希望以后自己记录也能像这样用心一点,有说明,还有例子,最后还有研究。


头文件 #include <stdarg.h>

格式化宏主要有四个

void va_start(va_list ap,last);

type va_arg(va_list ap,type);

void va_end(va_list ap);

void va_copy(va_list dest,va_list src);


它们的用法如下:

void va_start(va_list ap,last);

必须第一个被调用,初始化ap变量,last是函数参数的最后一个参数,其中这个最后一个参数不能使寄存器变量,函数指针,数组变量,因为va_start宏会用到last变量的地址.

type va_arg(va_list ap,type);

根据type类型来返回last后的参数值,ap为va_start初始化的ap,注意type 为指针类型时不需要用括号括起来

void va_end(va_list ap);

与va_start配对使用

void va_copy(va_list dest,va_list src);

主要用在va_list作为函数的参数传递时,详细的暂时不太清楚。


  
  ◎用法:
  func( Type para1, Type para2, Type para3, ... )
  {
   /****** Step 1 ******/
   va_list ap;
   va_start( ap, para3 ); //一定要“...”之前的那个参数
  
   /****** Step 2 ******/
   //此时ap指向第一个可变参数
   //调用va_arg取得里面的值
  
   Type xx = va_arg( ap, Type );
  
   //Type一定要相同,如:
   //char *p = va_arg( ap, char *);
   //int i = va_arg( ap, int );
  
   //如果有多个参数继续调用va_arg
  
   /****** Step 3 ******/
   va_end(ap); //For robust!
  }
  
  ◎研究:
  typedef char * va_list;
  
  #define va_start _crt_va_start
  #define va_arg _crt_va_arg
  #define va_end _crt_va_end
  
  #define _crt_va_start(ap,v) ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )
  #define _crt_va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
  #define _crt_va_end(ap) ( ap = (va_list)0 )
  va_list argptr;
  C语言的函数是从右向左压入堆栈的,调用va_start后,
  按定义的宏运算,_ADDRESSOF得到v所在的地址,然后这个
  地址加上v的大小,则使ap指向第一个可变参数如图:
  
   栈底 高地址
   | .......
   | 函数返回地址
   | .......
   | 函数最后一个参数
   | ....
   | 函数第一个可变参数 <--va_start后ap指向
   | 函数最后一个固定参数
   | 函数第一个固定参数
   栈顶 低地址
#include "stm32f10x.h" // Device header #include <stdio.h> #include <stdarg.h> uint8_t Serial_RxData; uint8_t Serial_RxFlag; void Serial_Init(void) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_Init(USART3, &USART_InitStructure); USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_Init(&NVIC_InitStructure); USART_Cmd(USART3, ENABLE); } void Serial_SendByte(uint8_t Byte) { USART_SendData(USART3, Byte); while (USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET); } void Serial_SendArray(uint8_t *Array, uint16_t Length) { uint16_t i; for (i = 0; i < Length; i ++) { Serial_SendByte(Array[i]); } } void Serial_SendString(char *String) { uint8_t i; for (i = 0; String[i] != '\0'; i ++) { Serial_SendByte(String[i]); } } uint32_t Serial_Pow(uint32_t X, uint32_t Y) { uint32_t Result = 1; while (Y --) { Result *= X; } return Result; } void Serial_SendNumber(uint32_t Number, uint8_t Length) { uint8_t i; for (i = 0; i < Length; i ++) { Serial_SendByte(Number / Serial_Pow(10, Length - i - 1) % 10 + '0'); } } int fputc(int ch, FILE *f) { Serial_SendByte(ch); return ch; } void Serial_Printf(char *format, ...) { char String[100]; va_list arg; va_start(arg, format); vsprintf(String, format, arg); va_end(arg); Serial_SendString(String); } uint8_t Serial_GetRxFlag(void) { if (Serial_RxFlag == 1) { Serial_RxFlag = 0; return 1; } return 0; } uint8_t Serial_GetRxData(void) { return Serial_RxData; } void USART3_IRQHandler(void) { if (USART_GetITStatus(USART3, USART_IT_RXNE) == SET) { Serial_RxData = USART_ReceiveData(USART3); Serial_RxFlag = 1; USART_ClearITPendingBit(USART3, USART_IT_RXNE); } }
最新发布
04-03
``` #include <stdio.h> #include <stdarg.h> #define MAX_HEAP_SIZE 1000 #define PARENT(i) (i/2) // given the index of a heap node, the returns the parent index #define LEFT(i) (2*i) // given the index of a heap node, the returns the left child index #define RIGHT(i) (2*i + 1) // given the index of a heap node, the returns the right child index #define SWAP(a, b, temp) {temp=a; a=b; b=temp;} typedef struct { void *a[MAX_HEAP_SIZE]; int size; } heap; void heap_init(heap *h); void heapify(heap *h, int (*comp_func)(void*, void*), int i); void build_heap(heap *h, int (*comp_func)(void*, void*)); void* heap_extract_max(heap *h, int (*comp_func)(void*, void*)); void heap_insert(heap *h, int (*comp_func)(void*, void*), void *key); // set heap size to 0 and NULL out all values void heap_init(heap *h) { int j; h->size = 0; for(j = 0; j < MAX_HEAP_SIZE; j++) h->a[j] = NULL; return; } // Adapted from Introduction to Algorithms, 1990, // by Cormen, Leiserson, Rivest, and Stein. // Chapter 7, Section 7.2 void heapify(heap *h, int (*comp_func)(void*, void*), int i) { void *temp = NULL; int largest, l = LEFT(i), r = RIGHT(i); if(l <= h->size && comp_func(h->a[l], h->a[i]) > 0) largest = l; else largest = i; if(r <= h->size && comp_func(h->a[r], h->a[largest]) > 0) largest = r; if(largest != i) { SWAP(h->a[i], h->a[largest], temp); heapify(h, comp_func, largest); } return; } // Adapted from Introduction to Algorithms, 1990, // by Cormen, Leiserson, Rivest, and Stein. // Chapter 7, Section 7.3 void build_heap(heap *h, int (*comp_func)(void*, void*)) { int i; for(i = h->size/2; i > 0; i--) heapify(h, comp_func, i); return; } // Adapted from Introduction to Algorithms, 1990, // by Cormen, Leiserson, Rivest, and Stein. // Chapter 7, Section 7.5 void* heap_extract_max(heap *h, int (*comp_func)(void*, void*)) { if(h->size < 1) return NULL; void *max = h->a[1], *temp = NULL; SWAP(h->a[1], h->a[h->size], temp); h->size--; heapify(h, comp_func, 1); return max; } // Adapted from Introduction to Algorithms, 1990, // by Cormen, Leiserson, Rivest, and Stein. // Chapter 7, Section 7.5 void heap_insert(heap *h, int (*comp_func)(void*, void*), void *key) { int i = ++h->size; while(i > 1 && comp_func(h->a[PARENT(i)], key) < 0) { h->a[i] = h->a[PARENT(i)]; i = PARENT(i); } h->a[i] = key; return; }```请解释这段代码的作用
03-24
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值