天天看點

那些踩過的declared implicitly的坑缺少頭檔案重複定義

缺少頭檔案

我的本意是想做序列槽列印進行調試,于是我在usart.c中重寫了這兩個函數,這裡順便記錄下如何序列槽列印

usart.c中

int fputc(int ch, FILE *f)
{
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
  return ch;
}
int fgetc(FILE * f)
{
  uint8_t ch = 0;
  HAL_UART_Receive(&huart1,&ch, 1, 0xffff);
  return ch;
}
           

main函數之前

本來以為大功告成,結果出現了FILE沒有定義,…/Core/Src/main.c(93): warning: #223-D: function “printf” declared implicitly 這些錯誤,本質上的原因是因為沒有在uart.h 中聲明 #include <stdio.h>,這主要是沒有了解重定義函數的意義。

printf 定義在 <stdio.h> 頭檔案中,printf 函數根據 format 字元串給出的格式列印輸出,stdout(标準輸出)中,當然,printf 函數是不會一個字元一個字元去輸出,它會調用更底層的 I/O 函數:fputc去逐個字元列印。fputc 也定義于頭檔案 <stdio.h>中。

添加好頭檔案後,幾個常用的示例:

char str[20];
  uint8_t ch;
  /* 複位所有外設,初始化Flash接口和系統滴答定時器 */
  HAL_Init();
  /* 配置系統時鐘 */
  SystemClock_Config();

  /* 初始化序列槽并配置序列槽中斷優先級 */
  MX_DEBUG_USART_Init();
  
  /* 調用格式化輸出函數列印輸出資料 */
  printf("Hello world!!!\n");
  
  /* sprintf函數把格式化的資料寫入某個字元串  */  
  sprintf(str,"今天是個好日子,20%02d-%02d-%02d",15,10,04);  
  /* 調用格式化輸出函數列印輸出資料 */
  printf("%s\n",str);
  /* 無限循環 */
  while (1)
  {
    ch=getchar();
    HAL_UART_Transmit(&huart1,&ch,1,0);
  }
           

重複定義

這個我遇到過兩種:

1 我本來是想寫一個新的bsp,于是我把bsp_led.c和.h分别進行複制,改了個名字,結果沒有修改。

ifdef 的用法

複制代碼
#define   KEY1_PA0

#ifdef    KEY1_PA0
-------------第一段-----------------
#define               macKEY1_GPIO_CLK                      RCC_APB2Periph_GPIOA
#define               macKEY1_GPIO_PORT                     GPIOA              
#define               macKEY1_GPIO_PIN                        GPIO_Pin_0

#else    //KEY2_PC13
-------------第二段-----------------
#define               macKEY1_GPIO_CLK                      RCC_APB2Periph_GPIOC
#define               macKEY1_GPIO_PORT                     GPIOC          
#define               macKEY1_GPIO_PIN                        GPIO_Pin_13

#endif
複制代碼
           

如果定義過KEY1_PA0,則執行第一段代碼,如果沒有,執行第二段。

ifndef 用法

#ifndef __USART1_H
#define    __USART1_H

//statement.

#endif  // usart1.h
           

如果沒有define過__USART1_H,就執行下面的語句;如果定義過,就不執行;

是以在一個.c檔案裡面,多次調用到該檔案的時候,就相當于隻調用一次。

這是頭檔案的常用寫法!!由于我沒有更改,就出現了兩個相同的頭檔案定義。

2 這是關于extern的用法

當有一個變量需要在多個檔案中用到時,不能定義在頭檔案中,可能會導緻重複定義,要把該變量定義在某個.c檔案中,另一個需要用到該變量的.c或者.h檔案在該變量的聲明前加extern

我們看一個示例:這是hal庫定義的例子

usart.c中定義

UART_HandleTypeDef huart1
           

usart.h中

這是正确的,但如果UART_HandleTypeDef huart1定義在了.h檔案中,在main函數裡和uart.c中都使用用了usart.h,出現了重複的定義。

繼續閱讀