тест по С++
список вопросов:
1) Переписать цикл с использованием указателей вместо индексов.
for (int x = 0; x < 100; x ++)
cout array[x]<<endl;
…
2) Пусть pint - указатель. Какие из след. предложений ошибочны и почему?
pint ++;
--pint;
pint /= 2;
pint *= 4;
pint += x // x – целое число.
3) Написать пример правильного вызова следующеё функции.
void MakeNegative (int *val)
{
if (*val > 0)
*val = -(*val);
}
…
4) Пусть дано след. объявление структуры.
struct Rectangle
{
int length, width;
}
Написать объявление указателя на структуру Rectangle.
5) Какие из этих объявлений неправильны и почему?
float measurements {4.5];
int size;
char name [size];
int numbers [10] = {0, 0, 1, 0, 0, 1, 0, 0, 1, 0};
int matrix [5] = {1, 2, 3, 4, 5, 6, 7};
float rad [10] = {3.2, 4.7};
int table [7] = { 2, , , 27, , 45, 39}
char [] = {‘A’, ‘X’, ‘1’, ‘!’, ‘s’};
int blanks [];
char name [6] = “Joanne”;
6) Дано объявление массива:
int nums [3] = {1, 2, 3};
Что будет выведено на экран следующим оператором?
cout << nums [3];
7) Сколько значений может вернуть функция?
8) Найдите и объясните ошибки в функции:
void getvalue (int value &)
{
cout << “enter a value”<< endl;
cin >> value &;
}
9) Найдите и объясните ошибки в программе:
struct TwoVals
{
int a = 5, b = 10;
}
void main()
{
TwoVals v;
cout << v a << v b;
}
10) Что будет выведено на экран для массива
int values [] = {2, 6, 10, 14}
cout << values [2];
cout << ++values[0];
cout << values [1]++;
int x=2;
cout << values [++x];
11) Что и почему неправильно в этих объявлениях?
int var; int *iptr=&ivar;
int ivar, *iptr=&ibar;
float fvar; int *iptr=&fvar;
int nums[50], *iptr=nums;
*iptr=&ivar; int ivar;
Отвечать тоже картинками надо? ))
Если бы ответы были в текстовом виде, то отвечать было бы намного удобнее. Проявите уважение к отвечающим. Да и у вас в голове может что-то отложится, если перепишете.
Вот еще - кто это вам должен рассматривать там значки и по ним что-то угадывать..
for (int x = 0; x < 100; x ++)
cout array[x]<<endl;
не указан тип массива -- пусть будет int для примера. Тогда:
for (int i = 0; i < 100; i++, pInt++)
{
cout << *pInt << endl;
}
pint ++;
--pint;
pint /= 2;//
pint *= 4;
pint += x // x – целое число.
Ошибочны:
pint /= 2;
pint *= 4;
void MakeNegative (int *val)
{
if (*val > 0) *val = -(*val);
}
MakeNegative(&iValue);
struct Rectangle
{
int length, width;
}
Написать объявление указателя на структуру Rectangle.
struct Rectangle *pRect;
5) Какие из этих объявлений неправильны и почему?
[COLOR="Red"]float measurements {4.5];[/COLOR]//ошибка синтаксиса
int size;
[COLOR="#ff0000"]char name [size];[/COLOR]//size не константа
int numbers [10] = {0, 0, 1, 0, 0, 1, 0, 0, 1, 0};
[COLOR="Red"]int matrix [5] = {1, 2, 3, 4, 5, 6, 7};[/COLOR]//слишком много инициализаторов
float rad [10] = {3.2, 4.7};
[COLOR="#ff0000"]int table [7] = { 2, , , 27, , 45, 39}[/COLOR]//ошибка синтаксиса
[COLOR="#ff0000"]char [] = {‘A’, ‘X’, ‘1’, ‘!’, ‘s’};[/COLOR]//нет имени переменной
[COLOR="#ff0000"]int blanks [];[/COLOR]//размер неизвестен
char name [6] = “Joanne”;
int nums [3] = {1, 2, 3};
Что будет выведено на экран следующим оператором?
cout << nums [3];
заранее сказать нельзя, т.к. индекс выходит за размер массива
не понял вопрос
void getvalue (int value &)
{
cout << “enter a value”<< endl;
cin >> value &;
}
{
cout << "enter a value" << endl;
cin >> value;
}
9) Найдите и объясните ошибки в программе:
struct TwoVals
{
int a[COLOR="#ff0000"] = 5[/COLOR], b[COLOR="#ff0000"] = 10[/COLOR];//нельзя инициализировать члены класса здесь
}[COLOR="#ff0000"];[/COLOR]
void main()
{
TwoVals v;
cout << v[COLOR="#ff0000"].[/COLOR]a << v[COLOR="#ff0000"].[/COLOR]b;
}
int values [] = {2, 6, 10, 14}
cout << values [2];
cout << ++values[0];
cout << values [1]++;
int x=2;
cout << values [++x];
103614
11) Что и почему неправильно в этих объявлениях?
int var; int *iptr=&[COLOR="#ff0000"]i[/COLOR]var;
int ivar, *iptr=&i[COLOR="#ff0000"]b[/COLOR]ar;
float fvar; int *iptr=&fvar;//разные типы у указателя и переменной
int nums[50], *iptr=nums;//все ок
*iptr=&ivar; int ivar;//не объявлен тип указателя; ссылка от переменной берется до ее объявления
for (int i = 0; i < 100; i++, pInt++)
{
cout << *pInt << endl;
}
Вобще то наверняка имелось ввиду такое, ибо индекс тут явно лишний:
for(; array != end; array++)
std::cout << *array << std::endl;
Дальше смотреть не стал ))
char name [6] = “Joanne”;
Я уж не знаю как там по правилам языков C/C++, но у меня MSVC2005 выдает ошибку, ибо нулик записать ему уже некуда. Думаю что и правильно делает что выдает. Ибо, если б мы захотели именно массив символов (а не с правилами строки) - пришлось бы написать так
Может корифеи цпп меня и поправят..
[COLOR="#ff0000"]int table [7] = { 2, , , 27, , 45, 39}[/COLOR]//ошибка синтаксиса
Здесь скорее не ошибка синтаксиса а недопустимость пропуска элементов массива в его начале или середине. А вот в конце - можно.
for(; array != end; array++)
std::cout << *array << std::endl;
Дальше смотреть не стал ))
эээ, нехорошо - портите указатель массива. Тогда уж
std::cout << *p << std::endl;
или
std::cout << *(array + i) << std::endl;
Одно или ни одного.
Если надо изменить больше данных, то можно использовать указатели или ссылки.
Я уж не знаю как там по правилам языков C/C++, но у меня MSVC2005 выдает ошибку
Builder5 это глотает.
Может, это и неверно с позиции высоких материй, но -- писать кучу апострофов неудобно
Может, это и неверно с позиции высоких материй, но -- писать кучу апострофов неудобно
Надо
char name [7] = “Joanne”;
или
char name [] = “Joanne”;
Не вижу ничего плохого в инициализации массива символов строкой, если потом им пользоваться именно как массивом, а не как строкой.
Неудобно - это одно. Но именно куча апострофов - это массив символов. И только так. Набор символов в кавычках это уже, извините, строка. А значит и правила там для строки. И нулик там таки должен быть а следовательно, и массив 7-ми символьный.
И "неудобно" -- это все же весомый аргумент
Это массив символов, заканчивающийся нулевым байтом. При инициализации константной строкой этот байт не указывается.
Почитайте любой учебник.
Повторю: [COLOR="Red"]для удобства[/COLOR] при инициализации массива символов проще написать char name[6] = "Joanne", а не char name[6] = {'J', 'o', 'a', 'n', 'n', 'e'}
И если пользоваться этим массивом как массивом, а не как строкой, какая тогда половая разница, есть ли там ноль в конце или нет.
Или будьте уж тогда последовательны в своих принципах, пишите:
int v = static_cast<int>(d);
вместо
int v = d;
потому что double -- это не int, и у него есть хвостик в виде дробной части
А заодно можете прекратить использовать операторы +=, ++, -= и иже с ними, потому что такая запись тоже введена для удобства, и далеко не очевидна
И если пользоваться этим массивом как массивом, а не как строкой, какая тогда половая разница, есть ли там ноль в конце или нет.
Почитайте стандарт по C++ от 2003 года пункт 8.5.2.
Не для удобства. Почитайте про перегрузку этих операторов. Вы удивитесь, но во многих случаях
a = a + b;
будет работать медленнее, чем
a += b;
Почитайте стандарт по C++ от 2003 года пункт 8.5.2.
Почитайте про перегрузку этих операторов.
Если уж используете что-то, написанное кем-то, в качестве своих аргументов, приведите цитаты или хотя бы ссылки на источники, откуда вы это взяли.
a = a + b;
будет работать медленнее, чем
a += b;
А во многих случаях люди умеют летать. Давайте не будем обсуждать сферического коня в вакууме.
Вы серьезно думаете, что операторы вида += введены для выигрыша пары лишних тактов процессора? Те, кому важны пара тактов, используют ассемблер. Впрочем, мотивы создателей С++ мы вряд ли узнаем. Хотя, если у вас есть доказательства...
И откуда вам знать, чему я удивлюсь, а чему нет
a = a + b;
будет работать медленнее, чем
a += b;
Не скажи. Хоть компиляторы разные но в большинстве не совсем дураки. Для примитивных числовых значений в Release билде (со всеми оптимизациями) разницы не будет.
Цитата выдернута из контекста. Я там говорил о перегрузке операторов (возможно, надо было указать, что для классов). Но с другой стороны, я указал: "во многих случаях", это не значит, что всегда будет так.
Для Нездешнего цитата из стандарта
...
2 There shall not be more initializers than there are array elements. [Example:
char cv[4] = "asdf"; // error
is ill-formed since there is no space for the implied trailing ’\0’. ]
[QUOTE=Нездешний]Впрочем, мотивы создателей С++ мы вряд ли узнаем.[/QUOTE]
Почему? Что мешает почитать Страуструпа (The C++ Programming Language Special 3rd Edition)?
дан код, нужно написать, что выводится на экран...
но у меня ругается на 3 ошибки. где они, я не понимаю.
using namespace std;
void show(int);
void main()
{
int num=0;
show(num);
}
int show (int arg)
{
if (arg < 10) show(arg);
else cout << arg << endl;
}
Приводите цитаты! Некогда снова копаться в давно прочитанных книгах.
Цитаты из Страуструпа:
из-за такого сжатого, использующего сложные выражения стиля
программирования. Оператор while (*p++ = *q++) ;
вероятнее всего, покажется невразумительным для незнакомых с С.
Страуструп по всему тексту говорит в основном об элегантности и краткости лексем С++. Возможная при перегрузке для пользовательских классов скорость, как видите, упоминается лишь в качестве побочного эффекта.
1. Да, согласен, стандарт этого не позволяет
2. Согласен, что для топикстартера вариант char name[6] = "Joanne" скорее является ошибочным
3. При всей "нестандартности" продолжаю настаивать, что вариант char name[6] = "Joanne" гораздо удобнее, чем char name[6] = {'J', 'o', 'a', 'n', 'n', 'e'}. И хорошо согласуется с заветами Страуструпа о краткости и элегантности записи.
Еще раз скажу, что в Borland C++ Builder 5 этот вариант проходит и ошибок не вызовет.
#include <conio.h>
#pragma hdrstop
//---------------------------------------------------------------------------
#pragma argsused
int main(int argc, char* argv[])
{
char name0[] = "Maria";
char name1[6] = "Joanne";
char name2[5] = {'H', 'e', 'l', 'e', 'n'};
char name3[] = "Irina";
cout << name0 << endl;
cout << name1 << endl;
cout << name2 << endl;
cout << name3 << endl;
getch();
return 0;
}
Листинг файла:
61 00 4A 6F 61 6E 6E 65 a.Joanne
48 65 6C 65 6E 49 72 69 HelenIri
6E 61 00 90 3C 13 40 00 na..<.@.
Так что в BCB5 при инициализации вида char name[6] = "Joanne" нулевой символ в конце не записывается в память, ошибок не возникнет, пользоваться можно, что удобно и элегантно
[COLOR="Red"]using namespace std;[/COLOR]//не надо, вы не используете ничего из пространства имен std
[COLOR="#ff0000"]void[/COLOR] show(int);//в объявлении функции тип void, а в определении int
void main()
{
int num=0;
show(num);
}
[COLOR="#ff0000"]int[/COLOR] show (int arg)
{
if (arg < 10) show(arg);
else cout << arg << endl;
//указан возвращаемый тип int, но ничего не возвращается
}
Ну, если вы читали, то зачем спорите? А в таких книгах надо копаться и копаться, чтобы освежать память, чтобы лучше понять некоторые куски.
Где там слово "побочный"? Тем более в третьем издании, он особо отмечает эту особенность. Да и во втором издании, откуда ваши цитаты, он далее разъясняет:
для работы с пользовательскими типами, поскольку обычно запись
с ними короче, чем с их обычными "двойниками" * и + , а кроме того
они могут повысить скорость выполнения программы за счет
исключения временных переменных:
inline complex& complex::operator+=(complex a)
{
re += a.re;
im += a.im;
return *this;
}
При использовании этой функции не требуется временной переменной
для хранения результата, и она достаточно проста, чтобы транслятор
мог "идеально" произвести подстановку тела. Такие простые операции
как сложение комплексных тоже легко задать непосредственно:
inline complex operator+(complex a, complex b)
{
return complex(a.re+b.re, a.im+b.im);
}
Здесь в операторе return используется конструктор,
что дает транслятору
ценную подсказку на предмет оптимизации. Но для более сложных
типов и операций, например таких, как умножение матриц, результат
нельзя задать как одно выражение, тогда операции * и + проще
реализовать с помощью *= и += , и они будут легче поддаваться
оптимизации:
matrix& matrix::operator*=(const matrix& a)
{
// ...
return *this;
}
matrix operator*(const matrix& a, const matrix& b)
{
matrix prod = a;
prod *= b;
return prod;
}
То есть, для простых классов - нет разницы, так как кампилятор может оптимизировать код, а для сложных эффективность явно повысится.
Таким образом, чтобы не задумываться, справится ли с оптимизацией компилятор, лучше где возможно использовать +=, а не +.
Может, стоит перенести часть темы в общалку или в общие вопросы по С++
Вы утверждаете, что основной причиной введения в С++ операторов вида += была более высокая скорость работы для пользовательских классов.
Это вызывает большие сомнения.
1. Возможная более высокая скорость операторов вида += при перегрузке для пользовательских классов зависит от конкретной реализации пользователем. Т.е., язык позволяет сделать оператор += более быстрым, но не обязывает этому
2.То, что акцент на скорости и оптимизации появился лишь в третьем издании, косвенно говорит о том, что ранее этому не придавалось особого значения -- т.е. основная причина появления не в скорости
Разве я где-то утверждал обратное?
О "побочном" эффекте говорит оборот "а кроме того".
<Утверждение>, поскольку/потому что <основная причина>, а кроме того <второстепенная причина или эффект>
Зачем? И так уже все понятно.
1. Стандарт не позволяет так инициализировать массив символов, Borland C++ Builder 5 позволяет (я не проверял, но верю).
2. Запись типа += короче, чем + и позволяет в некоторых случаях создавать более эффективный код.
Думаю, с этим согласны обе стороны и дальше спорить нет смысла. Если где-то нагрубил или как-то обидел, то извините.
[COLOR="Red"]using namespace std;[/COLOR]//не надо, вы не используете ничего из пространства имен std
Насколько я помню cout, тот что идет дальше - это std::cout
А нигде и не указанно, что это массив, а не указатель на его первый элемент. Иначе да, можно проинициализировать указатель на него сначала. А вот прибавлять каждый раз в цикле сотню к адресу не хорошо, хотя оптимизация компилятора это скорее всего и не пропустит в результат. В этом плане я постарался показать наиболее оптимальный код. )
А по поводу инициализации массива строкой - корректно инициализировать так:
эта строка для корректной работы не требуется
эта строка для корректной работы не требуется
Однако, удивительным образом работает пятый билдер...
А в той программе хорошо бы еще бесконечную рекурсию убрать.
Philips. Just do it.
C++Builder. Просто работает. :D
Конечно 5ый билдер настолько же далек от стандарта, насколько например и я далек от него. Да и вышел-то он фиг помнит когда.. 99? Но со временем борланд/кодгир/эмбаркадеро все-таки улучшили ситуацию. Во всяком случае о 2009-м билдере злостные ревнители стандарта говорят уже куда мягче :).
А так работает не только пятый билдер. Насколько я помню, так работает все с++ компилеры от борланда (которые еще не билдеры были). Да и в Визуал С++ 6 все так же. Пишите #include <iostream.h> и можете пользоваться cin, cout
Да и 2005 визуал студио.
#include <stdafx.h>
#include <iostream.h>
Да и 2005 визуал студио.
#include <stdafx.h>
#include <iostream.h>
Ты ошибаешся.
Да и 2005 визуал студио.
#include <stdafx.h>
#include <iostream.h>
Угу, счаззззз!
fatal error C1083: Cannot open include file: 'iostream.h': No such file or directory
Переходите уже на современный цпп..
А вот вопрос использования современных сред зависит уже не от меня