Автор Тема: Програмирование на C++  (Прочитано 76911 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн HardWareMan

  • Модератор
  • Сообщений: 7527
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #30 : 25 Январь 2011, 10:52:00 »
И где же указатель на первый элемент этого "массива"? )
Цитата
#include <iostream>

void digits(int i)
{
  int j = i / 10;
  if (j != 0)
    digits(j); << Указатель на следующий элемент массива
  std::cout << i % 10 << " ";
}

int main()
{
  std::cout << "Number: ";
  int n;
  std::cin >> n;
  std::cout << "Digits: ";
  digits(n); << Указатель на первый элемент массива
  return 0;
}
Кто скажет что это не так - лично плюну в глаз. :3

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #31 : 25 Январь 2011, 12:08:32 »
kamre, засчитывается :) Интересный алгоритм получился.

Оффлайн kamre

  • Пользователь
  • Сообщений: 8
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #32 : 25 Январь 2011, 14:43:55 »
Кто скажет что это не так - лично плюну в глаз. :3

Прикрывая глаз, цитирую:
Цитата
An array is a series of elements of the same type placed in contiguous memory locations that can be individually referenced by adding an index to a unique identifier.

А в моем примере все промежуточные значения находятся в локальных переменных, которые лежат в stack frames вперемешку с параметром функции и адресом возврата.

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #33 : 25 Январь 2011, 15:56:18 »
Вопрос на засыпку номер 2: почему в c++ новые переменные изначально не равны 0, какая польза из того что в них случайные числа? Ведь это лишний повод сделать ошибку забыв обнулить счётчик например. В это же время статические (static) новые переменные обнулены.

Оффлайн HardWareMan

  • Модератор
  • Сообщений: 7527
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #34 : 25 Январь 2011, 18:15:55 »
Прикрывая глаз, цитирую:
А в моем примере все промежуточные значения находятся в локальных переменных, которые лежат в stack frames вперемешку с параметром функции и адресом возврата.
Да, а стэк является массивом байт памяти. А каждый твой стэкфрэйм (если разговариваем на русском, то лучше говорить "кадр") является одним законченным элементом типа "запись". Правда согласен, рандомный доступ к этому массиву записей имеет только супервизор задач. Ладно, отвлеклись. Так что воооот!

Оффлайн kamre

  • Пользователь
  • Сообщений: 8
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #35 : 25 Январь 2011, 21:13:09 »
Да, а стэк является массивом байт памяти.
Тогда в компьютере все связанное с памятью "является массивом байт"  :lol:

Оффлайн MetalliC

  • Технический консультант
  • Сообщений: 9386
  • Пол: Мужской
  • Demul team / MAME developer
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #36 : 25 Январь 2011, 21:31:22 »
kamre, насчет стека оно так и есть, на нем динамически резервируется и потом освобождается некое количество данных, структура/размер которых определяется кол-вом аргументов функции и локальных динамических (не статик) переменных

Оффлайн BmpCorp

  • Пользователь
  • Сообщений: 1413
  • Пол: Мужской
  • Серьёзнее не бывает
    • Steam
    • Youtube
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #37 : 25 Январь 2011, 21:32:14 »
Цитата: DeniSS
А вообще, надо дружить с мануалами. Я так вот почти всегда MSDN-овскую справку открытой держу - мало ли 
Она для C++ и правда чем-то может помочь? А то, работая с C#, у меня сложилось впечатление, что она в любой задаче только всё затруднит :)

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #38 : 25 Январь 2011, 23:08:42 »
Я тут посмотрел на вес скомпилированного exe файла маленькой программки по сортировке одномерного массива с 10 элементами типа int так вес у неё 565 кб (Хотя архивируется она до 104 кб, но это сейчас опустим). Вопрос: а чего так много-то ?   :? У программы же даже граф.интерфейса нет да и сама программа небольшая ведь.

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

Оффлайн MetalliC

  • Технический консультант
  • Сообщений: 9386
  • Пол: Мужской
  • Demul team / MAME developer
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #39 : 25 Январь 2011, 23:26:55 »
gepar, не сравнивал в последнее время размеры, хотя тут при одинаковых проектах скорее дело в линковке, GCC(?) видимо более туповато линкует объектники и библиотеки, а VS выбирает только нужное из них.
« Последнее редактирование: 25 Январь 2011, 23:31:30 от MetalliC »

Оффлайн Planestranger

  • Пользователь
  • Сообщений: 1837
  • Пол: Мужской
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #40 : 26 Январь 2011, 00:08:13 »
Цитата: BmpCorp
работая с C#
по C# практически исчерпывающую инфу можно найти в справочнике Троелсена.

Оффлайн kamre

  • Пользователь
  • Сообщений: 8
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #41 : 26 Январь 2011, 00:19:59 »
kamre, насчет стека оно так и есть, на нем динамически резервируется и потом освобождается некое количество данных, структура/размер которых определяется кол-вом аргументов функции и локальных динамических (не статик) переменных
И каким образом это относится к типу "массив байтов" в языке C++?

Оффлайн HardWareMan

  • Модератор
  • Сообщений: 7527
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #42 : 26 Январь 2011, 06:21:50 »
И каким образом это относится к типу "массив байтов" в языке C++?
Ну как же. В данном контексте, размещать динамические переменные в стеке - это удел С++ как раз. Я бы никогда так делать не стал: юзал бы кучу. Но тупые программиЗды компиляторов С решили, что так лучше а другие это подхватили. И вот теперь мы имеем то, что мы имеем: дырки и уязвимости в виде переполнения буфера, пышто юзердата хранятся там же где и код. Поубывав бы нах.
« Последнее редактирование: 26 Январь 2011, 12:38:33 от HardWareMan »

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #43 : 27 Январь 2011, 15:24:06 »
HardWareMan, ну это делать лучше, проще и понятнее через массив, но тут была дана задача по принципу "а сможешь ли ты обходясь без массива сделать это, если сможешь то на практике когда все возможности с++ будут доступны уж точно сможешь" :)

Добавлено позже:
Разобрался тут слегка с массивами и стало интересно какой на с++ наиболее используемый (а значит самый удобный) среди программистов метод сортировки элементов массива?

Оффлайн HardWareMan

  • Модератор
  • Сообщений: 7527
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #44 : 28 Январь 2011, 06:53:39 »
Алгоритм сортировки не зависит от языка программирования.

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #45 : 29 Январь 2011, 14:56:40 »
Нашёл такую цацку как Beep  :)
#include <iostream>
#include <windows.h>

int main() {
Beep(659, 125);
Beep(659, 125);
Sleep(125);
Beep(659, 125);
Sleep(167);
Beep(523, 125);
Beep(659, 125);
Sleep(125);
Beep(784, 125);
Sleep(375);
Beep(392, 125);
Sleep(375);
Beep(523, 125);
Sleep(250);
Beep(392, 125);
Sleep(250);
Beep(330, 125);
Sleep(250);
Beep(440, 125);
Sleep(125);
Beep(494, 125);
Sleep(125);
Beep(466, 125);
Sleep(42);
Beep(440, 125);
Sleep(125);
Beep(392, 125);
Sleep(125);
Beep(659, 125);
Sleep(125);
Beep(784, 125);
Sleep(125);
Beep(880, 125);
Sleep(125);
Beep(698, 125);
Beep(784, 125);
Sleep(125);
Beep(659, 125);
Sleep(125);
Beep(523, 125);
Sleep(125);
Beep(587, 125);
Beep(494, 125);
Sleep(125);
Beep(523, 125);
Sleep(250);
Beep(392, 125);
Sleep(250);
Beep(330, 125);
Sleep(250);
Beep(440, 125);
Sleep(125);
Beep(494, 125);
Sleep(125);
Beep(466, 125);
Sleep(42);
Beep(440, 125);
Sleep(125);
Beep(392, 125);
Sleep(125);
Beep(659, 125);
Sleep(125);
Beep(784, 125);
Sleep(125);
Beep(880, 125);
Sleep(125);
Beep(698, 125);
Beep(784, 125);
Sleep(125);
Beep(659, 125);
Sleep(125);
Beep(523, 125);
Sleep(125);
Beep(587, 125);
Beep(494, 125);
Sleep(375);
Beep(784, 125);
Beep(740, 125);
Beep(698, 125);
Sleep(42);
Beep(622, 125);
Sleep(125);
Beep(659, 125);
Sleep(167);
Beep(415, 125);
Beep(440, 125);
Beep(523, 125);
Sleep(125);
Beep(440, 125);
Beep(523, 125);
Beep(587, 125);
Sleep(250);
Beep(784, 125);
Beep(740, 125);
Beep(698, 125);
Sleep(42);
Beep(622, 125);
Sleep(125);
Beep(659, 125);
Sleep(167);
Beep(698, 125);
Sleep(125);
Beep(698, 125);
Beep(698, 125);
Sleep(625);
Beep(784, 125);
Beep(740, 125);
Beep(698, 125);
Sleep(42);
Beep(622, 125);
Sleep(125);
Beep(659, 125);
Sleep(167);
Beep(415, 125);
Beep(440, 125);
Beep(523, 125);
Sleep(125);
Beep(440, 125);
Beep(523, 125);
Beep(587, 125);
Sleep(250);
Beep(622, 125);
Sleep(250);
Beep(587, 125);
Sleep(250);
Beep(523, 125);
Sleep(1125);
Beep(784, 125);
Beep(740, 125);
Beep(698, 125);
Sleep(42);
Beep(622, 125);
Sleep(125);
Beep(659, 125);
Sleep(167);
Beep(415, 125);
Beep(440, 125);
Beep(523, 125);
Sleep(125);
Beep(440, 125);
Beep(523, 125);
Beep(587, 125);
Sleep(250);
Beep(784, 125);
Beep(740, 125);
Beep(698, 125);
Sleep(42);
Beep(622, 125);
Sleep(125);
Beep(659, 125);
Sleep(167);
Beep(698, 125);
Sleep(125);
Beep(698, 125);
Beep(698, 125);
Sleep(625);
Beep(784, 125);
Beep(740, 125);
Beep(698, 125);
Sleep(42);
Beep(622, 125);
Sleep(125);
Beep(659, 125);
Sleep(167);
Beep(415, 125);
Beep(440, 125);
Beep(523, 125);
Sleep(125);
Beep(440, 125);
Beep(523, 125);
Beep(587, 125);
Sleep(250);
Beep(622, 125);
Sleep(250);
Beep(587, 125);
Sleep(250);
Beep(523, 125);
Sleep(625);
    /*for(int i = 0; i < 100; i++)
            printf("\a");*/
    system("pause >> void");
}

Оффлайн AjaxVS

  • Пользователь
  • Сообщений: 305
    • Youtube
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #46 : 29 Январь 2011, 21:23:48 »
Нашёл такую цацку как Beep  :)
ого, классно получилось  :drinks:
я в 2002 году тоже такой фигней страдал. только Du Hast рамштайна.

Цитата: gepar
какой на с++ наиболее используемый (а значит самый удобный) среди программистов метод сортировки элементов массива?
хех, я вот задумался и так и не смог вспомнить, когда я применял собственные функции сортировки кроме универа. в реале то юзается TListBox, std::list или подобные классы со встроенными "sort()" методами.

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #47 : 03 Февраль 2011, 20:58:04 »
Блин, почему это не работает:
# include <iostream>
# include <iomanip>
# include <ctime>
# include <cstdlib>
using namespace std;

void space (char *);
int main()
{
    char temp[100]={0};
    char *article[]={"the", "a", "one", "some", "any"};
    char *noun[]={"boy", "girl", "dog", "town", "car"};
    char *verb[]={"drove", "jumped", "ran", "walked", "skipped"};
    char *preposition[]={"to", "from", "over", "on"};
    for(int i=1;i<20;i++)
    {
        strcpy(temp,article[rand()%5]);
        space(temp);
        strcat(temp,noun[rand()%5]);
        space(temp);
        strcat(temp,verb[rand()%5]);
        space(temp);
        strcat(temp,preposition[rand()%4]);
        space(temp);
        strcpy(temp,article[rand()%5]);
        space(temp);
        strcat(temp,noun[rand()%5]);
        cout<<temp<<endl;
    }
}

void space(char *a)
{
    strcat(a," \0");
}

У меня уже сдают нервы от этой стандартной функции strcat, которая должна дописывать вторую строку к первой. Какого хрена она на опред. этапе берёт да и перезаписывает нафиг текущую строку? Или это у меня где-то здесь ошибка.

Добавлено позже:
Уже разобрался, у меня там по середине один strcpy был, что и сбивало всё.

Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #48 : 03 Февраль 2011, 21:31:43 »
gepar, не сравнивал в последнее время размеры, хотя тут при одинаковых проектах скорее дело в линковке, GCC(?) видимо более туповато линкует объектники и библиотеки, а VS выбирает только нужное из них.
Скомпилируй под VS без зависимостей от рантайма (чтобы не требовало всяких C++ Redistributable) - удивишься. Хотя, для простых программок с парой стандартных хидеров может и всё равно, а вот у меня простенькое клиент-серверное приложение на обычном винапи весило больше приложений с борландовским VCL. А для GCC используй флаг -s, если так печёшься о размере. Не понимаю связи размера файла и "тупости" линкера... Тупость обычно - удел пользователей (т.е. программистов, в данном случае). Хотя в целом GCC есть за что ругать, да. Но на ту же VS я бы побольше поматерился.

P.S. Надеюсь, вы размеры не в дебаг-конфигурации меряете?
« Последнее редактирование: 03 Февраль 2011, 21:38:11 от HoRRoR »

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #49 : 03 Февраль 2011, 21:44:17 »
Что-то указатели после паскаля тяжело даются (их ведь там не было  :) ).
Собственно вопрос: почему так можно:
char *a;
a="(555)5555555";
А вот так нельзя:
    char *a;
    cout<<"Enter number: ";
    cin>>a; //Ввести с клавиатуры (555)5555555 или просто какое-то число
?

Оффлайн DeniSS

  • Пользователь
  • Сообщений: 1088
  • Пол: Мужской
  • Сама скрытность
    • ВКонтакте
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #50 : 03 Февраль 2011, 22:05:25 »
Потому что это указатель, а не данные. . .
В общем, в первом случае ты записываешь данные по указателю, а во втором - пытаешься заставить указатель показывать на (555)5555555.
Юзай &a.

Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #51 : 03 Февраль 2011, 22:14:55 »
Что-то указатели после паскаля тяжело даются (их ведь там не было  :) )
Вообще-то, были. Принцип абсолютно тот же, что и в си. Разве что арифметика указателей там была реализована только с помощью Inc и Dec. Ну или мутить с преобразованием указателей в целочисленные типы.
@v ~ &v
v^ ~ *v

Добавлено позже:
gepar, в первом случае ты приравниваешь указателю адрес строки "(555)5555555". Во втором у тебя есть неинициализированный указатель (указывает хрен знает куда), и ты пытаешься считать по этому адресу (по сути по случайному адресу) данные. Он должен указывать на доступную область данных. Например, объяви его как char a[16]. Или выдели память с помощью malloc или new, и заставь указатель указывать на эту выделенную память:
char *a = new char[16];
или
char *a = (char*)malloc(16);

только потом надо вызвать delete или free, смотря чем ты выделял:

delete []a; или free(a);

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #52 : 03 Февраль 2011, 23:27:13 »
Цитата: HoRRoR
Например, объяви его как char a[16]
Ну это уже будет символьный массив, а я там хотел с указателем замутить всё ну да ладно. Тогда пусть буде так, спасибо за ответ.
Цитата: HoRRoR
Вообще-то, были.
Не знал.

Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #53 : 04 Февраль 2011, 00:16:32 »
Ну это уже будет символьный массив, а я там хотел с указателем замутить всё ну да ладно. Тогда пусть буде так, спасибо за ответ.Не знал.
Эээ... а как ты по-другому собираешься хранить строки?
Чтобы ты знал, статический массив в C++ - это суть есть константный указатель, указывающий на автоматически выделяемую область памяти. Т.е. всё равно, что char* const a. Для пущей достоверности создай функцию с прототипом foo(char* const a) и передай ей a, объявленную как char a[16]:
void foo(char* const a) // по-хорошему стоит сделать void foo(const char* const a), т.к. данные массива тоже не изменяются
{
  cout << a << endl;
}

int main()
{
  char a[16];
  strcpy(a, "string"); // или просто char a[] = "string";
  foo(a);
}

Однако, не всегда a[] эквивалентно *a. Например, sizeof(a) в первом случае вернёт размер массива, во втором - размер указателя (4 байта, что эквивалентно sizeof(&a[0]) в первом случае).
« Последнее редактирование: 04 Февраль 2011, 02:22:06 от HoRRoR »

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #54 : 04 Февраль 2011, 19:43:28 »
HoRRoR, но тогда у меня дальше возникают проблемы, если пользоваться просто массивом типа char то strcmp не хочет дописывать строку из одного массива в другой, ей только чтобы второй аргумент был указателем подавай:
    char t[100];
    char result[100];
    char a[]="This is a test string";
    char *b;
    char *c;
    b=strtok(a," ");//b=This
    c=strtok(NULL," ");//c=Is
    strcpy(result,b);// в result теперь This
    strcpy(t,result);// в t теперь This
    strcpy(result,c);//В result теперь Is
    strcmp(result,t);//Попытка дописать к result "This" но на самом деле ничего не происходит что видно при выводе
    cout<<result;
    return 0;
}

Оффлайн DeniSS

  • Пользователь
  • Сообщений: 1088
  • Пол: Мужской
  • Сама скрытность
    • ВКонтакте
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #55 : 04 Февраль 2011, 19:56:07 »
эээ... strcmp - это сравнение строк.

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #56 : 04 Февраль 2011, 20:05:52 »
Да твою налево. DeniSS, понял в чём ошибка. Я их всё время путаю эти функции для работы со строками, почему они только так названы что фиг запомнишь.

Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #57 : 04 Февраль 2011, 20:07:18 »
Дописывать - strcat(). А в a[] ты не допишешь, потому что надо выделять больше места (для того, чтобы было куда дописывать), а так оно чётко под строку. Пиши, к примеру, a[64], чтобы пустое место ещё оставалось.

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #58 : 04 Февраль 2011, 20:23:34 »
HoRRoR,да там цель была написать это:
//Выводит строку задом-наперёд

# include <iostream>
# include <iomanip>
# include <cstdlib>

using namespace std;
int main()
{
    char t[100]={0};
    char result[100]={0};
    char a[]="This is a test string";
    char *b;
    b=strtok(a," ");//b=This
    while (b!=NULL)
    {
       strcpy(t,result);
       strcpy(result,b);
       strcat(result," ");
       strcat(result,t);
       b=strtok(NULL," ");
    }
    cout<<result;
    return 0;
}

но у меня просто никак не получалось то что хотел вот я и убрал цикл и всё остальное и получился слегка кавардак.

Добавлено позже:
Ещё вопрос: как заставить работать strtok со строкой, но не сначала, а с n символа (в данном случае второго)?
Ато там есть одно задание где нужно разбить номер по типу (555)555-555. Так вот если я пытаюсь схитрить и задать strtok(a,")"). То за следующей попыткой strtok(NULL,")") оно возвращает (555 . Тоесть хитрость мою оно обходит  :)

Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #59 : 04 Февраль 2011, 20:45:37 »
Ты можешь взять адрес любого символа, с которого должна начинаться строка.
a[] = "12345678";
&a[0]; // "12345678"
&a[1]; // "2345678"
&a[2]; // "345678"
...
&a[7]; // "8"

Можно писать не &a[2], а a + 2 - суть одна.