Отправлено: 28.07.12 20:25. Заголовок: Шутка - ложь, но в ней намек, добрым молодцам урок.
Это не выдумка, а реальное сообщение, написанное на одном сайте:
цитата:
Решил я изучать C++. Но вот беда - перепробовал уже 9 книг - в каждой один и тот же первый пример - Hello world. И в каждой он не верен, если верить visual studio c++.
Перефразируя известное выражение, что если раз дали в морду, второй раз дали в морду, третий раз дали в морду, то может быть дело в морде?!
Отправлено: 28.07.12 20:26. Заголовок: Еще одно забавное вы..
Еще одно забавное высказывание одного начинающего программиста:
цитата:
so i have been wanting to make a OS but can anyone give some help by telling me were to start and any other info that may help?
Написано следующее: Мне захотелось создать операционную систему, поэтому не мог бы кто-нибудь сказать, с чего начать, а также предоставить другую информацию, которая может быть полезной.
Это только по молодости можно строить такие наполеоновские планы тем более. не имея опыта программирования.
Дополнение Похоже, это непреодолимая и бессмертная тема в программировании, как тема любви в художественной литературе, касательно начинающих программистов, которая не зависит ни от национальной, ни от территориальной принадлежности. Это, можно сказать, болезнь "переходного возраста" программистов, которой начинающие программисты должны переболеть, как многие из нас переболели в детстве "ветрянкой"..
На днях опять вычитал на одном, уже российском форуме такое сообщение начинающего программиста (главное достоинство этого сообщения состоит в том, что на этот раз мне не требуется переводить его с иностранного языка на русский ):
цитата:
Хочу написать ос на c++ но не знаю как помогите и подскажите с чего начать. А ещё лучше если кинете мне статью или видео-урок по написанию ос на c++
Вы не находите, что это сообщение является почти идентичной копией первого сообщения на английском языке, учитывая то, что первое сообщение также было написано в разделе форума, посвященном языку C++?
Отправлено: 28.07.12 20:27. Заголовок: Вот пример плодотвор..
Вот пример плодотворной дискуссии по вопросам программирования. Я лишь убрал ники участников дискуссии:
цитата:
потому что это был
Мне не понятен ни ход твоих мыслей, ни смысл сообщения в 4# посту. Поскольку, автор сабжа так же, по видимому тебя не вразумел, то есть предложение - получше формулировать свои мысли. Если конечно, ты разговариваешь не сам с собой, и тебе хочется, что бы тебя могли понять другие.
цитата:
Мне не понятен ни ход твоих мыслей, ни смысл сообщения в 4# посту.
это нормально, я точно также не понимаю, что пишут другие.
Отправлено: 28.07.12 20:29. Заголовок: Если ваш труд оценив..
Если ваш труд оценивают по количеству набранных знаков, то вы можете включить в свой арсенал средств по увеличению объема кода следующий прием, используемый при объявлении переменных:
const unsigned const long const long const int x = 10;
На первый взгляд эта конструкция кажется ошибочной, но на самом деле это есть объявление
const unsigned long long x = 10;
Компилятор просто отбросит лишние квалификаторы const.
Отправлено: 28.07.12 20:31. Заголовок: Часто начинающие изу..
Часто начинающие изучать С++ задают такой вопрос: чем отличается ++count от count++. Более опытные программисты им быстро разъясняют, чем прединкриметная операция отличается от постинкриментной. Естественно акцент делается на то, какой результат возвращают эти два выражения.. Но при этом обычно забывается еще один очень важный аспект, определяющий различие этих операций. И когда указываешь на него в виде примера записи выражения, то это порой удивляет даже опытных программистов.
Так что это за аспект, о котором забывают, и как его более наглядно продемонстрировать?
Все просто: разница между ++count и count++ состоит в том, что в первом случае вы можете указать любое четное число плюсиков, а во втором случае вы можете указать всего лишь только два плюсика!
++++++++++count;
и только
count++;
Это справедливо для C++. Однако в C первое предложение выражения не будет компилироваться. В C вы можете использовать только два плюсика.
При этом максимальное значение объекта типа unsigned int равно 4294967295.
Я это потому написал здесь, что часто начинающие программисты об этом совершенно не задумываются, когда используют вычисления факториалов. Вот пример размышления начинающего программиста, взятый с форума www.cplusplus.com
Его задание выглядет так:
цитата:
Write a program that computes the value of e-x by using the formula:
e-x= 1- x/1! + x2/2! - x3/3! + …
То есть требуется вычислить ряд, в знаменателе каждого члена которого используется факториал. Далее этот навичок пишет цикл и рассуждает, сколько итераций должно быть в цикле, приходя к выводу, что самое подходящее число для итераций - это 30! Причем для хранения факториалов он использует даже тип не unsigned int, а просто int!
цитата:
int factorial=1; for(int i=1;i<=30;i++)//I don't know which number to chose because for high values when the compiler compiles i get values which say IDK..i thought 30 was the best choice..30! for instance is high enough)
Отправлено: 28.07.12 20:33. Заголовок: Интересно отметить, ..
Интересно отметить, что оказывается количество факториалов, которые можно разместить в объекте типа unsigned int в точности совпадает с количеством факториалов, которые можно разместить в объекте типа int, то есть 12 факториалов. Вот значения факториалов для объекта типа int:
Максимальное значение объекта типа int равно 2147483647.
Кстати сказать, то же самое справедливо и для типа long long, то есть количество значений факториалов, которые можно разместить в объекте этого типа совпадает с количеством значений факториалов, которые можно разместить в объекте типа unsigned long long, - ровно 20 факториалов.
Я оговорился, сказав, что может бть всего лишь 20 и 12 значений факториалов для объектов соответственно типов unsigned long long/long long и unsigned int/int. На самом деле число факториалов на 1 больше, так как факториалы вычисляются, начиная с 0. То есть число фаториалов для этих типов 21 и 13. 20 и 12 - это максимальные значения неотрицательных чисел, факториалы которых могут уместиться соответственно в объектах указанных типов.
Те, кому интересно посмотреть значения факториалов для больших значений чисел, могут использовать следующую программу, написанную мною на C#. Она выдает значения факториалов для чисел от 1 до 50. Вам достаточно будет изменить условие цикла в статическом методе Factorial, если вы хотите подсчитать факториал для больших значений.
Эта программа использует класс BigInteger, определенный в пространстве имен System.Numerics, Чтобы его можно было бы использовать, вам надо добавить в проект ссылку на System.Numerics.dll.
Вот текст программы:
using System; using System.Numerics; using System.Collections.Generic;
namespace Factorial { class Program { static IEnumerable<string> Factorial() { uint i = 1; BigInteger value = 1;
do { value *= i; yield return string.Format( "{0,4}: {1}", i, value ); } while ( i++ != 50 ); }
static void Main(string[] args) { const int LINES_PER_SCREEN = 22; int i = 0;
foreach (string next_value in Factorial()) { Console.WriteLine(next_value);
if ( ( i = ++i % LINES_PER_SCREEN) == 0 ) { Console.Write("\nContinue (Enter - continue)? "); var c = Console.ReadKey(); if (c.Key != ConsoleKey.Enter) break; Console.WriteLine( "\n" ); } }
Console.WriteLine(); } } }
Ее вывод на консоль может выглядеть следующим образом:
Отправлено: 28.07.12 20:34. Заголовок: Следующий пример код..
Следующий пример кода можно в шутку предворить крылатой фразой: "Что позволено Юпитеру, то не позволено быку.":)
Если написать следующее объявление
int *pi = &pi:
То вы неминуемо получите ошибку компиляции. Нельзя неявно преобразовать тип int **, который имеет выражение &pi, в тип int *, который имеет сама переменная pi.
Но вполне можно написать
void *pv = &pv;
и это объявление успешно скомпилирутеся.
Первой реакцией неопытного С/С++ программиста может быть недоумение: "Как же так, ведь здесь тоже имеется два различных типа: void **. выражения &pv и void * переменной pv!"
Как говорится, ларчик открывается просто. Указателю void * может быть присвоено значение указателя любого типа в том числе и void **. Никаких при этом приведений типов делать нет необходимости.
Отправлено: 07.08.12 18:40. Заголовок: Встретил такой вопро..
Встретил такой вопрос на одном из форумов:
цитата:
Здравтвуйте, у меня такая проблема, не могу задать чтоб из побочной диагонали одномерного массива выбирался минимальный элемент.
Наверное в мое время, когда я сам был школьником, нас неправильно учили! Мне стыдно признаться, но я до сих пор не знаю, что такое "побочная диагональ одномерного массива". Может быть кто-нибудь подскажет, как в одномерном пространстве изобразить диагональ?
На самом деле он заблуждается. Никакого бага здесь нет. Код совершеннно корректный. Чтобы лучше было разобраться, что эта конструкция означает, желательно вставить пробел между знаками операторов = и +.
s = +"World";
В правой части находится строковый литерал, который имеет тип константного символьного массива. Массивы в выражениях преобразуются к указателю на их первый элемент.
А к указателям можно применять унарный оператор +!
Согласно параграфу №7 раздела 5.3.1 Unary operators стандарта С++:
цитата:
7 The operand of the unary + operator shall have arithmetic, unscoped enumeration, or pointer type and the result is the value of the argument. Integral promotion is performed on integral or enumeration operands. The type of the result is the type of the promoted operand.
Для указателя он никакой роли не играет. Поэтому выражение
s = +"World";
эквивалентно выражению
s = "World";
без унарного оператора +. А это - уже знакомая всем запись присвоения символьного литерала объекту типа std::string.
Замечу также, что в отличии от унарного оператора + унарный оператор - нельзя применять к указателям.
Забавность этого примера состоит в том, что многие, даже опытные программисты, попадаются на этот трюк С++ с операторами =+, считая, что они обнаружили баг компилятора.
Кстати сказать, такую опечатку легко пропустить, не заметив, а потом не один час потратить на поиск причины некорректной работы программы.
Отправлено: 21.09.12 15:53. Заголовок: Вот очень простой и ..
Вот очень простой и в то же время сложный вопрос, так как решение его не очевидно, то есть не сразу же приходит на ум.
Допустим в программе на C++ объявлена структура, члены которой имеют арифметические типы или типы перечислений.
struct A { /* объявления членов структуры арифметических типов или типов перечислений */ };
Являются ли два таких объявления объектов этой структуры, показанных ниже, эквивалентными, и может ли одно из них привести к ошибке компиляции, то есть при задании подобного объявления для некоторой сттруктуры, содержащей только члены, имеющие арифметические типы и типы перечислений, компилятор выдаст сообщение об ошибке?
Отправлено: 22.09.12 02:03. Заголовок: Не удержался и решил..
Не удержался и решил привести пример самого абсурдного кода начинающего программиста, который на первый взгляд не должен компилироваться, но на самом деле с точки зрения синтаксиса он корректный. Забавно, что у автора кода программа действительно скомпилировалась и даже что-то там запросила ввести!
Вот этот код. Привожу его целиком, чтобы можно было по достоинству оценить творческий порыв начинающих программистов
#include "stdafx.h" #include <iostream>
#define PI 3.14159
using namespace std;
void select() { cout << "Select r for radius or d for diameter: "; char choice; cin >> choice; }
void calculation(void select(), char choice) { if (choice == 'r') cout << "Select a value for your radius: " << endl; double radius; cin >> radius;
double circRadius; circRadius = 2 * PI * radius;
if (choice == 'd') cout << "You have selected a diameter." << endl; double diameter; cin >> diameter;
Найдите в коде причину возникновения этого исключения.
данный код будет кидать исключение только на тех платформах, где sizeof(unsigned int) != sizeof(string::size_type) (коим и является npos), например на x86-64. там где они равны, все будет работать нормально. меняем unsigned int pos на string::size_type pos и будет работать везде.
Являются ли два таких объявления объектов этой структуры, показанных ниже, эквивалентными, и может ли одно из них привести к ошибке компиляции, то есть при задании подобного объявления для некоторой сттруктуры, содержащей только члены, имеющие арифметические типы и типы перечислений, компилятор выдаст сообщение об ошибке?
A a1 = {}; A a2 = { 0 };
очевидно же, что если в структуре первый член будет являться перечислением, во второй строчке произойдет ошибка о невозможности неявного преобразования int к enum.
данный код будет кидать исключение только на тех платформах, где sizeof(unsigned int) != sizeof(string::size_type)
Все правильно. Данный пример демонстрирует, насколько важно использовать со стандартными контейнерами те имена типов, которые объявлены в каждом контейнере. Иначе можно столкнуться с подобной ситуацией, когда неожиданно ранее работающий код начинает вести себя непредвиденно.
Смоделировать эту ситуацию легко и на пллатформе, для которой std::string::size_type определен как unsigned int. Для этого достаточно просто присвоить значение std::string::size_type переменной unsigned short.
Вот пример такого кода
std::string s( "ABC" );
unsigned short n = s.find( "D" ); //std::string::size_type n = s.find( "D" );
if ( n != std::string::npos ) std::cout << "n != std::string::npos\n"; else std::cout << "n == std::string::npos\n";
Если использовать предложение unsigned short n = s.find( "D" );, то на консоль будет выдано сообщение
цитата:
n != std::string::npos
Если же использовать предложение std::string::size_type n = s.find( "D" );, которое закомментировано в примере, то на консоль будет выдано сообщение
Отправлено: 01.10.12 13:50. Заголовок: 2Сыроежка набор бито..
2Сыроежка набор битов у результата будет одинаков, отображение разное. unsigned short после аддитивной операции (да и не только аддитивной) продвигается до типа int, unsigned int остается самим собой.
Отправлено: 19.10.12 21:16. Заголовок: Знаете ли вы, что MS..
Знаете ли вы, что MS VC++ позволяет использовать символ $ (знак доллара) в идентификаторе. Так что следующее предложение в MS VC++ будет успешно компилироваться.
char $ = '$';
Не надо забывать, что стандард С++ разрешает в идентификаторах использовать implementation-defined символы.
Все даты в формате GMT
3 час. Хитов сегодня: 10
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет