А также сказать, сколько занимает в памяти следующий объект:
class A { int i; 2 byte short s; 1 byte static int si; 2 byte virtual void vf(); 1 byte }
Итого : 6 байтов правилбно ?
ps Я только начал изучать С++ поэтому порой буду задавать простые и глупые вопросы.
volvo
10.04.2008 21:22
Во-первых, это машинно- и компиляторо-зависимо (у меня на машине sizeof(int) = 4, а не 2), во-вторых зависит также от установок выравнивания (если откомпилировать без ничего, результат будет один, если с #pragma pack(1) - то результат другой), ну и в третьих, кто тебе сказал что виртуальная функция тоже что-то занимает, и это надо считать?
renesko1
10.04.2008 21:30
эээ ну я ... не знаю .... + у меня вопрос можно ли здесь еще задавать небольшие вопросы или создовать новую тему ?
klem4
10.04.2008 21:33
Если будет много небольших вопросов, то лучше в этой ветке задавай, только нумеруй их тогда, чтобы не возникло путаницы при ответах и тему переименуй в "Ряд вопросов по с++" например.
renesko1
10.04.2008 22:14
Вопрос 2. Не могу точно для себя понять зачем перед методами в классе ставить void ?
DocNo
10.04.2008 22:36
не обязательно void. можно и int.
volvo
10.04.2008 22:38
Чтобы объяснить компилятору, что метод ничего не возвращает. Вот синтаксис такой...
renesko1
10.04.2008 23:05
Вопрос 3. Вот написал класс описввающий фигуру rectangle. Он условен но меня волнует правильность.
classe rectangle { int width, length ; public : rectangle (int, int) ; void draw (int, int) ; Int Calcarea () ; Int CalcDiagonal () ; } //*************************************************** rectangle::rectangle (int w, int l) ; { if (w < 0) or (l < 0) then { cout << " Error input data/n " ; exit ; } width = w ; length = l ; } //**************************************************** Int rectangle::Calcarea() ; { return width * length } //**************************************************** void rectangle::draw (int x , int y) ; { rectangle(x, y, x + length, y + width) } //**************************************************** Int rectangle::CalcDiagonal () ; { return sqrt(sqr(width) + sqr(length)) } //************************end*******************************
volvo
10.04.2008 23:26
Цитата
меня волнует правильность.
В каком смысле "правильность"? Синтаксически пример неправильный, так что компилятор его не пропустит: отсутствуют точки с запятой в конце каждой строки, и после описания класса (а там, где они не нужны - присутствуют), слова then в С/С++ просто нет, так же как и функции sqr, ну и case-sensitivity языка тоже не даст программе откомпилироваться, если используешь тип int, то это не должен быть ни Int , ни INT... А только маленькими буквами...
Ну, а логически - фрагмент слишком маленький, чтобы что-то сказать...
P.S. Очень похоже на попытку дословного перевода с Паскаля...
renesko1
10.04.2008 23:32
Просто до этого у меня была монополия pascal
мисс_граффити
11.04.2008 4:31
class, не classe
AlonZo
11.04.2008 12:36
У меня тоже вопрос. Есть некий txt файл с числами, расположенными по числу на каждой строке, например: 1 2 3 И простая программа, которая считывает эти числа и выводит на экран. Проблема в том, что последяя цифра в файле дублируется и еще раз выводится. Что я не так делаю?
Т.е. результатом будет: 1 2 3 3 //Почему дублирует?
volvo
11.04.2008 13:13
Цитата
Почему дублирует?
Потому, что последняя строка - пустая... После прочтения последнего числа (тройки) конец потока еще не достигнут, значит, происходит попытка считать еще одно число. А не получилось, price остается прежним, печатается, и только теперь in.eof() возвращает истину... Чтобы избежать дублирования, подправляем чуть-чуть:
Спасибо, мисс_граффити и volvo, я купил себе наконец то книжку и теперь понимаю что за бред я понаписал.
renesko1
15.04.2008 23:08
Вопрос 4.
Как передать в функцию сточку для работы с ней ?
volvo
15.04.2008 23:19
Смотря что ты подразумеваешь под "строчкой" - это может быть и char *, и std::string, я уж не говорю о других обертках, которых в каждом компиляторе/библиотеке куча...
int main() { char s[20] = "start\0"; p(s); cout << s << endl; // печатаешь измененную
return 0; }
renesko1
15.04.2008 23:26
Ясно.
renesko1
21.04.2008 0:09
Вопрс 5. "Написать иерархию классов, которые в конструкторе принимает строку и у которых есть открытый метод print, которые выводят эту строку на экран или в файл на диск."
Честно пытался понять, но както так не очень далеко ушел. Можно хотя бы легкий пример.
volvo
21.04.2008 0:41
Не совсем понятно, зачем тут иерархия, это прекрасно делается в одном классе:
#include <iostream> #include <fstream>
class base { std::string s; friend std::ostream& operator << (std::ostream&, const base&); public: base(const std::string& st): s(st) { }
void print(std::ostream& os) { os << s; } };
std::ostream& operator << (std::ostream& os, const base& b) { os << b.s; return os; }
int main() { base b("hello, world!"); b.print(std::cout); // выводим на экран
std::ofstream out("file.txt", std::ios::out); // создаем файл ... b.print(out); // ... и пишем строку туда out.close();
return 0; }
Bo2nik
22.04.2008 22:39
Вопрос 6.
Объясните, пожалуйста, почему в отличие от функции printf() аргументами для функции scanf() могут быть только адреса объектов программы, в частном случае - адреса ее переменных. Глупый вопрос, но буду очень признателен.
volvo
22.04.2008 23:07
Ну, наверное все-таки потому, что printf не меняет входные параметры, они копируются в стек и выводятся на печать, а scanf как раз-таки должна значения параметров изменить (в этом и состоит ее задача), а сделать это можно только передав ссылку или указатель на аргумент (ссылок в чистом С еще не было, остаются только указатели).
alfons
24.04.2008 20:53
Дейтел. Как программировать на СИ. Очееееень подробная книга. Все очень просто, с примерами и заданиями!
blackhard
29.04.2008 20:31
Короче вот какой вопрос.У меня есть структура и указатель на нее по ходу выполнения мне надо под нее выделять память.Я решил сначало попробовать на простом примере
struct cel { int znac; char name[NAME];//вот структура }*CP;
............................................................ CP=(struct cel*)malloc(sizeof(struct cel )); realloc(CP,2*sizeof(struct cel )); CP[0].znac=20; printf("%d",CP[0].znac); free(CP);//при выполнении данной ф.и вылетает
Сначала выделяю память под 1 элемент.Подом добавляю памяти под второй.Так вот все ли я делаю правильно?И как потом эту память очистить? free(CP) не прокатывает.
volvo
29.04.2008 20:40
Скажи спасибо альфонсу, который посоветовал прочесть книгу Дейтела... Читай, наверное ее чтение само собой сделает свое дело, и ты больше не будешь задавать вопросов по С++... Там же все очень просто? Ну, так в чем дело?
Читаешь книгу, идешь спать... Проснулся - С++ стал тебе родным... Идиллия, правда? И главное - без усилий с твоей стороны, достаточно только прочитать, ведь "все ОЧЕНЬ просто!" (С)
blackhard
29.04.2008 20:47
Цитата(volvo @ 29.04.2008 17:40)
Скажи спасибо альфонсу, который посоветовал прочесть книгу Дейтела... Читай, наверное ее чтение сделает свое дело, и ты больше не будешь задавать вопросов по С++... Там же все очень просто? Ну, так в чем дело?
Да в том что неполучается освободить память после realloc на ф.и free(CP) выдается сообщение о том что обнаружена ошибка.
Добавлено через 2 мин. Блин ну я и тупой........Всегото надо CP=(struct cel*)realloc(CP,2*sizeof(struct cel ));
blackhard
29.04.2008 22:00
Если кому надо могу выложить Дейтела в электронном виде!!!
renesko1
1.05.2008 18:52
Я смотрю тема стала очень популярной Извините за флуд.
renesko1
8.05.2008 21:15
Вот еще попрос в паскале, когда пишешь модуль с обьектом переменные(обекта) видны во всех процедурах и тд. А в с++ как надо сделать что бы переменная была видна на весь модуль ?
volvo
8.05.2008 22:43
В С++ надо описать поле класса общим (в секции public) или пользоваться struct-урами, там поля общие по умолчанию, если не задашь другой метод доступа...
А вообще, это плохой стиль - давать всем подряд обращаться к полям класса. Лучше сделай Getter/Setter этой переменной, и дай им общий доступ, а саму переменную скрой в private-секции (так у тебя будет хоть какой-то контроль за тем, как изменяется поле класса; ведь может быть ситуация, что поле нельзя изменять, и вдруг какая-то посторонняя процедура берет и меняет его... Setter не должен ей этого позволить, если это на данный момент недопустимо)
renesko1
8.05.2008 22:56
Нет ты, к сожалению, не так меня понял. Я имею возможность обращатся в метадах обьекта напрямую не записывая в параметры мою переменную. А так, да, конечно, если сделать обращение напрямую, потом не разберешся, что где когда меняешь.
volvo
8.05.2008 23:31
Цитата
Я имею возможность обращатся в метадах обьекта напрямую не записывая в параметры мою переменную.
В методах объекта и в С++ ты можешь общаться со всеми полями напрямую... Разговор был о "снаружи", не правда ли?
Цитата
что бы переменная была видна на весь модуль
(на модуль, а не на класс, чувствуешь разницу?)
Или
class base { int value;
public: base(int val = 0): value(val) {} int getValue() const { return value; } };
и читай переменную, сколько влезет, но записать в нее тебе никто не даст (только изнутри класса или friend-function)... Или, если хочешь программировать в стиле Паскаля:
class base { public: int value;
base(int val = 0): value(val) {} };
или
struct base { int value;
base(int val = 0): value(val) {} };
, и работай отовсюду...
renesko1
9.05.2008 0:17
Как всегда помог, да ты прав, постараюсь в след. раз лучше формулировать вопрс.
DocNo
20.05.2008 20:37
у меня вопрос когда я должен вводить символы я ставлю условии на неналичие в них цифр вот так
но в далном случае прога виснет. подскажите что не так)
volvo
20.05.2008 21:09
Ты ж читаешь число, а не строку через scanf("%d"), а работаешь с day, как со строкой? Это во-первых... Во вторых: что за метка?
Достаточно было сделать вот так:
char buffer[256]; // Это для сбрасывания введенной строки, которая НЕ является числом
int day;
while(!(scanf("%d",&day))) { gotoxy(x, 2); day = -1; // Ну, или любое другое значение, неважно gets(buffer); // убираем из буфера строку, чтобы читать заново puts("Ошибка. Попробуйте еще раз... "); };
DocNo
20.05.2008 21:31
а зачем адрес брать у дня?
volvo
20.05.2008 22:06
Это ты у разработчиков С спрашивай, зачем им понадобилось, чтобы scanf работала с адресами... Наверное, чтобы введенное значение можно было вернуть из функции. Иначе зачем scanf вообще нужна?
blackhard
28.05.2008 22:45
А если у ф.и вот такой протатип
int sum2(int k,int(*p)(int,...),...)
(где k количество параметров).Как мне внутри этой ф.и передать необязательные параметры ... в ф.ю на которую указывет этот указатель int(*p)(int,...), и в которой тоже переменное число параметров?Можно так вообще сделать или нет?
volvo
28.05.2008 23:50
Цитата
Можно так вообще сделать или нет?
Можно... Вот так, например:
#include <stdio.h> #include <stdarg.h>
typedef int (*myFunc)(int ...);
int t(int k ...) { int sum = 0;
va_list vL; va_list *pvL;
va_start(vL, k); pvL = va_arg(vL, va_list*);
for(int i = 0; i < k; i++) { sum += va_arg(*pvL, int); } va_end(vL); return sum; }
int s(int k, myFunc f ...) { va_list vL; va_start(vL, f); int result = f(k, &vL); va_end(vL);
return result; }
int main() { int i = s(5, t, 10, 20, 30, 40, 150); printf("%d\n", i); return 0; }
compiler
14.06.2008 21:38
Вопрос #7 Вот есть программа, от которой я хотел бы составление последовательностей и вывод этого чуда.. Но увы она этого не делает( Наверно опять начудил с индексами.. Помогите..
#include <iostream> #include <vector> #include <cstdlib> using namespace std; int main(void){ const int number_el(6); //количество элементов const int number_seq(6); //количество последовательностей
upd подправлены формулы для треугольных и квадратных чисел, добавлено явное привидение типов.
volvo
14.06.2008 22:06
for(int i(0); i<number_seq; ++i){ for(int j(0); i<number_el; ++j) // Тут точно все, как надо? Может I не нужно? cout << (*seq_addrs[i])[j] << '\t'; cout <<'\n'; }
Кстати, обрати внимание на предупреждение... Лучше приводить результат к типу int явным образом...
compiler
14.06.2008 22:27
Цитата(volvo @ 14.06.2008 18:06)
Тут точно все, как надо? Может I не нужно?
точно.. спасибо..
Цитата(volvo @ 14.06.2008 18:06)
Кстати, обрати внимание на предупреждение... Лучше приводить результат к типу int явным образом...
а вот тут не понял( ты с какими ключами компилируешь?
Вопрос #7.1 это нормально вызывать конструктор для i несколько раз или этого надо избегать?
volvo
14.06.2008 22:43
Цитата
а вот тут не понял( ты с какими ключами компилируешь?
С какими бы ключами ты не компилировал, попытка сделать:
vector<int> triangular(number_el); //ряд Треугольных чисел for(int i(0); i<number_el; ++i) triangular[ i ]=0.5*(i*i+3)+1; // int <- double
на уважающем себя компиляторе приведет к Warning-у... Я компилирую с -Wall (причем всегда...), GCC 3.4.5 + Code::Blocks
Цитата
это нормально вызывать конструктор для i несколько раз или этого надо избегать?
Избегать за счет предварительного описания переменной что-ли? Я все-таки предпочитаю делать время жизни переменной минимальным... Кстати, почему именно такая форма? Вот так не проще для восприятия:
for(int i = 0; i < number_el; ++i) { ...
?
compiler
14.06.2008 23:10
Цитата(volvo @ 14.06.2008 18:43)
С какими бы ключами ты не компилировал, попытка сделать... на уважающем себя компиляторе приведет к Warning-у...
хм.. мой g++ (GCC) 4.2.3 (Ubuntu 4.2.3-2ubuntu7) ничего не говорит, даже с -Wall((
Цитата(volvo @ 14.06.2008 18:43)
Избегать за счет предварительного описания переменной что-ли?
да.. должно, наверно, экомится время на конструктор/деструктор.. или оно ничтожно?
Цитата(volvo @ 14.06.2008 18:43)
Вот так не проще для восприятия..
Лично мне все равно)) Ну, а потом, этот способ остался для совместимости с Си, насколько мне известно..
зы в программе есть еще ошибки по заполнению ряда, но не в них сейчас суть)
volvo
15.06.2008 0:29
Цитата
да.. должно, наверно, экомится время на конструктор/деструктор.. или оно ничтожно?
Можешь объяснить, с чего ты взял, что i = 0 ("оператор =") будет выполняться быстрее, чем конструктор для POD-типа, которым является int?
Цитата
Ну, а потом, этот способ остался для совместимости с Си, насколько мне известно..
Какой именно? Тот, которым пользуешься ты? Стандарт С++ открой, и посчитай, сколько там таких способов... А сколько - присваивания
compiler
15.06.2008 15:31
Цитата(volvo @ 14.06.2008 20:29)
Можешь объяснить, с чего ты взял, что i = 0 ("оператор =") будет выполняться быстрее, чем конструктор для POD-типа, которым является int?
я имел немножко другое, может лучше один раз объявить i, а потом один раз вызвать деструктор?
Цитата(volvo @ 14.06.2008 20:29)
Какой именно? Тот, которым пользуешься ты? Стандарт С++ открой, и посчитай, сколько там таких способов... А сколько - присваивания
насчет наследования Си, я руководствывался Липпманом*(это конечно не стандарт))). Там же несколько "преимуществ" нововведенного способа. Хотя сам Липпман, в последующих листингах пользуется оператором присваивания
*-Стэнли Липпман "Основы программирования на С++". Издательство "Вильямс" 2002год. глава 1.2 (страница 26, 6-я строка)
Цитата
Использования для инициализации оператора присваивания (=) унаследовано от языка С.
volvo
15.06.2008 15:41
Цитата
я имел немножко другое, может лучше один раз объявить i, а потом один раз вызвать деструктор?
Еще раз: в каждом цикле (в разделе инициализации, до первой точки с запятой оператора for) для объявленного тобой где-то сверху i будет вызываться "operator ="? Будет, иначе ты не присвоишь i правильное стартовое значение... Вопрос: кто тебе сказал, что для int конструктор будет выполняться медленнее, чем "operator ="?
compiler
15.06.2008 15:49
Цитата(volvo @ 15.06.2008 11:41)
.. Вопрос: кто тебе сказал, что для int конструктор будет выполняться медленнее, чем "operator ="?
хм.. не знаю) а как вообще можно засеч время выполнения программмы(урывка) на с++ ? (это вопрос #8 )
volvo
15.06.2008 16:44
Цитата
как вообще можно засеч время выполнения программмы(урывка)