ESP-8266/ESP32 NodeMCU Lua: азы программирования.

Тема в разделе "ESP8266, ESP32", создана пользователем ИгорьК, 25 июл 2017.

  1. ИгорьК

    ИгорьК Гуру

    Может и не обязательно JS, но что тогда?
    Автоматические типы данных и сборщик мусора и по книге Иерусалимски понятны.
    И, затрудняюсь сказать - особенности ли это скриптовых языков. Но это не важно.
    Что касается замыканий и callback - они ИМХО лучше всего раскрыты в JS. Посоветуйте что другое. Python точно не от сюда.
     
  2. b707

    b707 Гуру

    Callback-и и в Си есть, что в callback-ах Lua такого удивительного. что их надо через яваскрипт понимать?

    А что касается замыканий - кмк. это следствие наличия переменных с лексической областью действия, любой скриптовый язык. где есть такие переменные. наверно имеет и замыкания... мне так кажется. Например, по базовым конструкциям Луа мне очень напомнил Перл - в котором как раз есть замыкания. Правда. замыкания в Перле - это "выше средний" уровень владения языком, пользуются ими в Перле редко.
     
  3. ИгорьК

    ИгорьК Гуру

    :) зря я сменил название темы.
    Посчитайте, сколько здесь присутствующих знают о callback в Си.

    callback в Си - это высший пилотаж.

    Я позже напишу вводную часть - разъясню особенности.
    Пойду пиво пить.
     
  4. b707

    b707 Гуру

    ну не знаю, не считаю себя знатоком Си. вообще не очень люблю на нем писать... но в callback-ами пользуюсь как чем-то естесственным, в event-driven программировании без них трудно.

    Буду ждать вступительную часть про "особенности". очень часто именно в сравнении языков лучше понимаешь нюансы каждого из них
     
  5. rkit

    rkit Гуру

    Думайте еще, арифметики указательные.
    Код (Text):
    rkit@host /tmp $ cat > 1.c
    #include <stdio.h>

    void main()
    {
      char *p = "car";

      2[p] = 'd';

      printf("%s\n", p);
    }
    rkit@host /tmp $ gcc 1.c
    rkit@host /tmp $ ./a.out
    Segmentation fault (core dumped)

     
     
  6. ИгорьК

    ИгорьК Гуру

    Даже если Вы не знаток Си - Вы профессиональный программист, не так ли?
    Вы мыслите как программист, знаете общие вещи об алгоритмах и еще кучу всяких правильных вещей.

    Мои заметки не для Вас - они для самоделкиных-непрограммистов, коим я отношусь. (Кроме написания корявого кода я умею печатать на 3D принтере, работать на чпу станке, ровнять доски на фуганке, работать фрезером, болгаркой, etc. И все это моё хобби.)

    Я не буду учить языку Луа, я полный дилетант в программировании. Просто поделюсь некоторыми наработками и особенностями именно ESP-8266 ДЛЯ ЧАЙНИКОВ.

    Если мои заметки будут полезны и профессионалам - будет еще лучше.

    Вот rkit тут код ваяет - оно нужно самоделкиным так глубоко Си понимать? Но без этого глубокого понимания приличный код на Сях не написать.

    Луа гораздо лучше подходит для непрофессионалов - требует меньше знаний для решения типовых задач. Да и JS на espruino есть гуд.

    А сравнивать языки... ну нашли специалиста. Я могу только подтрунивать над ";" :)
     
    Последнее редактирование: 3 авг 2017
  7. b707

    b707 Гуру

    Нет, я не профессиональный программист. Я никогда не работал в IT или в разработке софта. Программирование - мое хобби, я пишу для себя. Правда делаю это очень давно, поэтому за это время научился мимикрировать под крутого кодера и узнал некоторые "правильные вещи" :)
     
  8. Igor68

    Igor68 Гуру

    Вы забыли.... впрочем как и я сначала. А где этот параметр "p" определён?
    Код (C++):

    #include <stdio.h>

    char dd[32];

    int main(int argc, char **argv)
    {
       char *p = &dd[0];
       sprintf(p, "car", 3);
       p[2] = 'd';
       printf("string:\"%s\"\n", p);
       return 0;
    }

     
    А тупое происвоение не прокатит, так как является частью кода... а он сам себя не поменяет. Особенно есл это всё в контрллере... в проекте Keil для ADuC7024 (ARM7TDMI)... происходит просто присвоение адреса параметру *p того места, где находится слово "car" в прошивке после компиляции. Понятно что это место изменяться выполнением программы просто так не выйдет.
     
    Последнее редактирование: 3 авг 2017
  9. b707

    b707 Гуру

    Вот так все работает. только что проверил на gcc 4.7.2
    Код (C++):

    void main()
    {
      char p[] = "car";

      2[p] = 'd';

      printf("%s\n", p);
    }
     
  10. SergeiL

    SergeiL Оракул Модератор

    Ну, это похоже особенность gcc...
    Проверил в Microsoft - все работает:

    Код (Text):
    C:\C600\zzz>
    C:\C600\zzz>type 2.c
    #include <stdio.h>

    void main()
    {
      char *p = "car";

      2[p] = 'd';

      printf("%s\n", p);
    }
    C:\C600\zzz>
    C:\C600\zzz>cl /AT /Fa 2.c
    Microsoft (R) C Optimizing Compiler Version 6.00
    Copyright (c) Microsoft Corp 1984-1990. All rights reserved.

    2.c

    Microsoft (R) Segmented-Executable Linker  Version 5.10
    Copyright (C) Microsoft Corp 1984-1990.  All rights reserved.

    Object Modules [.OBJ]: C:\C600\LIB\CRTCOM.LIB +
    Object Modules [.OBJ]: "2.obj" /farcall
    Run File [C:CRTCOM.exe]: "2.com" /noi /noe /tiny
    List File [NUL.MAP]: NUL
    Libraries [.LIB]:
    Definitions File [NUL.DEF]: ;

    C:\C600\zzz>2.com
    cad

    C:\C600\zzz>type 2.asm
    ;       Static Name Aliases
    ;
            TITLE   2.c
            .8087
    INCLUDELIB      SLIBCE
    _TEXT   SEGMENT  WORD PUBLIC 'CODE'
    _TEXT   ENDS
    _DATA   SEGMENT  WORD PUBLIC 'DATA'
    _DATA   ENDS
    CONST   SEGMENT  WORD PUBLIC 'CONST'
    CONST   ENDS
    _BSS    SEGMENT  WORD PUBLIC 'BSS'
    _BSS    ENDS
    DGROUP  GROUP   CONST, _BSS, _DATA
            ASSUME DS: DGROUP, SS: DGROUP
    EXTRN   __acrtused:ABS
    EXTRN   _printf:NEAR
    EXTRN   __aNchkstk:NEAR
    _DATA      SEGMENT
    $SG166  DB      'car',  00H
    $SG167  DB      '%s',  0aH,  00H
    _DATA      ENDS
    _TEXT      SEGMENT
            ASSUME  CS: _TEXT
    ; Line 1
    ; Line 4
            PUBLIC  _main
    _main   PROC NEAR
            push    bp
            mov     bp,sp
            mov     ax,2
            call    __aNchkstk
    ;       p = -2
    ; Line 7
            mov     BYTE PTR $SG166+2,100
    ; Line 9
            mov     ax,OFFSET DGROUP:$SG166
            push    ax
            mov     ax,OFFSET DGROUP:$SG167
            push    ax
            call    _printf
    ; Line 10
            mov     sp,bp
            pop     bp
            ret
            nop

    _main   ENDP
    _TEXT   ENDS
    END

    C:\C600\zzz>
    Прокатит - p присваивается адрес строки с нулем в конце из сегмента данных. См. ассемблерный листинг.
     
  11. Igor68

    Igor68 Гуру

    Работает... не спорю. Вы же совсем без указателя.
     
  12. b707

    b707 Гуру

    Кстати. ответ, почему здесь получается сегментэйшен, а в случае char p[] - нет, находится в Гугле на раз. Для gcc запись char *p = "car"; означает строковую константу, а char p[] - переменную. При попытке изменения константы происходит крах, это логично
     
  13. Igor68

    Igor68 Гуру

    Ещё мне как серпом... вот такое в этом случае, когда совсем без указателя
    Код (C++):

    printf("%s\n", p);
     
    обычно для строки без указателя делаю (напрямую)
    Код (C++):

    printf("%s\n", &p[0]);
     
     
  14. Igor68

    Igor68 Гуру

    Да никто не спорит... просто пример был не корректен. Для записи не порректен.
     
  15. SergeiL

    SergeiL Оракул Модератор

    Мне кажется, это уже перестраховка.
    В Си как не работай со строками - это все работа с указателями на память, где уже и лежат данные.
    Код (C++):

    char buff[] = "Test";
    char *p;

    p=buff;

    printf("%s\n", p);
    или
    printf("%s\n", buff);
    Абсолютно нормальная запись, оба варианта.
     
  16. AlexU

    AlexU Гуру

    Segmentation fault -- причин может быть несколько, но в данном попытка записи в память, защищённую от записи.
    Это особенность не компилятора, а Windows. rkit тестировал пример в Linux, а в нём страницы памяти с кодом программы защищены от записи. Если память не изменяет, эта защита реализована на уровне железа -- блок управления памятью в процессоре следит за корректностью доступа к страницам памяти. В Windows похоже забили на этот механизм защиты.
    Если воспользоваться предложением Igor68, то всё работает:
    Код (C++):
    #include <stdio.h>
    #include <stdlib.h>


    int main() {

        char pp[] = "car";
        char *p = pp;

        printf("%s\n", p);

        2[p] = 'd';

        printf("%s\n", p);

        return EXIT_SUCCESS;
    }
    В данном случае массиву выделяется память в стеке функции 'main()', который доступен на чтение и запись, и указатель указывает на этот участок памяти. Вывод программы будет следующим:
    Код (Bash):
    car
    cad
     
    Если использовать конструкцию:
    Код (C++):
    char *p = "car";
    То указатель будет указывать на участок памяти, находящейся в странице защищённой от записи. Вот отсюда и Segmentation fault.
     
    SergeiL нравится это.
  17. Igor68

    Igor68 Гуру

    Не спорю... ведь работает. Вы приводите два примера... я вижу их разными
    Код (C++):

    char buff[] = "test";
    printf("%s\n", &buff[0]);
     
    Это было напрямую

    Код (C++):

    char buff[] = "test";
    char *p;
    *p=&buff[0];
    printf("%s\n", p);
     
    это было по указателям

    Вызываемые функции чту... вообще-то Вы правы. Работает. Но зачем приставать с синонимами? Бегемот и Гипопотам одно и тоже, но для меня разные... видите ли читаются по пазному... хотя и одно и то же. Я же Вас не упрекаю за ваши вредные привычки. Почитаю бывает отчёт вывода компилятора... вроде всё правилно и работает как надо... но пристаю к его предупреждениям. Потому и высказываюсь.
     
  18. b707

    b707 Гуру

    Это одно и тоже, причем первый вариант на самом деле куда больше распространен. Имя массива есть указатель на нулевой элемент. Вся обработка строк в традиционном Си делается через арифметику указателей, где используется именно имя массива, а не неуклюжая конструкция типа &p[0]
     
  19. Igor68

    Igor68 Гуру

    Странно!!!:confused: Думал что сказал, а оказывается промолчал... А понял!:) Лиш бы потрещать!:D
     
  20. b707

    b707 Гуру

    ИМХО, не наставиваю... но по-моему, ваш вариант читается хуже