LINUX.ORG.RU

Потому что строгая типизация, и потому что перегрузка функций.

А вдруг у тебя там рядом объявлена функций целочисленного квадратного корня, с тем же названием sqrt? И как тогда понять, какую вызывать?

Crocodoom ★★★★★
()
Ответ на: комментарий от somequest1

Анонiмус, антонимом термина «слабая типизация» является термин «строгая типизация», а что такое сильная типизация ты сейчас можешь поведать изумленной почтенной публике, если тебя не затруднит.

Virtuos86 ★★★★★
()
Ответ на: комментарий от Virtuos86

Ты начитался мурзилок, чувак.

Антонимом «слабая» является «сильная», и не только в программировании

somequest1
()
Ответ на: комментарий от somequest1

По твоей же ссылке, гений:

в языке со строгой типизацией разрешены только явные преобразования типов данных;

В фрагменте кода из ОП именно это и происходит - значение типа int явно приводится к типу double для передачи в функцию с сигнатурой <double>.

Virtuos86 ★★★★★
()
Ответ на: комментарий от Virtuos86

это лишь одна из интерпретаций.

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

somequest1
()
Ответ на: комментарий от somequest1

Не, вроде не про это. Я уже забфл, чего хотел. Так что, без комментариев :)

Deleted
()
Ответ на: комментарий от somequest1

С тобой в общем-то всё понятно. Я, пожалуй, перестаю комментировать твои перлы =)

Virtuos86 ★★★★★
()
Ответ на: комментарий от Crocodoom

Потому что строгая типизация, и потому что перегрузка функций.
А вдруг у тебя там рядом объявлена функций целочисленного квадратного корня, с тем же названием sqrt? И как тогда понять, какую вызывать?

Ну, там простой пример. Приведу полный код:

#include <iostream>
#include <cmath>
using namespace std;

int main()
{
    int num;
    double sq_root;
    
    for (num=1; num < 100; num++) {
        sq_root = sqrt((double) num);
        cout << num << " " << sq_root << '\n';
    }
    
    return 0;
}

Если KDevelop не обманывает, то в C++ есть такие функции для нахождения корня:

double sqrt(double x);
float sqrtf(float x);
long double sqrtl(long double x);
Значит, перегрузок функций нет.

Mg_usr
() автор топика
Ответ на: комментарий от Mg_usr

Значит, перегрузок функций нет.

Автор прививает тебе правильную культуру программирования на «крестах» (надеюсь ;).

Virtuos86 ★★★★★
()
Ответ на: комментарий от Mg_usr

Значит, перегрузок функций нет.

Сегодня нет - а завтра будет.

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

PS: ваш пример кода - это сишка, а не плюсы. Должно быть так:

int main()
{
    for (int num = 1; num < 100; num++) {
        const double sq_root = sqrt(num); // ну или auto
        cout << num << " " << sq_root << '\n';
    }
    
    return 0;
}

RazrFalcon ★★★★★
()
Ответ на: комментарий от Virtuos86

Автор прибивает тебе правильную культуру программирования на «крестах» (надеюсь ;).

Понял.:) А где про это ещё можно почитать?

Mg_usr
() автор топика
Ответ на: комментарий от Mg_usr

Не знаю. А вот как точно работает та или иная вещь в языке точно надо читать в стандарте C++. Финальные версии которого, правда, платные, но есть и предфинальные, которые практически ничем не отличаются, зато публикуются в открытом доступе, а значит, свободно доступны.

Virtuos86 ★★★★★
()
Ответ на: комментарий от RazrFalcon

ваш пример кода - это сишка, а не плюсы.

(пока) для меня они почти близнецы. :)

Должно быть так:

...
    for (int num = 1; num < 100; num++) {
        const double sq_root = sqrt(num); // ну или auto
...

Эм... Объявление переменной в середине цикла? Разве память не утекает?

Mg_usr
() автор топика
Ответ на: комментарий от Mg_usr

Вам ещё многое предстоит узнать...

А если вне цикла, то что не утекает? Вы же её в своём примере тоже не очищаете. Банальная логика же.

PS: нет, не утекает, ибо стек.

RazrFalcon ★★★★★
()
Ответ на: комментарий от RazrFalcon

ваш пример кода - это сишка, а не плюсы. Должно быть так

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

Главное различие между сями и крестами - в отсутствии в сях и в наличии в крестах ООП. Но тут ни в одном из вариантов ООП нет, да и не нужно оно для такого примера.

Так что всё нормально. :-)

aureliano15 ★★
()
Ответ на: комментарий от aureliano15

а можно и не использовать

То есть вы советуете создавать неинициализрованне переменные? Прекрасно.

для них одну переменную i немного эффективнее

Пару инструкций хоть сэкономлю?

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

Какой? Счётчика?

Да и читабельнее, имхо, когда все описания в одном месте

Пока прога из 10-и строк, наверное.

в отсутствии в сях и в наличии в крестах ООП

Клиника. Уносите.

RazrFalcon ★★★★★
()
Ответ на: комментарий от RazrFalcon

создавать неинициализрованне переменные?

А какая разница, где они инициируются, если это происходит до первого использования?

для них одну переменную i немного эффективнее

Пару инструкций хоть сэкономлю?

Так я и говорю, что «немного», а не «охрененно». Но тоже хлеб. :-)

требуется значение этой переменной вне тела цикла

Счётчика?

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

Да и читабельнее, имхо, когда все описания в одном месте

Пока прога из 10-и строк, наверное.

Ну да, на чистых сях ведь только такие и пишут. :-)

в отсутствии в сях и в наличии в крестах ООП

Клиника. Уносите.

Кого уносить в клинику? Страуструпа, называвшего си++ «си с классами»?

aureliano15 ★★
()
Ответ на: комментарий от aureliano15

если это происходит до первого использования?

Кто сказал? Valgrind? Но любителей писать падучий код уже не спасти.

чтоб узнать длину массива или узнать

std::vector

завершился ли цикл досрочно (брейком) или нет

быдлокод

Кого уносить в клинику?

Вас. У C и C++ общего очень мало. И ООП лишь маленькая доля.

RazrFalcon ★★★★★
()
Ответ на: комментарий от RazrFalcon

если это происходит до первого использования?

Кто сказал? Valgrind? Но любителей писать падучий код уже не спасти.

Хорошо, приведите мне реальный пример, где программа падала бы или работала некорректно из-за того, что переменные не были инициализированы сразу (но были инициализированы до первого использования).

чтоб узнать длину массива или узнать

std::vector

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

завершился ли цикл досрочно (брейком) или нет

быдлокод

Ну да, очень удобно всё, что не вписывается в ваши представления, называть быдлокодом. :-)

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

for(i=0; i<n; ++i)
  for(j=0; j<m; ++j)
     for(k=0; k<l; ++k)
     {
       // Здесь что-то делается
       if(!x)
         goto break_loop;
     }
break_loop:
// Продолжаем выполнение.

и он написал примерно такое:

flag=0;
for(i=0; i<n; ++i)
{
  for(j=0; j<m; ++j)
  {
     for(k=0; k<l; ++k)
     {
       // Здесь что-то делается
       if(!x)
         {
	   flag=1;
           break;
         }
     }
     if(flag)
       break;
  }
  if(flag)
   break;
}
// Продолжаем выполнение.

И переубедить его, что его флаг с 2 проверками на 1 в каждой итерации - костыль, совершенно не эффективный и не добавляющий читабельности, а скорее наоборот, так и не получилось. Просто он когда-то где-то прочитал, что метки это плохо, и готов был делать ещё хуже, но только без них. Для него, перефразируя вас, код с меткой - это быдлокод, а любой костыль, но без метки - верх изящества и совершенства. :-)

Вы так же рассуждаете?

Кого уносить в клинику?

Вас. У C и C++ общего очень мало.

Ну вот и я говорю: нас со Страуструпом, который называл си++ «сями с классами», подчёркивая т. о. сходство и упирая на главное различие: наличие классов (то бишь ооп).

И ООП лишь маленькая доля.

Да, ещё шаблоны и STL. Но, учитывая, что всё это тоже в основном на шаблонных классах, то получим всё то же ООП.

aureliano15 ★★
()
(double)

, C++, рукалицо. А нужно чтобы блин явно кастить лучше чем неявно, т.к если был бы класс а не int, то хрен его знает что у него в operator double() написано и лучше кастить явно.

lberserq
()
Ответ на: комментарий от aureliano15

такая разница что в нашей галактической дыре^W в x86 неинициализированные переменные помещаются в .bss и потом в них пишется значения, а инициализированные в .data и они уже в бинаре (разница правда скорее всего будет только на -O0 но разница там есть и может быть при разных профилях оптимизации)

lberserq
()

В C++ есть:

float       std::sqrt( float arg );
double      std::sqrt( double arg );
long double std::sqrt( long double arg );
double      std::sqrt( Integral arg );      // since C++11

Последняя функция приводит к double. Так как последней функции раньше в стандарте не было, то скорее всего были реализации, на которых std::sqrt(0) не компилировалось, отсюда и каст.

xaizek ★★★★★
()
Ответ на: комментарий от lberserq

неинициализированные переменные помещаются в .bss и потом в них пишется значения

В данном примере речь шла о не инициализированной локальной переменной.

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

aureliano15 ★★
()
Ответ на: комментарий от aureliano15

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

lberserq
()
Ответ на: комментарий от aureliano15

Страуструп же, по крайней мере в третьем издании TC++PL, говорит, что плюсы — мультипарадигмальный язык и ООП в нём не навязывается. И это действительно так.

evilface ★★
()
Ответ на: комментарий от lberserq

ну так это чисто стиль и красота

Ну, не знаю, что красивого в таком объявлении:

float arr[100]={0.0, 0.0, /*ещё 96 раз 0.0*/, 0.0, 0.0};

писать кучу переменных сверху блока никто не заставляет

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

aureliano15 ★★
()
Ответ на: комментарий от BruteForce

Ты и есть бред, парень

Это что, ночной бред или отладка нового бота на прохождение теста Тьюринга? Тест не пройден.

aureliano15 ★★
()
Ответ на: комментарий от evilface

плюсы — мультипарадигмальный язык и ООП в нём не навязывается.

Безусловно. Я этого и не отрицал. Но без ооп это просто слегка улучшенный си.

aureliano15 ★★
()
Ответ на: комментарий от aureliano15

В C99 можно float arr[100]={0.0}; Не помню можно ли в c89 или нет.

Но читать такую программу, имхо, удобнее, чем выискивать описания переменных.

А искать использование переменной при рефакторинге неудобнее, имхо, удобнее если объявление рядом с использованием. Но так, да это вкусовщина.

lberserq
()
Ответ на: комментарий от lberserq

В C99 можно float arr[100]={0.0}; Не помню можно ли в c89 или нет.

Можно и там, и там. Но при этом явно инициализируется только 1-й элемент, а остальные по умолчанию 0. Т. е. в данном случае разницы нет (как если и вообще ничего не писать), но если написать

float arr[100]={1.0};

То в 1 будет установлен только 0-й элемент, а остальные в 0. Т. е. это немного мошенничество. Если уж явно всё инициализировать, то все 100 элементов, а если не надо, так зачем 1-й явно инициализировать?

А искать использование переменной при рефакторинге неудобнее, имхо, удобнее если объявление рядом с использованием.

Не понимаю, чем удобнее. Вот чем удобнее описывать все переменные в начале блока, я могу объяснить: зайдя в блок, я сразу вижу все локальные переменные. Если я вижу где-то в середине или в конце блока использование переменной и хочу посмотреть её тип, я могу просто вернуться в начало блока и всё увижу.

Если же я ищу инициализацию переменной, то, нажав ctrl+f (или что-то ещё) и введя имя abc, какая мне разница, найду я

int abc=10;
или просто
abc=10;
?

aureliano15 ★★
()

На главный вопрос уже ответили, поэтому обращу внимание на другой момент: раз уж кастуешь именно в плюсах, используй static_cast, а не сишный:

int num;
double sq_root;
…
sq_root = sqrt(static_cast<double>(num));
В случае с int и double разницы не будет, но лучше сразу учиться делать правильно

XMs ★★★★★
()
Ответ на: комментарий от DELIRIUM

Так у std::array фиксированный размер. Зачем его считать?

RazrFalcon ★★★★★
()
Ответ на: комментарий от Virtuos86

в крестах c-style приведения считаютяс неЪ, там static cast есть.

Dark_SavanT ★★★★★
()
Ответ на: комментарий от aureliano15

что переменные не были инициализированы сразу (но были инициализированы до первого использования).

Мне картинку нарисовать, чтобы вы поняли суть вопроса?

А если у меня не вектор, а статический массив?

И вы не знаете размер статического массива? Что за бред?

Вы так же рассуждаете?

Вас понесло непонятно куда. Я считаю, что в данном случае лучше завести отдельный флаг, чем полагаться на счётчик.

При чём тут метки - не ясно. Их нету в C/C++.

нас со Страуструпом
нас

Корона не жмёт, ставиться себя на один уровень со Страуструпом?

Да, ещё шаблоны и STL.

А ещё исключения, constexpr, std (которого в С тупо нету), строгие касты, неймспейсы, auto, ссылки, нормальный const, статическая типизация, raii, ну и это не считая тонны фишек ООП. И это только то, что я сходу вспомнил.

на шаблонных классах, то получим всё то же ООП

Шта?! При чём тут шаблоны и ООП? Таблетки примите.

RazrFalcon ★★★★★
()

Функция принимает в качестве параметра double. Можно приведение не делать явно — компилятор сам справится. А можно делать. Это просто вопрос аккуратности.

JacobTwoTwo
()
Ответ на: комментарий от RazrFalcon

А смысл? Для примитивов разницы не будет

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

XMs ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.