Другое > Hard'n'Soft
Програмирование на C++
Planestranger:
--- Цитата: BmpCorp ---работая с C#
--- Конец цитаты ---
по C# практически исчерпывающую инфу можно найти в справочнике Троелсена.
kamre:
--- Цитата: MetalliC от 25 Января 2011, 21:31:22 ---kamre, насчет стека оно так и есть, на нем динамически резервируется и потом освобождается некое количество данных, структура/размер которых определяется кол-вом аргументов функции и локальных динамических (не статик) переменных
--- Конец цитаты ---
И каким образом это относится к типу "массив байтов" в языке C++?
HardWareMan:
--- Цитата: kamre от 26 Января 2011, 00:19:59 ---И каким образом это относится к типу "массив байтов" в языке C++?
--- Конец цитаты ---
Ну как же. В данном контексте, размещать динамические переменные в стеке - это удел С++ как раз. Я бы никогда так делать не стал: юзал бы кучу. Но тупые программиЗды компиляторов С решили, что так лучше а другие это подхватили. И вот теперь мы имеем то, что мы имеем: дырки и уязвимости в виде переполнения буфера, пышто юзердата хранятся там же где и код. Поубывав бы нах.
gepar:
HardWareMan, ну это делать лучше, проще и понятнее через массив, но тут была дана задача по принципу "а сможешь ли ты обходясь без массива сделать это, если сможешь то на практике когда все возможности с++ будут доступны уж точно сможешь" :)
Добавлено позже:
Разобрался тут слегка с массивами и стало интересно какой на с++ наиболее используемый (а значит самый удобный) среди программистов метод сортировки элементов массива?
HardWareMan:
Алгоритм сортировки не зависит от языка программирования.
gepar:
Нашёл такую цацку как 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:
--- Цитата: gepar от 29 Января 2011, 14:56:40 ---Нашёл такую цацку как Beep :)
--- Конец цитаты ---
ого, классно получилось :drinks:
я в 2002 году тоже такой фигней страдал. только Du Hast рамштайна.
--- Цитата: gepar ---какой на с++ наиболее используемый (а значит самый удобный) среди программистов метод сортировки элементов массива?
--- Конец цитаты ---
хех, я вот задумался и так и не смог вспомнить, когда я применял собственные функции сортировки кроме универа. в реале то юзается TListBox, std::list или подобные классы со встроенными "sort()" методами.
gepar:
Блин, почему это не работает:
--- Код: ---# 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:
--- Цитата: MetalliC от 25 Января 2011, 23:26:55 ---gepar, не сравнивал в последнее время размеры, хотя тут при одинаковых проектах скорее дело в линковке, GCC(?) видимо более туповато линкует объектники и библиотеки, а VS выбирает только нужное из них.
--- Конец цитаты ---
Скомпилируй под VS без зависимостей от рантайма (чтобы не требовало всяких C++ Redistributable) - удивишься. Хотя, для простых программок с парой стандартных хидеров может и всё равно, а вот у меня простенькое клиент-серверное приложение на обычном винапи весило больше приложений с борландовским VCL. А для GCC используй флаг -s, если так печёшься о размере. Не понимаю связи размера файла и "тупости" линкера... Тупость обычно - удел пользователей (т.е. программистов, в данном случае). Хотя в целом GCC есть за что ругать, да. Но на ту же VS я бы побольше поматерился.
P.S. Надеюсь, вы размеры не в дебаг-конфигурации меряете?
gepar:
Что-то указатели после паскаля тяжело даются (их ведь там не было :) ).
Собственно вопрос: почему так можно:
--- Код: ---char *a;
a="(555)5555555";
--- Конец кода ---
А вот так нельзя:
--- Код: --- char *a;
cout<<"Enter number: ";
cin>>a; //Ввести с клавиатуры (555)5555555 или просто какое-то число
--- Конец кода ---
?
DeniSS:
Потому что это указатель, а не данные. . .
В общем, в первом случае ты записываешь данные по указателю, а во втором - пытаешься заставить указатель показывать на (555)5555555.
Юзай &a.
HoRRoR:
--- Цитата: gepar от 03 Февраля 2011, 21:44:17 ---Что-то указатели после паскаля тяжело даются (их ведь там не было :) )
--- Конец цитаты ---
Вообще-то, были. Принцип абсолютно тот же, что и в си. Разве что арифметика указателей там была реализована только с помощью 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:
--- Цитата: HoRRoR ---Например, объяви его как char a[16]
--- Конец цитаты ---
Ну это уже будет символьный массив, а я там хотел с указателем замутить всё ну да ладно. Тогда пусть буде так, спасибо за ответ.
--- Цитата: HoRRoR ---Вообще-то, были.
--- Конец цитаты ---
Не знал.
HoRRoR:
--- Цитата: gepar от 03 Февраля 2011, 23:27:13 ---Ну это уже будет символьный массив, а я там хотел с указателем замутить всё ну да ладно. Тогда пусть буде так, спасибо за ответ.Не знал.
--- Конец цитаты ---
Эээ... а как ты по-другому собираешься хранить строки?
Чтобы ты знал, статический массив в 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]) в первом случае).
gepar:
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:
эээ... strcmp - это сравнение строк.
gepar:
Да твою налево. DeniSS, понял в чём ошибка. Я их всё время путаю эти функции для работы со строками, почему они только так названы что фиг запомнишь.
HoRRoR:
Дописывать - strcat(). А в a[] ты не допишешь, потому что надо выделять больше места (для того, чтобы было куда дописывать), а так оно чётко под строку. Пиши, к примеру, a[64], чтобы пустое место ещё оставалось.
gepar:
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:
Ты можешь взять адрес любого символа, с которого должна начинаться строка.
--- Код: ---a[] = "12345678";
&a[0]; // "12345678"
&a[1]; // "2345678"
&a[2]; // "345678"
...
&a[7]; // "8"
--- Конец кода ---
Можно писать не &a[2], а a + 2 - суть одна.
Навигация
Перейти к полной версии