Почему функция упоминается в глобальной декларации?

Я пришел к этому коду для записи данных в EEPROM в arduino. Почему функции void printTemp();, void clearEEPROM(); и void writeTemp(); упоминаются в глобальной декларации? Как это поможет?

#include <EEPROM.h>
 
#define SAMPLE_TIME 2000  //Время между каждым вызовом функции записи EEPROM в ms
     
int tempPin = 0;      /pin АЦП
int printPin = 2;     //pin кнопки печати
int erasePin = 4;    //pin кнопки стирания
 
int address = 0;      //Счетчик адресов EEPROM
     
unsigned long timer;
     
float conv_coeff = 0.0;   //коэффициент для преобразования из диапазона 0-1024 в диапазон 0-5
     
void printTemp();
void clearEEPROM();
void writeTemp();
     
void setup(){
  Serial.begin(115200);     //start the serial connection as always
  conv_coeff = 5.0/1024.0;  //find the coefficient to do the conversion
  timer = millis();         //millis() возвращает время с момента запуска программы в ms
}
     
void loop(){
  if(millis()-timer > SAMPLE_TIME)  //проверьте, пришло ли время сделать образец датчика температуры
  {
    writeTemp();
    timer = millis();
  }
     
  if(!digitalRead(printPin))  //проверьте, нажата ли кнопка печати
  {
    printTemp();
    delay(500);
  }
     
  if(!digitalRead(erasePin)) //проверьте, нажата ли кнопка erase
  {
    clearEEPROM();
    delay(500);
  }
       
  delay(1);
}
     
void printTemp()
{
  for (int i = 0 ; i < EEPROM.length() ; i++) {
    byte value = EEPROM.read(i);                //read EEPROM data at address i
    if(value != 0)                              //skip "empty" addresses
    {
      float temp = value*conv_coeff;            //convert ADC values to temperature
      temp = (temp - 0.5)*100;                  //take care of the offset
     
      Serial.println(temp);
    }
  }
}
     
void clearEEPROM()
{
  for (int i = 0 ; i < EEPROM.length() ; i++) {
    if(EEPROM.read(i) != 0)                     //skip already "empty" addresses
    {
      EEPROM.write(i, 0);                       //write 0 to address i
    }
  }
  Serial.println("EEPROM erased");
  address = 0;                                  //reset address counter
}
     
void writeTemp()
{
  byte value = analogRead(tempPin);     //read sensor value
       
  EEPROM.write(address, value);         //write value to current address counter address
     
  Serial.print("Sensor value stored at address ");
  Serial.println(address);
    
  address++;                      //increment address counter
  if(address == EEPROM.length())  //check if address counter has reached the end of EEPROM
  {
    address = 0;              //if yes: reset address counter
  }
}

, 👍0


2 ответа


2

Они называются прототипами функций. Они означают, что "Эти функции существуют где-то еще". Это "где-то в другом месте" может позже оказаться в том же файле или совсем в другом файле.

Обычно такие вещи предоставляются файлами заголовков (.h) или автоматически создаются (для функций в файле INO) средой IDE и скрыты от вас, поэтому вы никогда не видите их на самом деле. Но если вы не используете интегрированную среду разработки, вам нужно иметь их, чтобы ваш код (который анализируется линейно) знал, что эти функции существуют, прежде чем анализатор их обнаружит.

,

Спасибо! рекомендуется ли писать это в коде? Даже при использовании IDE?, @Amrutha B V

Это хорошая привычка, которой стоит овладеть, когда вы закончите учебу и начнете правильно программировать ;), @Majenko

@Majenko, ой. Мы все когда-нибудь должны научиться!, @Duncan C

@DuncanC Все, что я хочу сказать, это то, что многие пользователи Arduino являются студентами, и когда вы закончите учебу и получите работу, от вас будут ожидать определенных стандартов ;), @Majenko


1

Первоначально C (от которого C++ унаследовал большую часть своего синтаксиса) был скомпилирован компилятором с одним проходом: компилятор получил только один взгляд на код.

Компилятор с несколькими проходами может просмотреть код и собрать определения функций за один проход, а затем на более позднем этапе скомпилировать код, вызывающий эти функции, или обнаружить ошибки в этих вызовах, если таковые имеются.

Компилятор с одним проходом не может этого сделать, поэтому ему нужно, чтобы функция или ее прототип появлялись перед любым кодом, который ее вызывает, чтобы у компилятора была та же информация, когда она ему нужна.

Прототип предоставляет имя функции, число и типы ее аргументов, а также тип возвращаемого значения, что необходимо компилятору для подтверждения и компиляции вызова функции или для выдачи диагностического сообщения, если вызов не соответствует прототипу.

,