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

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Для 103-го вот такого стартапа достаточно. Не нужен в стартапе С++.

На ASM, кстати, можно немного сэкономить в размере, разместив DefaultHandler внутри таблицы векторов. Зацените.
Вложения
startup_stm32f103xb.s.txt
(6.64 КБ) 228 скачиваний
startup_iar_stm32f103x8.c
(6.2 КБ) 235 скачиваний
Реклама
Вымогатель припоя
Сообщения: 574
Зарегистрирован: Вт ноя 02, 2010 17:46:37

Сообщение pokk »

Что такое weak, alias ? Читал читал, но так и не дошло, что там происходит.
Смутные понимание, что типа каждая функция (NMI_Handler)

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

void NMI_Handler()                 __attribute__ ((weak, alias ("Default_Handler")));
По дефолту заменяется на Default_Handler, если она не объявлена пользователем.
Реклама
Первый раз сказал Мяу!
Аватара пользователя
Сообщения: 28
Зарегистрирован: Вс ноя 12, 2006 06:33:28
Откуда: Владивосток

Сообщение Allex »

В процессе творческого копипащенья одного кода, встретил такую функцию:

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

//========================
// Процедура смены местами 2 значений int16_t
//========================
static void SwapInt16Values(int16_t *pValue1, int16_t *pValue2)
{
  int16_t TempValue = *pValue1;
  *pValue1 = *pValue2;
  *pValue2 = TempValue;
}
ну и вызов, соответственно:

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

SwapInt16Values(&x1, &x2);
Скажите, а все вот эти упражнения со ссылками и указателями имеют практический смысл? В плане быстродействия, или может чего другого... Я б, как старый ардуинщик, написал бы в лоб:

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

void SwapInt16Values(int16_t pValue1, int16_t pValue2)
{
  int16_t TempValue = pValue1;
  pValue1 = pValue2;
  pValue2 = TempValue;
}
Чем это хуже?
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18795
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Allex писал(а):Чем это хуже?
тем, что это не работает
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="Allex",url="/forum/viewtopic.php?p=3616862#p3616862"]Я б, как старый ардуинщик, написал бы в лоб:[/uquote]
Ардуинщики пишут на С++, потому аргументы имеет смысл передавать как ссылки, что и делает стандартная функция swap, правда она еще и шаблонная:

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

void SwapInt16Values(int16_t& pValue1, int16_t& pValue2)
{
  int16_t TempValue = pValue1;
  pValue1 = pValue2;
  pValue2 = TempValue;
}
Реклама
Первый раз сказал Мяу!
Аватара пользователя
Сообщения: 28
Зарегистрирован: Вс ноя 12, 2006 06:33:28
Откуда: Владивосток

Сообщение Allex »

Вроде дошло.

void SwapInt16Values(int16_t& pValue1, int16_t& pValue2)

Просто меняем адреса переменных? Или не дошло?
Реклама
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1590
Зарегистрирован: Вс июн 24, 2012 16:07:00
Откуда: Лен.Обл.

Сообщение da-nie »

Чем это хуже?
Тем, что вы передаёте параметры по значению. То есть, в функцию попадают не внешние переменные, а только их значения. Если же передать по ссылке/указателю, то передаётся ссылка/указатель и вы получаете возможность менять значение переменных.
Просто меняем адреса переменных? Или не дошло?
Не адреса, а значения.
что и делает стандартная функция swap, правда она еще и шаблонная:
Вот тут не понял. Функция void SwapInt16Values(int16_t& pValue1, int16_t& pValue2) не шаблонная. 8)
И день и ночь в пути...
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos
Контактная информация:
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="da-nie",url="/forum/viewtopic.php?p=3616889#p3616889"]Вот тут не понял. Функция void SwapInt16Values(int16_t& pValue1, int16_t& pValue2) не шаблонная. 8)[/uquote]
Для SwapInt16Values я просты ссылки добавил, а std::swap() - шаблонная, но тут грузить еще и шаблонами никакого смысла нет :)
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18795
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

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

Мой уютный бложик... заходите!
Контактная информация:
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="ARV",url="/forum/viewtopic.php?p=3616906#p3616906"]а в контексте параметров функции какая разница между ссылкой и указателем? только что ссылка не может изменяться или еще какие-то нюансы есть?[/uquote]
Нюансы есть, например, по константной сылке можно передать временный объект:

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

set(Point{10, 20});
А указатель у него не возьмешь... Но изначально автора вопроса интересовало можно ли избавиться от указателей внутри функции, так что основная разница в упрощении.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18795
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Reflector писал(а):set(Point{10, 20});
то есть

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

set(&Point{10, 20});
недопустимо, если в set параметр указатель? интересно, почему? временный объект создается же в памяти, и имеет адрес... или опять нюансы?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="ARV",url="/forum/viewtopic.php?p=3616929#p3616929"]недопустимо, если в set параметр указатель? интересно, почему? временный объект создается же в памяти, и имеет адрес... или опять нюансы?[/uquote]
Когда-то читал, но сейчас точно не скажу, вроде дело в невозможности применять & к rvalue, а временные объекты как раз rvalue и есть.
Первый раз сказал Мяу!
Аватара пользователя
Сообщения: 28
Зарегистрирован: Вс ноя 12, 2006 06:33:28
Откуда: Владивосток

Сообщение Allex »

Не адреса, а значения.
Я правда хочу разобраться.

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

void SwapInt16Values(int16_t& pValue1, int16_t& pValue2)
Не означает ли эта запись, что внутри функции мы работаем с адресами переменных?
Друг Кота
Аватара пользователя
Сообщения: 4906
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

Это (в C++) означает, что переменная передана по ссылке. То есть, любые изменения её внутри функции изменяют оригинальную переменную извне. Внутри функции (с точки зрения синтаксиса) с этими переменными работать нужно ровно так же, как если бы они были переданы просто по значению.

P.S.
Спойлер

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

#include <iostream>

using namespace std;

void swap_c_style(int a, int b)
{
    int r = a;
    a = b;
    b = r;
}

void swap_c_pointer_style (int *a, int *b)
{
    int r = *a;
    *a = *b;
    *b = r;
}

void swap_cpp_style(int &a, int &b)
{
    int r = a;
    a = b;
    b = r;
}

int main()
{
    int x, y;

    x = 2; y = 3;
    swap_c_style(x, y);
    cout << "x: " << x << ", y: " << y << endl;

    x = 2; y = 3;
    swap_c_pointer_style(&x, &y);
    cout << "x: " << x << ", y: " << y << endl;

    x = 2; y = 3;
    swap_cpp_style(x, y);
    cout << "x: " << x << ", y: " << y << endl;

    return 0;
}
Вывод:

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

x: 2, y: 3
x: 3, y: 2
x: 3, y: 2
Последний раз редактировалось WiseLord Пн апр 15, 2019 12:21:47, всего редактировалось 2 раза.
Контактная информация:
Модератор
Аватара пользователя
Сообщения: 4618
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

[uquote="Allex",url="/forum/viewtopic.php?p=3616962#p3616962"]Не означает ли эта запись, что внутри функции мы работаем с адресами переменных?[/uquote]
Означает. Мы передаём константные адреса переменных, по которым работаем с самими переменными внутри функции.
Единственные, на мой взгляд, отличия от указателей - синтаксис и константность.
Прорезались зубы
Аватара пользователя
Сообщения: 211
Зарегистрирован: Пт окт 21, 2011 14:39:31

Сообщение FeCat »

Как создать и подключить .h и .с файлы? Как правильно?
Создаю timer8.c с реализацие функции, и создаю timer8.h с обьявлением функции. Кидаю в одну папку с main.cpp файлом.
В main в начале пишу:

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

#include "timer8.h"

Timer0Init();  // Timer0Init - обьявлен в timer8.h, и реализован в timer8.c
	
while(1)
{
 
}
В timer8.h обьявляю:

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

#ifndef __timer8_h__
#define  __timer8_h__

void Timer0Init(void);

#endif
В timer8.c пишу:

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

void Timer0Init(void)
{
   реализация Timer0Init
}
Как итог "undefined reference to `Timer0Init()'". Если в .h файле добавить "#include "timer8.c"" то ошибки нет. Но это же идеологически не правильно.
Пишу в AtmelStudio7.
Как правильно делать?
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18795
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

правильно:
1. не делать проекты без необходимости с исходниками одновременно С++ и С
2. добавлять исходники в проект средствами IDE
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Модератор
Аватара пользователя
Сообщения: 4618
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

FeCat писал(а):Кидаю в одну папку с main.cpp файлом.
1. Этого, наверное, мало. Нужно добавить исполняемый файл в проект.
2. Объявление в .cpp-файлах внешних функций, находящихся в .c-файлах нужно делать через обрамление в extern "C"{}
Прорезались зубы
Аватара пользователя
Сообщения: 211
Зарегистрирован: Пт окт 21, 2011 14:39:31

Сообщение FeCat »

[uquote="Аlex",url="/forum/viewtopic.php?p=3617081#p3617081"]Нужно добавить исполняемый файл в проект.[/uquote]
[uquote="ARV",url="/forum/viewtopic.php?p=3617076#p3617076"]добавлять исходники в проект средствами IDE[/uquote]
Т.е. это нормально-правильно, что если в майне есть инклюд .h файла, то .cpp автоматом к нему не подтягивается? Надо обязательно средствами IDE добавлять, а не из main или добавленных к main файлов. Далать "#include "timer8.cpp"" - вроде как не правильно?
Модератор
Аватара пользователя
Сообщения: 4618
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

FeCat писал(а):Т.е. это нормально-правильно, что если в майне есть инклюд .h файла, то .cpp автоматом к нему не подтягивается?
Да, нормально.
В любой IDE нужно добавлять ручками исходные файлы в проект.
Ответить

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