Тролль Опубликовано 22 февраля, 2012 Жалоба Поделиться Опубликовано 22 февраля, 2012 (изменено) Иазяв Прошу объяснить, зачем здесь нужны указатели, на что они должны указывать и неужели оптимальным будет решение через указатели??? Указатели тут нужны как рыбке зонтик. Целью задания является потренировать в работе с указателями, но так как примеров, где они были бы нужны, у преподавателя не нашлось, то задание напоминает вычисление площади квадрата с помощью двойного интеграла. Делается все это очень просто, пишем нормальную программу, но вместо просто переменных используем указатели на них со звездочкой впереди :) Объявлены должны быть, естественно, не только указатели на переменные, но и сами переменные, но обращаться к ним мы будем только через указатели: желание начальника - закон для подчиненного ;) 1) #include <stdio.h>int main(){float fb,*pfb=&fb,fd,*pfd=&fd,fe,*pfe=&fe; printf("Enter two numbers: "); scanf("%f%f",pfb,pfd); *pfe=*pfb+*pfd; printf("sum=%f\n",*pfe); getchar(); getchar(); return 0;} 2) #include <stdio.h>int main(){char q,*pq=&q; float fb,*pfb=&fb,fd,*pfd=&fd,fe,*pfe=&fe; char s[40];printf("Enter the expression: "); scanf(" %f %c %f",pfb,pq,pfd);switch(*pq){case '+':*pfe=*pfb+*pfd;break; case '-':*pfe=*pfb-*pfd;break; case '*':*pfe=*pfb**pfd;break; case '/':*pfe=*pfb/ *pfd;break;}printf("%f %c %f = %f\n",*pfb,*pq,*pfd,*pfe); getchar(); getchar(); return 0;} Тут выражение (может быть только одна операция) в калькулятор вводится одной строкой в виде, например, 5+2 3) #include <stdio.h>int main(){float fb=1,*pfb=&fb; int k,*pk=&k,n,*pn=&n; printf("n: "); scanf("%d",pn); for(*pk=1;*pk<=*pn;(*pk)++)*pfb*=*pk; printf("fact=%f\n",*pfb); getchar(); getchar(); return 0;} 4) #include <stdio.h>#include <math.h>int main(){float a,*pa=&a,b,*pb=&b; printf("a b: "); scanf("%f%f",pa,pb); printf("a^b=%f\n",pow(*pa,*pb)); getchar(); getchar(); return 0;} 5) #include <stdio.h>int main(){float a,*pa=&a,b,*pb=&b,**ppb=&pb; printf("a b: "); scanf("%f%f",pa,pb); if(**ppb)printf("a/b=%f\n",*pa/ *pb);else printf("It is impossible to divide by null!\n"); getchar(); getchar(); return 0;} Изменено 22 февраля, 2012 пользователем Тролль 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
Иазяв Опубликовано 22 февраля, 2012 Жалоба Поделиться Опубликовано 22 февраля, 2012 Тролль, извиняюсь, но мне не программа нужна, а объяснение. Я упрямая до ужаса. На меня не действует приказ начальника, если приказ тупой, глупый, бессмысленный и т.п., поэтому со мной трудно. Я стараюсь делать код максимально простым, искать самое сжатое решение, концентрированное (надеюсь, я понятно объясняю). Правда, с учетом недолгого изучения и отсутствия должной практики не всегда использую самый рациональный способ решения, но я стараюсь. Честно стараюсь. И в этих задачах я не вижу смысла использовать указатели. (Хотя если Вы объясните мне об указателях... мечта!) Разве не лучше просто решить? Или я не понимаю чего-то высшего? Ссылка на комментарий Поделиться на другие сайты Поделиться
Тролль Опубликовано 22 февраля, 2012 Жалоба Поделиться Опубликовано 22 февраля, 2012 (изменено) Иазяв Быть упрямой - это хорошо :) А "Я стараюсь делать код максимально простым, искать самое сжатое решение, концентрированное" - просто замечательно. Не только по сути, но и по сжатому и концентрированному стилю выражения мыслей. Хорошо, когда так получается. Правда, чаще бывает как у Блеза Паскаля: "Извините, что написал так много. У меня не было времени написать коротко" ;) В этих задачах не было никакого смысла использовать указатели. Это просто для того, чтобы вы поняли, как с ними обращаются. В этих задачах их использование совершенно нерационально, но как объявить указатель, присвоить ему адрес другой переменной (или даже другого указателя) и получить с помощью указателя значение переменной, на которую он указывает, тут вы потренировались. Убедились, что указатели существуют и работают, даже если они тут совершенно не были нужны. Об указателях. Указатель - довольно примитивная вещь. Это переменная, в которой содержится адрес другой переменной. Ей можно присвоить адрес другой переменной при помощи операции взятия адреса &, и можно обратиться к переменной, адрес которой записан в указателе, с помощью операции * (операции разыменования). Примеры приводить не буду, их в этих программах выше головы. Этой "другой переменной", кстати, может быть и другой указатель. Чтобы пройти по всей цепочке, операции & и * можно использовать в таких случаях многократно. Например, **b - пройти по адресу, хранящемуся в b, взять из переменной по этому адресу следующий адрес, пройти по нему и взять значение из переменной по этому второму адресу. Еще раз - в этих задачах все эти страсти были на самом деле абсолютно не нужны, они только запутывают программу, вам было сказано просто убедиться, что они возможны. Когда они полезны и нужны, распространяться не буду - нужны они в сложных структурах данных, например, в списках. Еще об указателях надо знать, что к их содержанию можно прибавлять числа, причем, что сначала совершенно неочевидно, для удобства использования этих операций числа в таких случаях автоматически умножаются на размер в байтах переменной, на которую ссылается указатель, так что для указателя с именем p выражение р+1 дает адрес вовсе не следующего байта после адреса, хранящегося в р, а адреса следующей переменной (а переменная может занимать несколько байтов). Можно также вычитать указатели одного типа друг из друга, размер будет опять же не в байтах, а в размерах переменных, на которых ссылаются указатели. Эта так называемая "арифметика указателей" в этих программах не использовалась, но вы с ней, видимо, еще встретитесь. С и C++ меньше всего предназначены для начального обучения. Это языки, созданные профессионалами для самих себя по принципу "два пишем, три в уме", заранее предполагающие хорошее знание устройства компьютеров, своего рода стенография записи программ для опытных программистов. В качестве примера: *pfb**pfd; Тут средняя звездочка - знак умножения, а крайние - знаки операций разыменования. Можно было, правда, для большей понятности вставить пробелы: *pfb * *pfd; , но я люблю кратчайшую запись ;) Изменено 23 февраля, 2012 пользователем Тролль 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
Иазяв Опубликовано 23 февраля, 2012 Жалоба Поделиться Опубликовано 23 февраля, 2012 Тролль, скачала несколько задач, где на первый взгляд использование указателей оправдано. Буду разбираться. Большое спасибо за ответ. Ссылка на комментарий Поделиться на другие сайты Поделиться
ludman Опубликовано 23 февраля, 2012 Жалоба Поделиться Опубликовано 23 февраля, 2012 помогите пожалуста с легенькой задачей на фортране: Переставить слова в тексте так, чтобы они были упорядочены по длине. Ссылка на комментарий Поделиться на другие сайты Поделиться
ludman Опубликовано 23 февраля, 2012 Жалоба Поделиться Опубликовано 23 февраля, 2012 И еще одна: Исходный файл состоит из компонент вида -фио сотрудника -год рождения -образование(из фиксированного перечня/перечисляемый тип/) -должность(инженер, мастер, лаборант и т.д.- из фиксированного перечня) -стаж работы Сформировать файл для указанной должности с указанным образованием. Упорядочить его по году рождения и вычислить средний стаж работы этих сотрудников. зарание большое спасибо. Ссылка на комментарий Поделиться на другие сайты Поделиться
Иазяв Опубликовано 23 февраля, 2012 Жалоба Поделиться Опубликовано 23 февраля, 2012 Даны два массива, мне надо их сравнить и те элементы, что не содержатся во втором массиве, записать в третий. Почему функция работает только в том случае, если первый массив больше первого? int findElements (int *Ar1, int *Ar2, int *Ar3, const int a1, const int a2, int z) { for (int i = 0; i < a1; i++){ bool flag = false; for (int j = 0; !flag && (j < a2); j++) flag = (Ar1 [i] == Ar2 [j]); for (int r = 0; !flag && (r < z); r++) flag = (Ar1 [i] == Ar3 [r]); if (!flag) Ar3 [z++] = Ar1 [i];}return true;} Ссылка на комментарий Поделиться на другие сайты Поделиться
Тролль Опубликовано 23 февраля, 2012 Жалоба Поделиться Опубликовано 23 февраля, 2012 (изменено) Иазяв Во-первых, переменную z надо инициализировать z=0; Или же надо при обращении давать параметру, соответствующему z, значение 0. Что нехорошо - лишнее действие, и вдруг забудем... Потому что если значение не задано, оно может быть изначально чем угодно. Во-вторых, длину массива A3 после выхода из функции никто не знает. Внутренней переменной z присваивается значение из обращения к функции, но после выполнения функции эта внутренняя переменная уничтожается без всякой передачи значения обратно. Так что значение переменной на месте z после вызова функции останется таким же, как было. Чтобы передать значение z обратно, в С надо было передавать в функцию не z, а адрес z и его при использовании в функции каждый раз разыменовывать операцией * - вот и пример необходимости работы с адресами в С. Правда, у нас есть и возможность, раз уж такая переменная у нас одна, передавать ее измененное значние в качестве значения самой функции. Но если бы таких переменных, значения которых надо возвращать, было несколько, пришлось бы все равно работать с адресами. А в C++ появилась третья возможность, самая удобная - так называемые ссылки, то есть автоматически разыменовываемые указатели. При объявлении функции в ее заголовке надо писать тогда не int z , а int &z, при этом передастся не значение внешней переменной, а ее адрес. Но в теле функции при каждом упоминании z будет браться не адрес, а внешняя переменная, адрес которой был передан. Так что после окончания работы функции в переменной останется новое значение. Ну и не ошибка, но неясно, зачем тип функции объявлять int, да еще и зачем-то возвращать в него значение true. Раз нам значение имени функции не нужно, объявим его типа void, и ничего присваивать ему не будем. Тогда заголовок функции будет выглядеть так: void findElements (int *Ar1, int *Ar2, int *Ar3, const int a1, const int a2, int &z) В самой же функции надо только в начале добавить z=0; и в конце выкинуть return true; И вроде бы все должно работать... Изменено 23 февраля, 2012 пользователем Тролль 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
Иазяв Опубликовано 24 февраля, 2012 Жалоба Поделиться Опубликовано 24 февраля, 2012 Переделала на такой вариант. По ссылке у меня не получилось почему-то. Вернее, не заработала корректно. int findElements (int *Ar1, int *Ar2, int *Ar3, const int a1, const int a2) { int z = 0;for (int i = 0; i < a1; i++){ bool flag = false; for (int j = 0; !flag && (j < a2); j++) flag = (Ar1 [i] == Ar2 [j]); for (int r = 0; !flag && (r < z); r++) flag = (Ar1 [i] == Ar3 [r]); if (!flag) Ar3 [z++] = Ar1 [i];}return z;} Теперь заработало, хотя мне сказали, что можно еще более оптимизировать функцию. Буду думать. Ссылка на комментарий Поделиться на другие сайты Поделиться
Тролль Опубликовано 24 февраля, 2012 Жалоба Поделиться Опубликовано 24 февраля, 2012 (изменено) Иазяв По ссылке у меня не получилось почему-то.Попробовал, #include<iostream>using namespace std;void findElements(int *Ar1,int *Ar2,int *Ar3,const int a1,const int a2,int &z){ z=0; for(int i=0;i<a1;i++){ bool flag=true; for(int j=0;flag&&j<a2;j++)flag=Ar1[i]!=Ar2[j]; for(int r=0;flag&&r<=z;r++)flag=Ar1[i]!=Ar3[r]; if (flag)Ar3[z++]=Ar1[i];}}int main(){int Ar1[]={1,2,3,3,7,8,9},Ar2[]={2,4,6,8,10,12,14,16,18};const int a1=sizeof(Ar1)/sizeof(int),a2=sizeof(Ar2)/sizeof(int);int Ar3[a1],z;findElements(Ar1,Ar2,Ar3,a1,a2,z);for(int i=0;i<z;i++)cout<<Ar3[i]<<' '; cin.get();} вроде все работает. Тут объявление массивов такое для удобства тестирования, чтобы можно было менять их содержание просто вписывая или убирая числа при объявлении. Насчет оптимальности - по-моему, у тебя все просто и логично, как сделать проще, не вижу. В принципе работу программы на больших массивах можно было бы ускорить за счет значительного усложнения алгоритма, но тут не вижу смысла добиваться наивысшего быстродействия. Изменено 24 февраля, 2012 пользователем Тролль Ссылка на комментарий Поделиться на другие сайты Поделиться
Иазяв Опубликовано 24 февраля, 2012 Жалоба Поделиться Опубликовано 24 февраля, 2012 Тролль Можно задать еще один вопрос про указатели? Почему при вызове функции вывода массива на экран мы ее передаем просто? А функцию добавления элемента в массив по указателю? void printArray (int *Array, int s){for (int i = 0; i < s; i++){ cout << Array [i] << '\t';}cout << endl;}int *addElement (int *Array, int &s, int c) // добавляем элемент в конец массива{int *tmp = new int [++s];for (int i = 0; i < s; i++) tmp [i] = Array [i];tmp [s - 1] = c;delete [] Array;return tmp;} Когда в функциях лучше всего возвращать true? Уже не помню, в этой или какой-то другой функции true почему-то не возвращалось. P.S. Извиняюсь за такое количество пробелов в коде и лишних строчках - я так пишу, чтобы не напрягать сильно глаза и можно было долго работать за компьютером (у меня проблемы со зрением). Ссылка на комментарий Поделиться на другие сайты Поделиться
Тролль Опубликовано 24 февраля, 2012 Жалоба Поделиться Опубликовано 24 февраля, 2012 (изменено) Иазяв Что мы делаем во второй функции (addElement)? Создаем новый массив с длиной на единицу больше, переписываем в него содержимое старого (кстати, та еще работенка при больших массивах), добавляем в конец новый элемент, уничтожаем старый массив и возвращаем в имени функции адрес нового массива. А в первой функции нам возвращать просто нечего - ну, вывели на экран и вывели, что возвращать? Часто функции возвращать просто ничего не нужно или она обходится возвращением значений через список параметров, тогда возможность возврата значения через имя функции можно использовать просто для того, чтобы иметь возможность сообщить, что при выполнении функции не возникло никаких ошибок (или, наоборот, что что-то не вышло). Для этого хорошо подходит булевский тип. В С и C++ возвращаемое функцией значение ведь не обязательно использовать, поэтому мы можем вызвать такую функцию с проверкой, все ли прошло хорошо, или же игнорировать возвращаемое функцией значение - если мы уверены, что все пройдет хорошо или нам лень это проверять. По поводу второй функции замечу еще, что в C++ для всего этого в его библиотеках есть специальные функции, написанные гораздо лучше (например, если надо добавить в массив элемент, он расширяется сразу на много элементов, с запасом, и следующие элементы при добавлении будут просто дописываться, пока не кончится запас, а переписываться заново массив будет только когда этот запас кончится). Но все это у вас еще впереди, когда будете разбираться с создаваемыми пользователем и стандартными структурами для записи и обработки данных (классами). Насчет пробелов в тексте - многие их любят, и обычно их вставка считается хорошим стилем оформления кода. Но лично мне кажется более удобным, когда все записано компактно - все сразу перед глазами, и не надо далеко бегать глазами по тексту программы. Но Вы-то пишите, как Вам удобнее :) Изменено 24 февраля, 2012 пользователем Тролль Ссылка на комментарий Поделиться на другие сайты Поделиться
Иазяв Опубликовано 25 февраля, 2012 Жалоба Поделиться Опубликовано 25 февраля, 2012 Тролль Неправильный пример я привела. Пусть будет сравнение функций, которые обе возвращают что-то - addElement и findElements (мой вариант, т.к. он типа int и там возвращается z). Одна с указателем, другая нет. Почему так надо? Классы я очень жду, но нам сказали, нескоро это чудо нас ждет. А я жду. Когда нам рассказали про структуры, я очень обрадовалась - во-первых, что-то новое, во-вторых, больше возможностей и шире простор. :rolleyes: P.S. Спасибо, что возитесь со мной! Ссылка на комментарий Поделиться на другие сайты Поделиться
Тролль Опубликовано 25 февраля, 2012 Жалоба Поделиться Опубликовано 25 февраля, 2012 Иазяв addElement рассчитана на то, чтобы возвращать в качестве результата новый созданный ею массив (в имени функции будет содержаться адрес его начала), findElements возвращает значение одинарной переменной типа int (количество использованных элементов в уже существовавшем до ее вызова массиве). Поэтому у них разные типы. Если я правильно понял вопрос. во-первых, что-то новое, во-вторых, больше возможностей и шире просторНу, нового в C++ еще надолго хватит :) Основное отличие C++ от C - это что C++ был задуман не просто как язык, а как метаязык (расширяемый язык), который можно расширять новыми понятиями, создавая свой язык более высокого уровня. В C++ можно вводить новые типы данных, определить для них свои операции, изменив значение всяких знаков вроде =, >, +, -, *, ++ и так далее вплоть до изменения значения скобок [ и ]. И многие такие расширения языка уже заранее реализованы в нем в виде множества готовых библиотек классов. Вас будут, вероятно, для тренировки мучить написанием своих вариантов всякой такой всячины, но часто это уже есть в стандартных библиотеках C++ готовое и отшлифованное. Ссылка на комментарий Поделиться на другие сайты Поделиться
Иазяв Опубликовано 25 февраля, 2012 Жалоба Поделиться Опубликовано 25 февраля, 2012 Тролль Получается, если функция что-то меняет, делает то, чего раньше не было, то она будет с "*" ? А если возвращает то, что было - без? Сегодня поняла, что не хватает навыка работы со строками. Структуры очень тесно связаны с ними. Сейчас изучаю функции строк. Заметила, что иногда пишут "char* gets", а иногда "char *gets". Есть ли разница? Как должно быть? Не понимаю, зачем используются указатели на указатели? Неужели нет путей проще для запроса к многомерным массивам? Завтра сяду за указатели. Сильно отстала из-за их непонимания, а из-за изучения дополнительных материалов (чтобы понять) в чем-то ушла вперед. Тяжко теперь на занятиях. Вас будут, вероятно, для тренировки мучить написанием своих вариантов Уже мучают. Писали, например, функцию математического округления. Ведь есть стандартные, я это еще из пхп знала. Поэтому я и радуюсь новым инструментам, новым возможностям. Практики мало и времени для монументального разбора. Ссылка на комментарий Поделиться на другие сайты Поделиться
Форматцевт Опубликовано 26 февраля, 2012 Жалоба Поделиться Опубликовано 26 февраля, 2012 Вопрос к Троллью или к тем кто знает PascalABC.NET (Писать по сути то ничего не надо, а просто подсказать.) И так. Есть некая программа на PascalABC.NET которая выполняет следующее. Процесс №1. Сканирует, а не ожидает нажатия на клавишу, т.е. function ReadChar: integer; Возвращает значение типа char, введенное с клавиатуры не подходит, т.к. тут ожидание.Так же данный процесс различает однократное нажатие и удержание (анализ скан-кодов) Процесс №2. По результатам Процесса №1, т.е. анализа клавиши производит некие вычисления. Процесс №3. Вывод на экран идёт не прерывно на основе вычисления Процесса №2 P.S. Готовых функций в PascalABC.NET я не нашёл или быть может проглядел. (OS Win 7 x64) Ссылка на комментарий Поделиться на другие сайты Поделиться
Тролль Опубликовано 26 февраля, 2012 Жалоба Поделиться Опубликовано 26 февраля, 2012 Indomito В PascalABC.NET я не разбирался, хотя знаю, что там нет использовавшихся в Turbo в таких случаях keypressed и readkey и люди выкручиваются через WinAPI или другими ухищрениями, хотя - выкручиваются, а в смысле где смотреть - посмотри ЛС, чтобы тут не мусорить... Ссылка на комментарий Поделиться на другие сайты Поделиться
Тролль Опубликовано 26 февраля, 2012 Жалоба Поделиться Опубликовано 26 февраля, 2012 (изменено) Иазяв если функция что-то меняет, делает то, чего раньше не было, то она будет с "*" ? А если возвращает то, что было - без?Пожалуй, да. Потому что если функция создает какую-то новую переменную, она требует выделить ей для этого память, и ей будет надо передать адрес этой памяти в окружающий мир, чтобы кто-нибудь мог ею воспользоваться. Практически не стоит над этим задумываться. Когда нам что-нибудь надо, и так будет ясно, чего именно хочется. Сегодня поняла, что не хватает навыка работы со строками. Структуры очень тесно связаны с ними. Сейчас изучаю функции строк. Структуры со строками связаны не больше, чем с другими типами переменных, просто в учебных примерах часто в структурах используют строки. Для строк в С определена куча разных функций. Как всегда, полезно знать, что имеется в библиотеке, но как именно использовать конкретные функции, помнить не надо - когда знаешь, что именно можно применить, прочитать к этому простенькую инструкцию из справочника о деталях использования легко. Кстати, в C++ есть усовершенствованный тип строк string на основе классов, но сначала надо разобраться с базовым. Заметила, что иногда пишут "char* gets", а иногда "char *gets". Есть ли разница? Как должно быть?char *gets и char* gets, а также char * gets и char*gets - одно и то же. А можете и char(*gets) написать. Тут звездочка - обычная операция разыменования. Мы говорим компилятору, что то, что получится при разыменовании gets (то есть если пройти по адресу, хранящемуся в gets), будет типа char. Объявления сложных типов - не заклинания, а описания действий, которые надо произвести с объявленной переменной, чтобы прийти к объявленному в начале объявления типу. Впрочем, часто они, как и все в C++, действительно выглядят как заклинания. Ну что ж, программирование мало отличается от магии ;) Не понимаю, зачем используются указатели на указатели? Неужели нет путей проще для запроса к многомерным массивам?Есть, конечно. Никто не мешает объявить массив Ar[3][4][5] и работать с его элементами так: Ar[2][1][0]=5; Но для обоснования "зачем" есть два "но". Первое: когда-то для работы с массивами использовалась арифметика указателей, то есть увеличивали адрес в указателе. Потом придумали ввести в языки программирования индексы, и *(a+3) стало можно записать удобнее (так называемый "синтаксический сахар") как a[3]. Но для совместимости со старыми программами и старыми программистами в С и C++ осталась возможность работать с массивами и по-старому через указатели, и вас учат обоим способам работы с массивами - очень старому и не очень старому ;) Второе: указатели гибче. Из функции я могу вернуть указатель на созданный в ней массив, но не сам массив как выданный функцией результат. Кроме того, я могу объявить прямоугольный массив a[3][4], но не могу так объявить непрямоугольный массив, у которого в первой строке 4 элемента, во второй 5, а третьей 8. А с указателями я так могу - массив из трех указателей, каждый из которых указывает на свой одномерный массив. Или, при динамическом создании (во время работы программы) - указатель на массив из трех указателя, каждый из которых указывает на свой одномерный массив. Вообще к любому языку, а к C++ в особенности, не надо подходить как к кладезю сверхчеловеческой мудрости. Правильнее подходить к нему как к тришкину кафтану. Языки развивались десятилетиями, перенимая друг от друга по возможности полезные средства и накладывая их на старые сверху. Поэтому многие средства дублируют друг друга или имеют еще пару-тройку улучшенных вариантов - кто-то написал что-то для чего-то, потом это улучшил, но для совместимости и старый вариант остался, еще кто-то тоже написал что-то похожее, и теперь у нас глаза разбегаются... Изменено 26 февраля, 2012 пользователем Тролль 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
Форматцевт Опубликовано 26 февраля, 2012 Жалоба Поделиться Опубликовано 26 февраля, 2012 Тролль ...и люди выкручиваются через WinAPI или... я так и подумал... жаль конечно - думал есть что - то, а я проглядел. :cool: Ссылка на комментарий Поделиться на другие сайты Поделиться
Форматцевт Опубликовано 26 февраля, 2012 Жалоба Поделиться Опубликовано 26 февраля, 2012 Иазяв о стиле написания и т.д. Рекомендую не путать себя жуткими конструкциями и максимально комментировать, иначе, как говорил один из авторов локализатора языка forth: "Вечером написал, а с утра не могу понять что я написал." :D Вот пример - как надо, хотя это не С++, а JS но суть та же... Ну и я конечно не идеален - каюсь, 80% комментов пропали в процессе модификации. /*Initialization Code*/// Версия от 10.02.2011// Автор - Indomito// Благодарность за помощь - Infocatcher//*********************************************************************// ----------------Можно менять значения констант ---------------------// ------------------------BEGIN DEF-----------------------------------const cEICB = "Export.Import.CB.type.HTML";const cPathEI = "C:\\Custom Buttons\\Сохранение кнопок\\";const cPathSetMsg = "Надо установить путь для чтения/записи кнопок";const csExpT = "Экспорт кнопок в HTML";const csExpOneT ="Экспорт одной кнопки в HTML";const csExpOneMsg ="Выберите имя кнопки"; const csImpT = "Импорт кнопок из HTML";const csSetIET = "Каталог для Экспорта/Импорта кнопок в/из HTML";const dProc = 0.30; // процент открытия выбора окна кнопок, при dProc = 0.30 это 30% кнопок от общего числаconst csNoNameBT = "Для этой кнопки не определено имя";const csNoBT = "Это не кнопка";const spcTn = "=================================";const spcTm = " Не активные кнопки";this.tooltipText = "Shift+Left => Записать одну кнопку"+ "\nLeft => Записать все кнопки"+ "\nMiddle => Каталог записи/чтения кнопок"+ "\nRight => Считать все кнопки";// -------------------------END DEF-----------------------------------//*********************************************************************// Обработчик событий по нажатию кнопок мыши с/без модификаторами//*********************************************************************this.onclick = function(event) { if(event.button == 0 && event.shiftKey) {// Действие при клике shift+ЛКМshKeylbMouse(); } else if(event.button == 0) {// Действие при клике ЛКМlbMouse(); } else if(event.button == 1) { // Действие при клике СКМmbMouse(); } else if(event.button == 2 && !event.ctrlKey &&!event.shiftKey && !event.altKey && !event.metaKey) { // Действие при клике ПКМ без модификаторовrbMouse(); }};this.oncontextmenu = function(event) { if(event.button == 2 && !event.ctrlKey &&!event.shiftKey && !event.altKey && !event.metaKey) { // Блокируем контекстное меню при клике ПКМ без модификаторов event.preventDefault(); event.stopPropagation(); }};//*********************************************************************//Запись одной кнопки по выборуfunction shKeylbMouse(){if (chkPath(Application.prefs.getValue(cEICB, 0)) != 1) { custombuttons. alertBox (csExpT, cPathSetMsg); return; }var name = []; //массив имён кнопок для выводаvar namea = []; //массив имён кнопок активныхvar namep = []; //массив имён кнопок не активныхvar i,j, buts;buts = document. getElementsByTagName ("toolbarbutton");for (i = 0, j = 0; i < buts. length; i++) if (buts[i].getAttribute("id").indexOf("custombuttons-button")==0 && typeof(buts [i].name)=="string") namea[j++] = buts [i]. name;namea.sort(cmp);namea.splice(j,0,spcTn,spcTm,spcTn);buts = custombuttons. palette. getElementsByTagName ("toolbarbutton");for ( i = 0, j = 0; i < buts. length; i++) if (buts [i]. getAttribute ("id"). indexOf ("custombuttons-button") == 0&&typeof(buts [i].getAttribute ("label"))=="string") namep[j++] = buts [i]. getAttribute ("label");namep.sort(cmp);name=namea.concat(namep);// Открытие модального окна выбора имён кнопок с учётом общего числа кнопокvar rowsCount = name.length * dProc; var oSvc = Components.classes["@mozilla.org/observer-service;1"] .getService(Components.interfaces.nsIObserverService);var observer = { added: true, observe: function(subject, topic, data) { subject.addEventListener("load", this, false); }, handleEvent: function(e) { var doc = e.target; var win = doc.defaultView; win.removeEventListener("load", this, false); if(doc.location.href != "chrome://global/content/selectDialog.xul") return; oSvc.removeObserver(this, "domwindowopened"); this.added = false; var list = doc.getElementById("list"); if(list) list.setAttribute("rows", rowsCount); }};oSvc.addObserver(observer, "domwindowopened", false);var selected = {};var bRt = Components.classes["@mozilla.org/embedcomp/prompt-service;1"] .getService(Components.interfaces.nsIPromptService) .select(window, csExpOneT, csExpOneMsg, name.length, name, selected )observer.added && oSvc.removeObserver(observer, "domwindowopened");if (!bRt) return; // Отмена - выходelse if (spcTm==name[selected.value]||spcTn==name[selected.value]) { custombuttons. alertBox (csExpOneT, csNoBT); return; } else if (name[selected.value]=="") { custombuttons. alertBox (csExpOneT, csNoNameBT); return; } //OK - начинаем обрабоку и запись выбранной кнопкиvar mydir=Application.prefs.getValue(cEICB, 0), myfilename=name [selected.value]; var fp = Components.classes["@mozilla.org/filepicker;1"] .createInstance(Components.interfaces.nsIFilePicker); fp.init(window, csExpOneT, fp.modeSave); var dd = Components.classes["@mozilla.org/file/local;1"] .createInstance(Components.interfaces.nsILocalFile);dd.initWithPath(mydir); //Путь который установленfp.displayDirectory = dd;fp.defaultString = myfilename+".html";if(fp.show() != fp.returnCancel) custombuttons. alertBox (csExpOneT, "Кнопка "+myfilename+" сохранена в \n"+ saveCB(fp.file.path, myfilename));//****** DefSub//Сортировка строк по возрастаниюfunction cmp(a, b) { if (a.toUpperCase() > b.toUpperCase()) return 1; if (a.toUpperCase() < b.toUpperCase()) return -1; return 0;};//****** EndDefSub};//*********************************************************************//Записать кнопкиfunction lbMouse(){if (chkPath(Application.prefs.getValue(cEICB, 0)) != 1) custombuttons. alertBox (csExpT, cPathSetMsg);else {var mydir=Application.prefs.getValue(cEICB, 0), myfilename = GenFileName(); var fp = Components.classes["@mozilla.org/filepicker;1"] .createInstance(Components.interfaces.nsIFilePicker); fp.init(window, csExpT, fp.modeSave); var dd = Components.classes["@mozilla.org/file/local;1"] .createInstance(Components.interfaces.nsILocalFile);dd.initWithPath(mydir); //Путь который установленfp.displayDirectory = dd;fp.defaultString = myfilename;if(fp.show() != fp.returnCancel) custombuttons. alertBox (csExpT, "Набор кнопок сохранён в \n"+ saveCB(fp.file.path, "")); }};//*********************************************************************//Считать кнопкиfunction rbMouse(){if (chkPath(Application.prefs.getValue(cEICB, 0)) != 1) custombuttons. alertBox (csImpT, cPathSetMsg); else { var mydir=Application.prefs.getValue(cEICB, 0); //, myfilename = GenFileName(); var fp = Components.classes["@mozilla.org/filepicker;1"] .createInstance(Components.interfaces.nsIFilePicker); fp.init(window, csImpT, fp.modeOpen); var dd = Components.classes["@mozilla.org/file/local;1"] .createInstance(Components.interfaces.nsILocalFile); dd.initWithPath(mydir); fp.displayDirectory = dd; if(fp.show() != fp.returnCancel) getBrowser (). selectedTab = getBrowser (). addTab (fp.file.path); }};//*********************************************************************//Установить каталог записи/чтенияfunction mbMouse(){var sPathEI=Application.prefs.getValue(cEICB, 0), myfilename = GenFileName();if (chkPath(sPathEI) == -1) { custombuttons. alertBox (csSetIET, "переменная "+cEICB+" уже существует и занята") return; //Нельзя создавать тк переменная уже занята };// Диалог создания и установки путиvar fp = Components.classes["@mozilla.org/filepicker;1"] .createInstance(Components.interfaces.nsIFilePicker);fp.init(window, csSetIET, fp.modeGetFolder);var dd = Components.classes["@mozilla.org/file/local;1"] .createInstance(Components.interfaces.nsILocalFile);dd.initWithPath(sPathEI);fp.displayDirectory = dd;if(fp.show() == fp.returnCancel) return; else { sPathEI = fp.file.path Application.prefs.setValue(cEICB, sPathEI+=(sPathEI[sPathEI.length-1] != "\\")?"\\":""); custombuttons. alertBox (csSetIET, "Установлен путь для записи/чтения \n " + sPathEI); }};//*********************************************************************//chkPath проверяет путь и тд, можно добовлять проверки, тк не всё проверяется.//return = -10 ошибка в определении синтаксиса пути (не используется)//return = -2 ошибочный путь или его не существует (почти не используется)// return = -1 ошибка настройки (для совместимости)// return = 0 требуется создать и определить путь// return = 1 всё ОКfunction chkPath(cPth){var vPth = Application.prefs.getValue(cEICB, cEICB), res = -10; //предустановкаif (vPth == cEICB ){ Application.prefs.setValue(cEICB, cPathEI); // Создали и путь по умолчанию из определения res = 1; //Переменная существует и определена }else if (typeof(vPth) != "string") res = -1; //Переменная определена и не того типа, значит она не наша else { //Пробуем проверить путь - ответ в исключении. var file = Components.classes["@mozilla.org/file/local;1"]. createInstance(Components.interfaces.nsILocalFile); try { file.initWithPath(cPth); if (!file.isDirectory() ) res = 0; //Такого пути нет надо создавать else res = 1; // Путь есть } catch(e) { res = -2; } }return res;};//*********************************************************************//Генерация имени файла при записи всех кнопокfunction GenFileName(){var t=new Date();var y=1900+t.getYear();var min=t.getMinutes(); if (min<10){min="0"+min};var h=t.getHours();var m=t.getMonth();switch(m){case 0: m="Jan";break;case 1: m="Feb";break;case 2: m="Mar";break;case 3: m="Apr";break;case 4: m="May";break;case 5: m="Jun";break;case 6: m="Jul";break;case 7: m="Aug";break;case 8: m="Sep";break;case 9: m="Oct";break;case 10: m="Nov";break;default: m="Dec";}var d=t.getDate();var curdate=y+"-"+d+"-"+m+"_"+h+"-"+min;var myfilename="my_cbuttons_"+curdate+".html";return myfilename;};//*********************************************************************// Функция записи кнопок в HTML-файл//*********************************************************************//Запись кнопок в HTML файлfunction saveCB(fullfilepath, nameCB){var bu="", buts, doc, name, image, uri, mode, code, initCode, accelkey, help;VisibleConv (nameCB);AllConv(nameCB);//var uc = Components. classes ["@mozilla.org/intl/scriptableunicodeconverter"]. createInstance (Components. interfaces. nsIScriptableUnicodeConverter);//uc. charset = "utf-8";//bu = uc. ConvertFromUnicode (bu);var head = "<html>\n<head>\n<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>\n</head>\n<body>\n";var fileend = "\n</body>\n</html>"var htmlSource = head + bu + fileend;var filedata=htmlSource;var file = Components.classes["@mozilla.org/file/local;1"]. createInstance(Components.interfaces.nsILocalFile);file.initWithPath(fullfilepath);var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"]. createInstance(Components.interfaces.nsIFileOutputStream);foStream.init(file, 0x02 | 0x08 | 0x20, 0666, 0);var converter = Components.classes["@mozilla.org/intl/converter-output-stream;1"]. createInstance(Components.interfaces.nsIConverterOutputStream);converter.init(foStream, "UTF-8", 0, 0);converter.writeString(filedata);converter.close();return fullfilepath;//*********************************************************************//Подпрограммы для function saveCB//*********************************************************************//******DefSub//*********************************************************************function VisibleConv(nameCB) {buts = document. getElementsByTagName ("toolbarbutton");for (var i = 0; i < buts. length; i++){ if (buts [i].getAttribute ("id"). indexOf ("custombuttons-button") == 0) { name = buts [i]. name; if (nameCB!=""&&nameCB!=name) continue; image = buts [i]. image || buts [i]. cbStdIcon; uri = buts [i]. URI; bu +="<img src=" + image + "> <a href=" + uri + ">" + name +"</a><br>\n"; }}bu +="<hr>";};//*********************************************************************function AllConv(nameCB){buts = custombuttons. palette. getElementsByTagName ("toolbarbutton");for (var i = 0; i < buts. length; i++){ if (buts [i]. getAttribute ("id"). indexOf ("custombuttons-button") == 0) {// Имя кнопки в UTF-8 name = buts [i]. getAttribute ("label"); if (nameCB!=""&&nameCB!=name) continue;// var uc = Components. classes ["@mozilla.org/intl/scriptableunicodeconverter"]. createInstance (Components. interfaces. nsIScriptableUnicodeConverter);// uc. charset = "utf-8";// name = uc. ConvertFromUnicode (name);// BASE64 в UTF-8 image = buts [i]. getAttribute ("image") || buts [i]. getAttribute ("cb-stdicon"); var uc = Components. classes ["@mozilla.org/intl/scriptableunicodeconverter"]. createInstance (Components. interfaces. nsIScriptableUnicodeConverter); uc. charset = "utf-8"; image = uc. ConvertFromUnicode (image); mode = buts [i]. getAttribute ("cb-mode"); code = buts [i]. getAttribute ("cb-oncommand"); initCode = buts [i]. getAttribute ("cb-init"); accelkey = buts [i]. getAttribute ("cb-accelkey"); help = buts [i]. getAttribute ("Help") || buts [i]. getAttribute ("help") || ""; doc = document. implementation. createDocument ("", "", null); doc. async = false; doc. load ("chrome://custombuttons/content/nbftemplate.xml"); setText (doc, "name", name, false); setText (doc, "mode", mode, false); setText (doc, "image", image, true); setText (doc, "code", code, true); setText (doc, "initcode", initCode, true); setText (doc, "accelkey", accelkey, true); setText (doc, "help", help, true); var ser = new XMLSerializer (); var data = ser. serializeToString (doc); uri = "custombutton://" + escape (data); bu+="<img src=" + image + "> <a href=" + uri + ">" + name +"</a><br>\n"; }}};//*********************************************************************function setText (doc, nodeName, text, make_CDATASection){ var node = doc. getElementsByTagName (nodeName) [0], cds; if (!node) return; if (make_CDATASection) { try { cds = doc. createCDATASection (text || ""); } catch (e) { cds = doc. createTextNode (text || ""); } node. appendChild (cds); } else { node. textContent = text; }};//****** EndDefSub//****** End function saveCB}; Ссылка на комментарий Поделиться на другие сайты Поделиться
reclearerr Опубликовано 27 февраля, 2012 Жалоба Поделиться Опубликовано 27 февраля, 2012 Всем доброго дня, недавно созрела небольшая проблема. Дело в том, что я держу серверы по Minecraft и LineAge II в локальной сети. После запуска компьютера и серверов процессор достигает загрузки 100% где-то через трое суток работы. В .bat не шарю, потому и прошу помощи. Нужно: 1. создать таймер, который через 24 часа после начала отсчета выполнит команду 2; 2. влезть в уже запущенный батник minecraft-сервера (работает на Java), написать там команду "stop", дабы сервер отключился; 3. перезагрузить компьютер. Возможно ли воплотить все это в жизнь?) Ссылка на комментарий Поделиться на другие сайты Поделиться
Форматцевт Опубликовано 27 февраля, 2012 Жалоба Поделиться Опубликовано 27 февраля, 2012 (изменено) Можно... ну на AutoHotkeyL. Зайди на "Серый Форум" и спроси - там помогут. Помогут на проф. уровне, просто эта тема больше как учебная. Серый форум (разработка скриптов) P.S. Если что будет непонятно или возникнут проблемы спрашивай у меня тут или в ЛС :bye1: Изменено 27 февраля, 2012 пользователем Indomito Ссылка на комментарий Поделиться на другие сайты Поделиться
Форматцевт Опубликовано 27 февраля, 2012 Жалоба Поделиться Опубликовано 27 февраля, 2012 И ещё.... 1. создать таймер, который через 24 часа после начала отсчета выполнит команду 2;2. влезть в уже запущенный батник minecraft-сервера (работает на Java), написать там команду "stop", дабы сервер отключился; 3. перезагрузить компьютер. а не проще смодифицировать батник minecraft-сервера т.к. в JS есть доступ к таймеру, а ? Ссылка на комментарий Поделиться на другие сайты Поделиться
reclearerr Опубликовано 27 февраля, 2012 Жалоба Поделиться Опубликовано 27 февраля, 2012 В Java совершенно не силен, если подскажешь, как написать функцию - буду благодарен) Ссылка на комментарий Поделиться на другие сайты Поделиться
reclearerr Опубликовано 27 февраля, 2012 Жалоба Поделиться Опубликовано 27 февраля, 2012 С рестартом решил по другому. На Windows можно просто создать ярлык и вместо пути написать "shutdown.exe -r -t <время, через которое компьютер выключится>", затем занести сей ярлык в автозагрузку. Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения
Для публикации сообщений создайте учётную запись или авторизуйтесь
Вы должны быть пользователем, чтобы оставить комментарий
Создать учетную запись
Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!
Регистрация нового пользователяВойти
Уже есть аккаунт? Войти в систему.
Войти