Несовместимость типов данных: Error:invalid conversion from 'int' to 'const char*'

hacker_007
Offline
Зарегистрирован: 14.04.2015
#include <VirtualWire.h>
 
const int led_pin = 13;
const int transmit_pin = 12;
 
void setup() 
{ 
  vw_set_tx_pin(transmit_pin); 
  vw_setup(2000);
  pinMode(led_pin, OUTPUT); 
  Serial.begin(9600);
}
 
void loop() 
{ 
  if (Serial.available() > 0) {
        const char *msg = Serial.read();
        digitalWrite(led_pin, HIGH);
        vw_send((uint8_t *)msg, strlen(msg));
        vw_wait_tx();
        digitalWrite(led_pin, LOW);
        Serial.print("Send: ");
        Serial.println(msg);
        delay(1000);
    }
  }

Ошибка:

In function 'void loop()':

error: invalid conversion from 'int' to 'const char*' [-fpermissive]



Я запутался уже короче))) Понимаю, что несовместимость типов... Но как это поправить. Много его перепробовал(

GraninDm
Offline
Зарегистрирован: 01.08.2013

Serial.Read() возвращает int, а не указатель на char

Returns

the first byte of incoming serial data available (or -1 if no data is available) - int

hacker_007
Offline
Зарегистрирован: 14.04.2015

Я понимаю это. Я не знаю как сопоставить, чтобы не было этой ошибки. 

GraninDm
Offline
Зарегистрирован: 01.08.2013

int ch = Serial.read();

А уже дальше как то запихнуть ch в vw_send правильно его преобразовав.

hacker_007
Offline
Зарегистрирован: 14.04.2015

При таком раскладе, весь вопрос сводится к строке:

vw_send((uint8_t *)msg, strlen(msg));

Я много чего пробовал уже. Ни как не пойму как лучше сделать.

GraninDm
Offline
Зарегистрирован: 01.08.2013
std
Offline
Зарегистрирован: 05.01.2012
Вроде так:
if (Serial.available() > 0) {
        char* msg;
        int imsg = Serial.read();
        sprintf(msg, "%d", imsg);
        digitalWrite(led_pin, HIGH);
        vw_send(&msg, strlen(msg));
        vw_wait_tx();
        digitalWrite(led_pin, LOW);
        Serial.print("Send: ");
        Serial.println(msg);
        delay(1000);
    }
  }

Но хз, понравится ли массив char функции Serial.println()

 

X-Dron
Offline
Зарегистрирован: 24.01.2015

Или на основе такого:

    #include <VirtualWire.h>
    String message;
     
    void setup()
    {
      Serial.begin(9600);
    }
     
    void loop()
    {
      while (Serial.available()) {  
        char incomingChar = Serial.read();
        if (incomingChar != '\n') {
          message += incomingChar;
        } else {
          char buf [message.length()]; 
          message.toCharArray(buf, message.length());
          vw_send((uint8_t*)buf,sizeof(buf));
          vw_wait_tx();
          message = "";
        }
      }
    }

 

hacker_007
Offline
Зарегистрирован: 14.04.2015
#include <VirtualWire.h>

const int led_pin = 13;
const int transmit_pin = 12;
char msg[10];

void setup() 
{ 
  vw_set_tx_pin(transmit_pin); 
  vw_setup(2000);
  pinMode(led_pin, OUTPUT); 
  Serial.begin(9600);
}

void loop() 
{ 
  if (Serial.available() > 0) {
        msg[0] = Serial.read();
        digitalWrite(led_pin, HIGH);
        vw_send((uint8_t *)msg, strlen(msg));
        vw_wait_tx();
        digitalWrite(led_pin, LOW);
        Serial.print("Send: ");
        Serial.println(msg);
        delay(1000);
    }
  }

Получилось)

X-Dron
Offline
Зарегистрирован: 24.01.2015

А если ввести в строке, скажем 5 символов и надать энтер, то передаваться они будут посимвольно с паузами в секунду? Железа под рукой нет. Проверить не могу.
Serial.read() возвращает только один символ, и в msg строка не формируется, используется только нулевой символ.

так посылает целиком введенную строку

#include <VirtualWire.h>
String message;
const int led_pin = 13;
const int transmit_pin = 12;

void setup()
{
  vw_set_tx_pin(transmit_pin);
  vw_setup(2000);
  pinMode(led_pin, OUTPUT);
  Serial.begin(9600);
}
	 
void loop()
{
  while (Serial.available()) { 
    char incomingChar = Serial.read();
    if (incomingChar != '\n') {
      message += incomingChar;
      digitalWrite(led_pin, HIGH);
    } else {
      message +='\0';
      char buf [message.length()];
      message.toCharArray(buf, message.length());
      vw_send((uint8_t*)buf,sizeof(buf));
      vw_wait_tx();
      digitalWrite(led_pin, LOW);
      Serial.print("Send: ");
      Serial.println(buf);
      message = "";
    }
  }
}

 

saftik
Offline
Зарегистрирован: 08.04.2015

я  новичек и мое замечание может быть ошибочным,

но выражу свое мнение,

error: invalid conversion from 'int' to 'const char*'
в моём  понимании фраза означает: что из переменной int не может перейти в переменную char

читал что приставка const указывает на то что значение не может изменяться в процессе работы программы,

мне кажеться надо либо убрать const либо заменить другой переменной.

я совсем не програмист и только начинаю изучать, но думаю стоит попробовать мой вариант

 

 

hacker_007
Offline
Зарегистрирован: 14.04.2015

Всем спасибо, ребят) Все варианты хороши) На счет отправки символа по одному, для меня не так важно) Но все равно спасибо)

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Такое впечатление, что никто не умеет программировать, 99% примеров некорректны. Одни примеры описывают указатель без выделения памяти по буфер, другие расходуют память, как будто там её море.
Не нравится? Объяснить ошибки?

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

нравится... моя бы послушал про ошибки ! :)   ( из-за одного - не нано )
"Век учись - всё равно дураком помрёшь !"

....в смысле - всем желаю здоровья !

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

Такое впечатление, что никто не умеет программировать, 99% примеров некорректны
....Я БЫ ПОПРОСИЛ !!!!!!! миня вычеркни - будет 98% !!!!!!!!!!!!!!!!!!!
:)-

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

std пишет:

Вроде так:
if (Serial.available() > 0) {
        char* msg;
        int imsg = Serial.read();
        sprintf(msg, "%d", imsg);
        digitalWrite(led_pin, HIGH);
        vw_send(&msg, strlen(msg));
        vw_wait_tx();
        digitalWrite(led_pin, LOW);
        Serial.print("Send: ");
        Serial.println(msg);
        delay(1000);
    }
  }

Но хз, понравится ли массив char функции Serial.println()

 

Ошибка в строке 4 (проявится в строке 4), потому что msg - указатель и он не проинициализирован ничем. Значит писать будет куда попало. Считайте как русская рулетка, кому то повезет, а кому то нет.

 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

X-Dron пишет:

Или на основе такого:

    #include <VirtualWire.h>
    String message;
     
    void setup()
    {
      Serial.begin(9600);
    }
     
    void loop()
    {
      while (Serial.available()) {  
        char incomingChar = Serial.read();
        if (incomingChar != '\n') {
          message += incomingChar;
        } else {
          char buf [message.length()]; 
          message.toCharArray(buf, message.length());
          vw_send((uint8_t*)buf,sizeof(buf));
          vw_wait_tx();
          message = "";
        }
      }
    }

 

Ошибка в строке 16, нельзя создать массив с неизвестной на этапе компиляции длиной. Поэтому char buf[ message.length() ] просто не скомпилируется. В добавок в этом примере используется ДВА буфера памяти. Один в String, другой в buf. Накладно.

UPD:

Конструкция char msg[message.length()] является расширением gcc, потому не соответствует стандартам.
Данный массив создается на стеке, как и положено, однако никаких проверок и т.п. не производится.
В общем можно пользоваться на свой страхи и риск. Я же буду знать и обходить стороной.

 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

hacker_007 пишет:

#include <VirtualWire.h>

const int led_pin = 13;
const int transmit_pin = 12;
char msg[10];

void setup() 
{ 
  vw_set_tx_pin(transmit_pin); 
  vw_setup(2000);
  pinMode(led_pin, OUTPUT); 
  Serial.begin(9600);
}

void loop() 
{ 
  if (Serial.available() > 0) {
        msg[0] = Serial.read();
        digitalWrite(led_pin, HIGH);
        vw_send((uint8_t *)msg, strlen(msg));
        vw_wait_tx();
        digitalWrite(led_pin, LOW);
        Serial.print("Send: ");
        Serial.println(msg);
        delay(1000);
    }
  }

Получилось)

Здесь рассчет на то, что переменные инициализированы. Дело хозяйское, однако до определенного момента, когда это не сработает и придется искать баг долго, а такие баги найти не всегда легко.

Хотя бы в setup записать в msg[1] = '\0' или при описании проинициализировать, типа char msg[] = " ";

Хотя данный вариант самый близкий и простой, можно считать его почти корректным.

 

X-Dron
Offline
Зарегистрирован: 24.01.2015

kisoft

kisoft пишет:
нельзя создать массив с неизвестной на этапе компиляции длиной. Поэтому char buf[ message.length() ] просто не скомпилируется.

а как же

kisoft пишет:

при описании проинициализировать, типа char msg[] = " ";

Здесь тоже массив неизвестной на момент компиляции длинны.

 

Как ни странно, но скетч компилится и работает.
Второй буфер нужен для преобразования типов String и string. :)
char buf - локальный и не статик, уничтожается сразу после выхода из else
 

X-Dron
Offline
Зарегистрирован: 24.01.2015

Про тот в котором "Получилось"
Скажите, а зачем нужен массив msg[10], если работа все время идет только с нулевым элементом массива, остальные даже не затрагиваются, не заполняются и не используются?
Разницу  в выполнении моего кода и "Получилось" оцените, когда зальете скетч в ардуино и введете, хотя бы пару символов в мониторе.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Все ж таки есть обиженные.
Про char msg[] = " "; спасибо, улыбнуло. Про скорость работы скетчей, так это нивелируется убиранием delay(1000). Или добавьте в свой delay, а то как то нечестно сравнивать.
Про char msg[ message.length() ], пожалуй посмотрю, кто же накосячил, я или оптимизатор.
А использовать два буфера в мк, где памяти мало - не есть хорошо. Да и зачем, если достаточно одного.

X-Dron
Offline
Зарегистрирован: 24.01.2015

kisoft пишет:
. Да и зачем, если достаточно одного.

Попробуйте, если достаточно, скормить целую строку введенную с терминала в функцию vw_send(). При этом вся строка должена передаваться одним вызовом vw_send().
Мне будет интересно поучиься.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

X-Dron пишет:

kisoft пишет:
. Да и зачем, если достаточно одного.

Попробуйте, если достаточно, скормить целую строку введенную с терминала в функцию vw_send(). При этом вся строка должена передаваться одним вызовом vw_send().
Мне будет интересно поучиься.

Привожу простой пример того, что я имел в виду. В примере вместо использования vw_send я вывожу в Serial, поскольку это не принципиально куда выводить, можно с тем же успехом вывести и в vw_send, при этом даже можно будет буфер сделать короче на один символ, т.е. не понадобится добавлять в конец буфера символ завершения строки '\0'. А длину взять непосредственно из message_buffer_index.

#define MAX_MESSAGE_BUFFER_LEN (20)

/* Буфер для получения строки из Serial. +1 для добавления '\0' в конец буфера. */
char message_buffer[MAX_MESSAGE_BUFFER_LEN + 1];
byte message_buffer_index = 0;

/* Признак прихода всей входящей посылки */
bool messageIsComplete = false;

void setup() {
  Serial.begin(57600);
  /* Только для Леонардо */
  while(!Serial) {}
}

void loop() {
  if(messageIsComplete) {
    Serial.println(message_buffer);
    messageIsComplete = false;
    message_buffer_index = 0;
  }
}

/* Стандартный обработчик данных с Serial. Пример есть в ArduinoIDE, в каталоге examples */
void serialEvent() {
  while(Serial.available()) {
    char l_InChar = Serial.read();
    /* Записываем в буфер все данные до получения символа '\n' */
    if('\n' != l_InChar) {
      /* Записываем данные в буфер только если в нем еще есть место */
      if(message_buffer_index < MAX_MESSAGE_BUFFER_LEN) {
        message_buffer[message_buffer_index] = l_InChar;
        message_buffer_index++;
      }
      else {
        /* Здесь можно сделать выход по переполнению буфера или установить флажок ошибки. */
        #ifdef EXIT_ON_OVERFLOW
        message_buffer[message_buffer_index] = '\0';
        messageIsComplete = true;
        break;
        #endif
      }
    }
    else
    {
      message_buffer[message_buffer_index] = '\0';
      messageIsComplete = true;
      break;
    }
  }
}

Пример он и есть пример, здесь нет обработки ошибок и т.п. Т.е. он далек от идеала. Но как пример использования одного буфера на две задачи (прием данных и отправка их в другую систему) вполне сгодится. В реальной жизни придется озаботиться еще и остатком данных в Serial и некоторыми другими вещами, но это уже совсем другая история.
Я писал раньше и сейчас повторю, что использование String не является ошибкой, но для данной задачи, на мой взгляд это избыточность. Хотя в примере serialEvent используется именно String. Впрочем задачу ТС мы не знаем, потому вопрос философский.

Да, я выше в своем сообщении добавил результат "разборок" с char msg[message.length()], остальной текст сообщения не трогал. Краткое резюме: gcc имеет такое расширения языка, но оно не является стандартным на данный момент, т.е. пользоваться можно, однако не стоит забывать, что стек не резиновый и такой массив в стеке займет неизвестно сколько места, что чревато сюрпризами.

UPD: По поводу String. Я посмотрел исходники, там ничего особенного, могу только порекомендовать использовать метод reserve для того, чтобы заранее выделить место в этой строке, чтобы оно в дальнейшем не перераспределялось при операциях типа 'str += "message";'. Для тех, кто использует STL, понятно, этот тип данных удобней, но использование в нем realloc для МК болезненно, что тоже понятно.

 

X-Dron
Offline
Зарегистрирован: 24.01.2015

Принцип понятен, спасиб. У каждого метода есть свои достоинства и недостатки. И перименять из нужно исходя из конкретной задачи.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

X-Dron пишет:

Принцип понятен, спасиб. У каждого метода есть свои достоинства и недостатки. И перименять из нужно исходя из конкретной задачи.

Это да, тут уже только опыт поможет, использовать то, что нужно в нужном месте. Ну и задача должна быть точно сформулирована, наче можно и из пушки по воробьям.

 

hacker_007
Offline
Зарегистрирован: 14.04.2015

Итог. Код X-Dron данные не отправляет. Собрал по примеру kisoft. Все нормально работает)

std
Offline
Зарегистрирован: 05.01.2012

kisoft пишет:
Ошибка в строке 4 (проявится в строке 4), потому что msg - указатель и он не проинициализирован ничем. Значит писать будет куда попало.

А как правильно? Для меня указатели - отнюдь не оккультные арканы, но опыта таки мало. Поэтому и с трансиверами Нордика работаю на библиотеке MIRF, а не RF24. Просто в силу наличия в коде RF24 махинаций с памятью, которые мне непонятны.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

std пишет:

kisoft пишет:
Ошибка в строке 4 (проявится в строке 4), потому что msg - указатель и он не проинициализирован ничем. Значит писать будет куда попало.

А как правильно? Для меня указатели - отнюдь не оккультные арканы, но опыта таки мало. Поэтому и с трансиверами Нордика работаю на библиотеке MIRF, а не RF24. Просто в силу наличия в коде RF24 махинаций с памятью, которые мне непонятны.

Указатели, массивы - это детская болезнь любого человека, изучающего С (UPD: я лично по этим граблям тоже прогулялся ;) ). Потому дальше только о массивах и указателях, именно в таком контексте. И да, речь про переменные в ОЗУ.

Можно начать с того, что любая переменная получет своё место в ОЗУ. Размер этого места зависит от размера этой переменной. Т.о. если есть массив uint16_t array[5];, то для него в ОЗУ выделяется места 10 байт. Как считается? Просто. Размер одного элемента умножить на количество элементов. В данном случае uint16_t - два байта и всего 5 элементов. 5 * 2 = 10.

Теперь указатели. Это тоже переменная. Её размер зависит от системы (МК). У нас это uint16_t, т.е. беззнаковое целое, размером два байта. Еще раз. Указатель - это в нашем контексте (!) всегда два байта. И это всё. Сам по себе он занимает место, а содержит он адрес какой то другой области памяти (как в ОЗУ, так и во флеше, как использовать).

Совместим массивы и указатели в следующем фрагменте:

uint8_t array1[16] = { 0, 1, ... 15 };
uint8_t *pointer;

...
memcpy(pointer, "FILLER", 6);
....

куда попадут данные? Ответ простой, неизвестно. Теперь сразу другой пример:

uint8_t array1[16] = { 0, 1, ... 15 };
uint8_t *pointer;

...
pointer = array1;
memcpy(pointer, "FILLER", 6);
....

куда попадут данные? Теперь это очевидно, что в array1

Еще пример, но он не очень хороший, только в учебных целях:

uint8_t array1[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
uint8_t array2[3] = { 0, 1, 2 };
uint8_t *pointer;

...
pointer = array1;
memcpy(pointer, "FILLER", 6);
pointer = array2;
memcpy(pointer, "OUT", 3);
....

Здесь символы 'F', 'I', 'L', 'L', 'E', 'R' попадут в array1, а 'O', 'U', 'T' в array2. Однако использовать указатель для разных областей не очень хорошая практика. Можно нарваться на кучу проблем, но это совсем другая история.

Кстати, о практике, последние два примера можно на камне покрутить, вывести в Serial содержимое массивов до и после выполнения копирования.

Итак, мы теперь знаем, что указатель, это переменная, которая хранит адрес какой то области памяти и если её (переменную) не проинициализировать, то указатель будет указывать на неопределенное место.

Это в двух словах, если что непонятно, поясню.

 

std
Offline
Зарегистрирован: 05.01.2012

kisoft

Как такое возможно, что

pointer = array1;

?

Разве не должно быть знака *? Или это и есть та самая сакральная магия, типа присвоили указателю массив и он получил адрес первого байта? Или переменная массива, то есть array[], но без квадратных скобок - это и есть собственно указатель, то есть адрес первого байта? Я подозреваю второе, но пока непонятно.

Заодно ещё один вопрос, который давно не даёт мне покоя и тоже выглядит магией. Чем отличается uint8_t от byte (неподписанная 8-битная переменная, то бишь байт); чем отличается uint16_t от unsigned int (неподписанная 16-битная переменная, или int, два байта)? Не? Ну серьёзно, поджечь спичку или повысить её температуру до ~3000°C? Вот ведь непростой выбор...

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

А что по вашему массив ? Массив цепочка последовательных данных начинающаяся с адреса. Поэтому компилятор понимает pointer=array, а вот в случае с array[0], такое не пройдет, тут надо pointer=*array[0] .

А uint8_t  и uint16_t , я так думаю наследие от AVR си. Ну любят микропрограмеры ;) именовать типы данных по количеству бит. А unsigned char, byte и unsigned int это исконно сишные типы. Кстати меня больше занимает что есть unsigned char, что в переводе означает беззнаковый символ :), то есть обычный символ может иметь знак !!! Чего в природе не встречается. 

 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Да, сразу про опечатку в тексте brokly:

pointer=*array[0]; // некорректно
pointer = &array[0]; // верно
 
Теперь о другом, попробуем рассмотреть проблему с разных сторон:
uint8_t array1[3] = { 1, 2, 3 };
uint8_t *array2 = array1;

Т.е. это как бы одно и тоже, array1 и array2, но это на первый взгляд. Хотя, сначала об одинаковости. Что такое массив - это набор элементов, т.е. это элементы, расположенные в памяти последовательно, т.е. один за другим. Что такое указатель, это адрес элементов, расположенных в памяти последовательно. Одинаково? Ну да, это одно и то же, почти. Однако разница всё таки есть. Массив, как правило, это всё таки определенное количество элементов в памяти, а указатель, хранящий адрес этого массива (правильно, это адрес первого элемента массива), это указатель на элементы, но длина неизвестна. Это и есть основная разница. Разумеется существуют и массивы с динамической длиной, но это всего лишь указатели, а не массивы.

Для примера, у массива sizeof(array) - есть размер, а такой же sizeof для указателя не получить - размер неизвестен. Точнее сам указатель имеет размер и sizeof(pointer) выдаст, например, два (зависит от камня). В то же время sizeof(*pointer) будет далеко не равен sizeof(array). Можно легко попробовать.

Теперь о простых типах.

Если посмотреть определение, то:

typedef uint8_t byte; // см. файл Arduino.h

typedef unsigned char uint8_t; // см. файл stdint.h

typedef unsigned int uint16_t; // см. файл stdint.h

Теперь вопрос исчерпан? Отнюдь. Мы видим маленькую особенность, а именно, тип byte описан в Arduino.h, а компилятор такого типа не имеет. И наоборот, тип uint8_t описан в компиляторе, но в arduino используется готовый тип. Это значит что? Что uint8_t можно использовать в gcc-avr и "ArduinoIDE", а byte - только в "ArduinoIDE".

Скажу больше, в Visual Studio также можно использовать uint8_t, потому что он там тоже определен в файле stdint.h

Чем хорошо или плохо использование одного и того же типа byte & uint8_t? Переносимость. Использование одного и того же исходника в разных средах. О чем я? byte можно использовать только в wiring (ArduinoIDE), а uint8_t можно использовать и в компиляторе и в ArduinoIDE (и в Visual Studio тоже).

Думаю не надо объяснять, что лучше?

Хотя всё это философия, особо никто не будет писать программу в ArduinoIDE и потом переносить её в другие среды. Но в тоже время, я иногда пишу программы в Visual Studio, потом переношу их в скетчи, в ArduinoIDE.

Разумеется никто не запрещает в Visual Studio определить typedef uint8_t byte; и использовать byte вместо uint8_t.

По-поводу знаковости и беззнаковости char. Эмм.. На самом деле в компиляторах есть ключи, которые позволяют считать тип char беззнаковым. А еще, если почитать Microsoft, то можно увидеть странную фразу, что тип char имеет размер примерно один байт. Странно? Может быть, однако не совсем. ASCII, Unicode и т.п.

Короче, не вдаваясь в подробности не парьтесь на счет знаковости и беззнаковости char, просто используйте тот тип, который соответствует ситуации, а именно. Если данные имеют значения от 0 до 200, то храним их в типе uint8_t или byte. Это логично, потому что в char эти значения не влезут (только не надо говорить, что влезут, с приведением типов, конечно влезут, но я не об этом, приведение типов - это совсем и не всегда хорошо, как кажется).

Например, есть данные, где значения от -5 до +5. В каком типе хранить? В char? Можно, конечно, однако это не символьная информация, значит выбираем тип int8_t, т.е. знаковое и минимальный размер - один байт.

Другой пример, символы '0' - '9', 'A' - 'F'. Выбираем тип char, его достаточно для хранения таких данных.

Русские буквы. Не буду здесь писать про эту "проблему", потому что не хватит времени и буду это описывать до утра. Просто нужно помнить, что UTF-8 - это два байта на одну русскую буквы, а на латинскую - один байт. В то же время в 1251, что русские, что латинские - по одному байту на символ.

Уфф, утомил уже.

Если что то непонятно, лучше спрашивайте, может где и накосячил или не точно описал.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Да да, вечер засыпал уже :(

Вопрос знакового чара не раскрыт :) !  У компилятора есть всякие ключи, думаю можно найти и тот который сделает чар двухбайтовым. однако наличие знака у чара подразумевает использование его для математических операций, без приведения типа. По крайней мере в операциях сравнения это имеет большое значение. Короче знаковый чар это "непонятное чего то".

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

brokly, вот тут для Microsoft есть описание. Может Вас такой вариант объяснения устроит :) Меня этот вопрос не парит, потому копаться в доках у меня нет желания. Когда понадобится, тогда и пороюсь ;)

 

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

дык нет там никакого объяснения, есть лишнее подтверждение того, что занковый чар - бред :)

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

А кто утверждал обратное? :)

 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

brokly пишет:

дык нет там никакого объяснения, есть лишнее подтверждение того, что занковый чар - бред :)

наверное определений не хватило ? byte (беззнаковый) и char (беззнаковый) почти одно и тоже - 0..255

в Паскале есть определение целого ShortInt - -128..+127
в CPP это , наверное и будет - сигнетБайт или сигнетЧар ? - короткое целое....

если почитать Microsoft, то можно увидеть странную фразу, что тип char имеет размер примерно один байт. Странно?
....интерпретирую это примерно как = знаковый чар имеет размер 7/8 байта без учёта знака
кататак....

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

byte и unsigned char, всё таки не совсем одно и тоже, по смыслу. byte - это двоичная информация, а unsigned char - это символьная информация. И не важно, что byte это unsigned char по размеру. К примеру многие пишут: char_array[0] = 0; а я пишу char_array[0] = '\0'; Нет разницы? Да, по результату - нет, а когда читаешь исходник, разница видна сразу и ты точно знаешь, какого типа элементы массива char_array. Вот потому для меня есть разница где использовать byte, а где unsigned char.

 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

эт дааааа....
а анализ сравнительный byte и char ?
если unsigned char - неподписанный-беззнаковый , то char - подписанный-знаковый ?

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Да в общем, все, что строки, char, остальное byte.
Надо попробовать только сравнение char с Русскими буквами, не пробовал, отосплюсь, попробую

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Мне кажется байт это всё же не двоичные, а шестнадцатиричные данные :) 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Это что, юмор?

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

С чего вы взяли ? Двоичные данные и шестнадцетеричные вполне себе отдельно классифицируются. Вот такая запись данных :

byte b=0x33     ... тут 0x33 какое число, бинарное или все же HEX ?

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

скорее всего это число 60xAY ( в 60-тиричной системе счисления ) , т.е. - часовое , а не бинарное
:)

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

brokly пишет:

byte b=0x33     ... тут 0x33 какое число, бинарное или все же HEX ?

byte b=0b00110011    ... тут 0b00110011 какое число, HEX или все же бинарное?
А если так:   byte b=51, то вообще выходит десятичное!? о_0

А ещё можно так: uint8_t b=0x33,   uint8_t b=0b00110011,  uint8_t b=51

Собсно, не вижу разницы. Работать будет одинаково.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Гм...  Давайте определимся. Сначала мы начали отличать чар от остального. То есть закодированную запись символа мы обособили. " Шестнадцатеричная система счисления (шестнадцатеричные числа) — позиционная система счисления по целочисленному основанию 16. " (википедия). Мы можем легко преобразовать из char в byte или в десятичную систему или в двоичную, но... Для байта базовой системой является HEX, точнее байт - элементарная ячейка для записи HEX данных. Для двоичной системы "родной" ячейкой будет БИТ. Ну раз мы чар отделили.... Где ошибка в этих рассуждениях ?

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

а нет ошибки.... нужно отделить физическое представления числа в микросхемах ( там только 0 или 1 ) от виртуального представления в голове
в какой системе мы представляем число - МК по барабану , а нам проще - и запись короче, и для восприятия проще

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Физическое представление в рэа это вообше наличие или отсутствие определенного уровня на шине :) , в том числе и внутренней. А бывает еще и третье состояние - высокий импеданс.  

Во теперь в эту тему можно начинающих присылать, "почувствовать нашу любовь" :)

X-Dron
Offline
Зарегистрирован: 24.01.2015

Я бы наоборот сказал, что здесь все одна ошибка.
Во-первых "Для байта базовой системой является HEX" - абсурд. Максимальное значение одного байта даже не может быть представлено одной цифрой 16-тиричной записи. (FF)
Во-вторых идет путаница мягкого, теплого и легкого.
1.HEX, BIN, OCT - это форма записи/представления двоичного кода.
2.byte, bit, word - это единици информации
3.char, int, float - тип данных. Они придуманы в языках высокого уровня для контроля ошибок работы с данными на уровне компиляции. На ассемблере  это логическая интерпретация 2
Любой набор информации в памяти может быть отображен как в 1, так и в представлении типа данных(3)
Это как в термодинамике существует температура, объем, давление. Между ими есть определенные взаимосвязи, они влияют друг на друга. Но это разные величины и говорить, что температура это давление - чушь.
 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Согласен с X-Dron. Плюс когда я говорил про бинарную информацию, я и не представлял что кто то решит, что бинарная - это система представления.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

X-Dron пишет:

Во-первых "Для байта базовой системой является HEX" - абсурд. Максимальное значение одного байта даже не может быть представлено одной цифрой 16-тиричной записи. (FF)

Вот это не понял, перефразируйте, по возможности. В если переменная байт, то она не может отобразить 255 ?

Про теплое и легкое - не коректно. Температура и давление имеют четкую зависимость. Как байт и HEX. А вот теплое с легким не зависят друг от друга.

Ну и так, на всякий случай... Засуньте шестнадцатеричное значение в бит ;) А потом расскажите , что одно от другого не зависит :) 

PS Бинарная бывает только система представления... А что еще ?

PSS А ошибка это знаковый чар,  и не просто большая ошибка, это поток мысли...

step962
Offline
Зарегистрирован: 23.05.2011

brokly пишет:

PSS А ошибка это знаковый чар,  и не просто большая ошибка, это поток мысли...

Ну да, равно как и 8-битовые АЛУ, оперирующие в этими знаковыми и беззнаковыми чарами...