Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18797
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

isx писал(а):Это получается будет восемь строк (в каждой по одной структуре)?
нет, это одна строка для всех восьми структур, но это расширение синтаксиса Си только для компилятора GCC
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
AAX
Опытный кот
Сообщения: 721
Зарегистрирован: Сб ноя 16, 2013 23:34:34

Сообщение AAX »

[uquote="isx",url="/forum/viewtopic.php?p=3501356#p3501356"]Пробовал кучу вариантов, в том числе и такой в СИшном файле (который, как мне кажется, должен был работать):[/uquote]

Код: Выделить всё

All_ChannelData_t All_ChannelData = {
(ChannelData_t){
  1000,
  1000,
  1000,
  1000,
},
(ChannelData_t){
  1000,
  1000,
  1000,
  1000,
},
...
};
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4906
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

Можно ещё и так, чуть длиннее, без GCC-шного расширения в виде оператора ...:

Код: Выделить всё

    All_ChannelData_t All_ChannelData = {
        .ChannelData[0] = {
            1000, 1000, 1000, 1000,
        },
        .ChannelData[1] = {
            1000, 1000, 1000, 1000,
        },
        .ChannelData[2] = {
            1000, 1000, 1000, 1000,
        },
        .ChannelData[3] = {
            1000, 1000, 1000, 1000,
        },
        .ChannelData[4] = {
            1000, 1000, 1000, 1000,
        },
        .ChannelData[5] = {
            1000, 1000, 1000, 1000,
        },
        .ChannelData[6] = {
            1000, 1000, 1000, 1000,
        },
        .ChannelData[7] = {
            1000, 1000, 1000, 1000,
        },
    };
Контактная информация:
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18797
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

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

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
AAX
Опытный кот
Сообщения: 721
Зарегистрирован: Сб ноя 16, 2013 23:34:34

Сообщение AAX »

[uquote="ARV",url="/forum/viewtopic.php?p=3501507#p3501507"]все эти варианты не объясняют, почему у задавшего вопрос не проходит его вариант - он тоже корректный с виду[/uquote]все эти оба правильных варианта ;) инициализации вложенной структуры, как мне кажется, отлично объясняют, в чём проблема у задавшего вопрос: {1000,1000,1000,1000,} - с точки зрения компилятора это массив int[4], имеющий разительно отличаться от структуры из четырёх элементов int32_t. Мало того, даже если мы явно укажем элементам тип int32_t, что-то вроде {(int32_t)1000,(int32_t)1000,(int32_t)1000,(int32_t)1000,} всё равно будет разница в выравнивании элементов у массива и структуры.
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Код: Выделить всё

typedef struct
{
  int32_t       power;
  int32_t       energy;
  uint32_t      voltage;
  uint32_t      current;
} ChannelData_t;

typedef struct
{
  ChannelData_t ChannelData[8];
} All_ChannelData_t;

All_ChannelData_t All_ChannelData = {
  1001, 1002, 1003, 1004,
  2001, 2002, 2003, 2004,
  3001, 3002, 3003, 3004,
  4001, 4002, 4003, 4004,
  5001, 5002, 5003, 5004,
  6001, 6002, 6003, 6004,
  7001, 7002, 7003, 7004,
  8001, 8002, 8003, 8004
};
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18797
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

AAX писал(а):отлично объясняют, в чём проблема у задавшего вопрос: {1000,1000,1000,1000,} - с точки зрения компилятора это массив int[4], имеющий разительно отличаться от структуры из четырёх элементов int32_t
ерунду глалолить изволите.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
isx
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2316
Зарегистрирован: Вс июн 26, 2011 20:03:21

Сообщение isx »

Всех благодарю за помощь!
Прокатил вот такой вариант:

Код: Выделить всё

All_ChannelData_t  All_ChannelData= { 
  .ChannelData[0] = { 1000, 1000, 1000, 1000},
  .ChannelData[1] = { 1000, 1000, 1000, 1000},
  .ChannelData[2] = { 1000, 1000, 1000, 1000},
  .ChannelData[3] = { 1000, 1000, 1000, 1000},
  .ChannelData[4] = { 1000, 1000, 1000, 1000},
  .ChannelData[5] = { 1000, 1000, 1000, 1000},
  .ChannelData[6] = { 1000, 1000, 1000, 1000},
  .ChannelData[7] = { 1000, 1000, 1000, 1000},
};
В принципе, это тоже, что предлагал WiseLord
Сейчас разбираюсь с выравниванием структуры. Как оказалось, этот момент тоже может добавить щепотку геморроя в работу с кодом.
AAX
Опытный кот
Сообщения: 721
Зарегистрирован: Сб ноя 16, 2013 23:34:34

Сообщение AAX »

[uquote="ARV",url="/forum/viewtopic.php?p=3501526#p3501526"]ерунду глалолить изволите.[/uquote]извольте проглаголить истину, в таком раскладе. А то чот как-то... несерьёзно
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18797
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

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

Мой уютный бложик... заходите!
Контактная информация:
AAX
Опытный кот
Сообщения: 721
Зарегистрирован: Сб ноя 16, 2013 23:34:34

Сообщение AAX »

Сначала правильно объясните компилятору, какую переменную вы инициализируете. Си предоставляет программисту 100500 способов выстрелить себе в ногу.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18797
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

запись, приведенная isx в его сообщении, вполне соответствует требованиям инициализации структур, и поэтому я сказал, что не понятно, почему у него не получается.
в любом случае ваши объяснения проблемы, что константа int пишется в переменную uint32_t, и, якобы, вызывает какие-то проблемы с выравниванием или размещением в памяти - это ерунда.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
AAX
Опытный кот
Сообщения: 721
Зарегистрирован: Сб ноя 16, 2013 23:34:34

Сообщение AAX »

не "пишется", а вызывает ошибку в процессе компиляции. В вашей терминологии "не помещается" ;) Как вы, возможно, можете наблюдать, после явного указания типа инициализируемой переменной ошибка более не появляется. Возможно, мои объяснения - ерунда. Предложите, пожалуйста, правильное объяснение. Если для вас это по какой-то причине невозможно - просто помолчите в сторонке, пока кто-нибудь умный не объяснит.

Добавлено after 13 minutes 9 seconds:
я понял, в чём дело ;) всё действительно намного проще, чем я думал: нам нужно инициализировать структуру All_ChannelData_t, массив на 8 экземпляров ChannelData_t, и сами структуры ChannelData_t. "Просто добавь фигурные скобки" :)

Код: Выделить всё

	All_ChannelData_t All_ChannelData = { // All_ChannelData_t structure
		{ // ChannelData[8] array
			{ // ChannelData_t structure
			1000, 1000, 1000, 1000,
			},
				{
				1000, 1000, 1000, 1000,
			},
				{
				1000, 1000, 1000, 1000,
			},
				{
				1000, 1000, 1000, 1000,
			},
				{
				1000, 1000, 1000, 1000,
			},
				{
				1000, 1000, 1000, 1000,
			},
				{
				1000, 1000, 1000, 1000,
			},
				{
				1000, 1000, 1000, 1000,
			},
		}
	};
собственно, оно и ругалось на "too many initializers" - массив же один ;)
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18797
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

AAX писал(а):Возможно, мои объяснения - ерунда.
как вы сами доказали - таки да, ерунда
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Опытный кот
Аватара пользователя
Сообщения: 848
Зарегистрирован: Ср мар 02, 2011 07:47:39
Откуда: Уфа

Сообщение Psych »

Никто не знает почему
auto n=end(silo)-begin(silo);
Code blocks выдает int вместо ptrdiff_t.
Это от компилятора зависит?
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Что такое end, begin и silo нам предлагается угадать?

PS: auto удаляет ссылки, квалификаторы const и квалификаторы volatile. Не в этом дело?

Догадаемся, что речь идёт о std::end и std::begin

Определение в IAR
Спойлер

Код: Выделить всё

// TEMPLATE FUNCTION begin
template<class _Elem> inline
constexpr const _Elem *begin(initializer_list<_Elem> _Ilist) _NOEXCEPT
{       // get beginning of sequence
  return _Ilist.begin();
}

// TEMPLATE FUNCTION end
template<class _Elem> inline
constexpr const _Elem *end(initializer_list<_Elem> _Ilist) _NOEXCEPT
{       // get end of sequence
  return _Ilist.end();
}
Определение в GCC по сути то же самое
Спойлер

Код: Выделить всё

  /**
   *  @brief  Return an iterator pointing to the first element of
   *          the initializer_list.
   *  @param  __ils  Initializer list.
   */
  template<class _Tp>
    constexpr const _Tp*
    begin(initializer_list<_Tp> __ils) noexcept
    { return __ils.begin(); }

  /**
   *  @brief  Return an iterator pointing to one past the last element
   *          of the initializer_list.
   *  @param  __ils  Initializer list.
   */
  template<class _Tp>
    constexpr const _Tp*
    end(initializer_list<_Tp> __ils) noexcept
    { return __ils.end(); }
}
Посмотрим что такое ptrdiff_t

В IAR
Спойлер

Код: Выделить всё

/* type definitions */
#ifndef _PTRDIFF_T
  #define   _PTRDIFF_T
  #define   _STD_USING_PTRDIFF_T
  typedef   __PTRDIFF_T_TYPE__ ptrdiff_t;
#endif
В GCC
Спойлер

Код: Выделить всё

#ifndef __PTRDIFF_TYPE__
#define __PTRDIFF_TYPE__ long int
#endif
typedef __PTRDIFF_TYPE__ ptrdiff_t;
Псевдоним на базовый тип. Думаю, компилятор вполне закономерно взял базовый тип.
Последний раз редактировалось VladislavS Сб ноя 17, 2018 17:08:13, всего редактировалось 1 раз.
Опытный кот
Аватара пользователя
Сообщения: 848
Зарегистрирован: Ср мар 02, 2011 07:47:39
Откуда: Уфа

Сообщение Psych »

VladislavS писал(а):Догадаемся, что речь идёт о std::end и std::begin
Ну да.

Да черт с этими определениями.
Почему компилятор определяет неявно тип int вместо ptrdiff_t?

#include <cstddef>
#include <iterator>
using namespace std;

int main(int argc, char** argv) {
char silo[10];
auto n=end(silo)-begin(silo);
return 0;
}
тут n почему-то int
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="Psych",url="/forum/viewtopic.php?p=3506724#p3506724"]тут n почему-то int[/uquote]
Перед выполнением математических операций все приводится к одному типу и для целых это будет int, если его достаточно, т.е. даже 'A' + 1 дает int.
А, тут итераторы, тогда все зависит от перегрузки операторов, тем более в принципе ptrdiff_t как int и объявлен... Компилятор какой?
Последний раз редактировалось Reflector Сб ноя 17, 2018 17:14:38, всего редактировалось 1 раз.
Опытный кот
Аватара пользователя
Сообщения: 848
Зарегистрирован: Ср мар 02, 2011 07:47:39
Откуда: Уфа

Сообщение Psych »

[uquote="Reflector",url="/forum/viewtopic.php?p=3506728#p3506728"]Перед выполнением математических операций все приводится к одному типу и для целых это будет int, если его достаточно, т.е. даже 'A' + 1 дает int.[/uquote]
да, но тут вычитаются же указатели.
Компилятор игнорит стандарт чтоли?
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Тип то тут одинаковый. Но вступает в силу "арифметика указателей". Результат разности двух указателей это по классике будет int. Будет ли компилятор подбирать для него псевдоним ptrdiff_t ? Я бы не стал :)
Ответить

Вернуться в «Разные вопросы по МК»