ESP8266程序编写中遇到的语法总结

本次博客知识来自于韦东山老师的7天物联网课程。

1、当使用HAL库的函数时,遇到函数形参时指针时,实参应为地址。

HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)

这个函数中,形参UART_HandleTypeDef *huart、uint8_t *pData。均为指针,所以调用时,实参应为地址,如下。

HAL_UART_Receive_IT(&huart2, (uint8_t*)&rx_data, 1);

2、强制数据类型转换。

如上,(uint8_t*)&rx_data,即为把rx_data强制转换为8位的指针并取地址。

3、数组地址的问题。

数组名即可代表数组首元素的地址。

详细解释见数组的地址问题详解

4、字符串地址的问题。

字符串本身就是一个地址,字符串它的本身就相当于字符数组名,数组可以的操作,字符串也都可以。详细解释见字符串的地址问题详细解释

如下代码,函数的形参是指针,而实参用的是字符串。

ESP8266_SendCommand("AT+CWMODE=1", "OK", 500);

uint8_t ESP8266_SendCommand(char *cmd, char *reply, uint16_t timeout)
#include <stdio.h>
#include<string.h>

using namespace std;

int main()
{
	char c[5] = {1,2,3,4,5};
	printf("%#x\n", c);
	printf("%#x\n", &c[0]);	
	printf("%#x\n", &c);
	printf("\n");

	printf("%#x\n", &c[1]);
	printf("%#x\n", c + 1);
	printf("%#x\n", &c[0]+1);
	printf("%#x\n", &c+1);
	printf("%#x\n", (&c) + 1);

	printf("%d\n", sizeof(c[0]));
	printf("%d\n", sizeof(c));
	printf("%d\n", sizeof(&c[0]));
	printf("%d\n", sizeof(&c));
	printf("%d\n", sizeof(char));
	printf("%d\n", sizeof(int));
}

 

/* printf example */
#include <stdio.h>
#include<string.h>

using namespace std;

int main()
{
	char c[4] = {1,2,3,4};
	printf("%#x\n", c);
	printf("%#x\n", &c[0]);	
	printf("%#x\n", &c);
	printf("\n");

	printf("%#x\n", &c[1]);
	printf("%#x\n", c + 1);
	printf("%#x\n", &c[0]+1);
	printf("%#x\n", &c+1);
	printf("%#x\n", (&c) + 1);

	printf("%d\n", sizeof(c[0]));
	printf("%d\n", sizeof(c));
	printf("%d\n", sizeof(&c[0]));
	printf("%d\n", sizeof(&c));
	printf("%d\n", sizeof(char));
	printf("%d\n", sizeof(int));
}

 

结合上述两个程序,得到

  • c是数组首元素地址0x49eff9b4;
  •  c+1为数组元素地址后移一个char型(1个char型一个字节)的偏移量0x49eff9b4+1;
  • &c是整个数组的地址0x49eff9b4;
  • &c+1、((&c)+1)整个数组的地址后移整个数组空间大小的偏移量,即0x49eff9b4+1*4=0x49eff9b9或0x49eff9b4+1*3=0x49eff9b8;
  • &c[0]是数组首元素地址0x49eff9b4,注意:&c[0]是一个指针,编译器要为它分配存储空间,但c不是指针型变量,不会被分配存储空间;
  • &c[0]+1为数组元素地址后移一个char型的偏移量,即0x49eff9b4+1;
  • sizeof(c[0])是首元素1所占字节大小:1;
  • sizeof(c)是整个数组所占字节大小:4*1/5*1;
  • sizeof(&c)是数组的地址所占字节大小:8;
  • sizeof(&c[0])是首元素1的地址所占字节大小:8;
  • sizeof(char)、sizeof(int)分别是char型和整形所占的字节大小。

5、printf输出格式。

如,printf("%d\n", a)中,%d即为a表示的输出位置,且是用10进制的格式输出。

详细的解释见详细printf()输出格式

6、取余的巧妙用法。

static uint8_t rx_data = 0;            //接收的字符
static uint8_t rx_len = 0;             //接收的长度
static uint8_t usart_rx_buf[200] = {0};//保存接收的数据

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	usart_rx_buf[rx_len%200]= rx_data;
	rx_len++;
	HAL_UART_Receive_IT(&huart2, (uint8_t*)&rx_data, 1);
}

上述代码中usart_rx_buf[]为一个200个成员的数组,但是第五行代码用了rx_len%200,取余的操作,巧妙的解决了容量不足的问题,思路如下。

1/200=余1
2/200=余2

201/200=余1
202/200=余2

7、memcpy、memset、strcat、strstr、sprintf。

1)memcpy

extern void *memcpy(void *dest, void *src, unsigned int count);

用法:#include <string.h>

功能:由src所指内存区域复制count个字节到dest所指内存区域。

说明:

  • str1 -- 指向用于存储复制内容的目标数组,类型强制转换为 void* 指针;
  • str2 -- 指向要复制的数据源,类型强制转换为 void* 指针;
  • n -- 要被复制的字节数。
  •  src和dest所指内存区域不能重叠,函数返回指向dest的指针。

2)memset

void *memset(void *str, int c, size_t n)

用法:#include <string.h>

功能:复制字符 c(一个无符号字符)到参数 str 所指向的字符串的前 n 个字节。

说明:

  • str -- 指向要填充的内存块;
  • c -- 要被设置的值。该值以 int 形式传递,但是函数在填充内存块时是使用该值的无符号字符形式;
  • n -- 要被设置为该值的字节数;
  • 该值返回一个指向存储区 str 的指针。

3)strcat

char *strcat(char *dest, const char *src)

用法:#include <string.h>

功能:把 src 所指向的字符串拼接dest 所指向的字符串的结尾。

说明:

  • dest -- 指向目标数组,该数组包含了一个 C 字符串,且足够容纳追加后的字符串;
  • src -- 指向要追加的字符串,该字符串不会覆盖目标字符串;
  • 该函数返回一个指向最终的目标字符串 dest 的指针。

4)strstr

char *strstr(const char *haystack, const char *needle)

用法:#include <string.h>

功能:在字符串 haystack 中查找第一次出现字符串 needle 的位置,不包含终止符 '\0'。

说明:

  • haystack -- 要被检索的 C 字符串;
  • needle -- 在 haystack 字符串内要搜索的小字符串;
  • 该函数返回在(返回值) haystack 中第一次出现 needle 字符串的地址,如果未找到则返回 null。

5)sprintf

int sprintf(char *buffer, const char *format, [argument]…)

用法:#include <stdio.h>

功能:格式化字符串,将格式化的数据写入字符串中。

说明:

  • buffer -- 是char类型的指针,指向写入的字符串指针;
  • format -- 格式化字符串,即在程序中想要的格式;
  • argument -- 可选参数,可以为任意类型的数据

  • 函数返回值:buffer指向的字符串的长度。

  • 格式化数字字符串:在这点上sprintf和printf的用法一样,只是打印到的位置不同而已,前者打印给buffer字符串,后者打印给标准输出,所以sprintf也可以用来将整型转化为字符串,比itoa效率高且如此地简便~比如:sprintf(buffer, “%d”, 123456);执行后buffer即指向字符串“123456”~

  • 
        #include<stdio.h>  
        int main()  
        {  
            char buffer[10];  
            char *a = “1234”;  
            char *b = “5678”;  
            sprintf(buffer, ”%s%s”, a, b);  
            printf(”%s\n”, buffer);  
            return 0;  
        }  

    结果

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值