четверг, 30 декабря 2010 г.

Структуры в C (С, Си)

Привет, с вами опять я - кодер -бывший студент
Иногда есть необходимость сгруппировать некоторые данные, допустим вы делайте программу, которая подбирает лучшую девушку 2011.

Конечно можно использовать ряд массивов, например char NameGirl[10]={"Sveta","Anja",....};int AgeGirl[10]={21,23,...} и т.д.

Но лучше использовать структуры.
Структура struct это объеденение нескольких переменных разных или однотипных в одну пачку.

Синтаксис
struct уникальное_название_вашей_структуры
{
переменные, например int age;
};

Но я не рекомендую использовать такой синтаксис, более простой способ это использовать typedef, описание структуры будет в этом случае, таким:
typedef struct
{
переменные, например int age;
} уникальное_название_tp

В чем разница? В объявлении (в функциях и как переменные),
в первом случае вы должны будете писать struct уникальное_название_вашей_структуры имя_переменной,
во-втором случае всего уникальное_название_tp имя_переменной;

Допустим:
typedef struct
{
char name[30];
short age;
char virgin;
char like_drink;
char emo;
} TS_Girl;

В Си, нет булевых типов переменных (они есть только в C++ - bool), потому используем char, но для кода на самом деле все равно, булевая переменная из C++, занимает в памяти также 1 байт, а не 1 бит - как кажется.

Теперь TS_Girl - это, что-то типа переменной и можно сделать так:
TS_Girl girl_from_work[10];
Тут мы объявили массив структур, обращение к структуре будет выглядеть так:
if (girl_from_work[0].age > 30) continue;

Обращение к членам структуры - через точку TS_Girl wounder_girl;
if (wounder_girl.emo != 0) printf("Не повезло!\n");


В чем прелесть структур - что (кроме группировки) - что данные хранятся в одном месте и последовательно друг-за другом.
Системная функция sizeof вернет размер струтуры, в моем случае sizeof(TS_Girl) вернет 35.
Можно эти данные копировать/записовать как область памяти, например write(file,(char*)&girl_from_work[i],sizeof(TS_Gril));

В некоторых (поздних)версиях С, в структурах появились функции - но это язычество, сын мой, избегай этого!
Есть классы (в C++), а есть структуры и не стоит мешать мух с котлетами.

понедельник, 20 декабря 2010 г.

Циклы и условия

Объединил их в один урок, т.к. на самом деле - это одно и тоже - проверка условия и выполнения оператора или блока операторов.
Разница только в том, один раз выполняется блок/операнд или несколько - по условию.

Условия



Как и в множества других языках - блок проверки условия называется if - в переводе если.

После if пишется условие в круглых скобках, а затем один операнд (с замыкающей ;), либо блок (в фигурных скобках).

Например:
if (age > 21) printf("You may'be buy VODKA\n");

Комбинирование условий



В блоке проверки условий можно проверять не одно, а несколько условий - написано в некоторых учебниках и самоучителей.
Это все вранье и чушь! - В блоке if проверяется только одно условие, а операции && - и, и || - или - это операции над значениями.

Допустим if (age > 21 && sex == SX_MAN) на самом деле сначала выполняется решение условия в скобках, все операции имеют разный приоритет (из школы вам известно что умножить приоритетнее, чем сложение), а у операций && и || - самый низкий приоритет.

Выполняется первая часть (проверка идет справа налево) проверка на пол и ее значение запоминается, затем идет проверка на возраст и ее значение запомниается (обе части получают значение true или false), а далее выполняется третья операция && (и) - и если обе части true - то и общее значение будет true.

Если нужно выполнить разные блоки при срабатывание и не срабатывания условия, то используют конструкцию if () {...} else {}
else в переводе иначе.
Логично - сделай так если условие и иначе если не так.

Циклы


При реализации алгоритма цикла можно использовать любой способ т.е. любую запись, и самое главное при любом случае - в машинных кодах получится одно и тоже, но вот для более понятного исходников их делят:

for - для


Цикл for чаще всего используется там, где нужно выполнить заранее известное количество иттераций (циклов).

Синтаксис
for(условия иницилизации ; блок проверки ; блок выполняемый при каждом цикле - блок шага) {...}
Вместо блока операндов, можно также писать один операнд - если это необходимо.

Пример:
for(i=0;i<10;i++) printf("i=%d\n",i);
В примере в блоке условия инициализации - переменной i назначается значение = 0.
В блоке проверки переменная i проверяется, что она (переменная) меньше 10, в блоке шага - переменная i увеличивается на один.

Блок инициализации выполняется всегда - а блок шага только в том случае, если выполняется условия.
Т.е. выполняется i=0; затем проверяется i<10, далее выполняется блок за for - печатается строка printf("%d\n",i), затем выполняется блок шага - i++,
затем опять проверяется условие и если оно = true (меньше 10 в нашем случае) - опять выполняется блок за for и блок шага. И до тех пор пока блок условия - будет = true.

В любом блоке for можно указать несколько действий через запятую, например:
for(i=0,j=0; i<20,j<5; i+=2,j++) printf("i=%d,j=%d\n",i,j);
Т.е. в блоке инициализации выполняем присвоение перменной i и переменной j.

В блоке проверки условий выполняется два условия что i меньше 20 и j меньше 5 - на самом деле цикл будет только при выполнении всех условий - аналогично сработает (и кстати более лучше для понимания) i<20&&j<5
В блоке шага, выполняется также два операнда, увеличение переменной i на два и i на один.
Результат:
i=0,j=0
i=2,j=1
i=4,j=2
i=6,j=3
i=8,j=4


Скажу больше в блоках можно использовать даже функции, например for(i=0,printf("start");i<10;i++,printf("step\n")) printf("i=%d\n",i);

Но кроме использования их в блоках инициализации и проверки - не вижу смысла использовать функции в блоке шага, уж лучше перенести в блок за for, либо использовать....

while - пока


Цикл while - чаще используют если количество иттераций заранее не известно.

Синтаксис:
while (условие) {...}
Блок за while будет выполнятся пока условие = true.

Если условие изначально false то блок не будет выполнятся вообще, если это необходимо используют более редкую конструкцию while с do
Синтаксис:
do {...} while(условие);
Блок do-while выполнится один раз как минимум и будет выполнятся пока условие = true.


Для изменения работы циклов (for и while) - есть ключевые слова break и continue

break - сломать


Цикл прерывается и выполняется слелующий операнд за циклом

continue - продолжить


Цикл принудительно переходит на блок проверки условия, однако у for - выполняется блок шага


Еще про проверки условий



Еще для более удобного представления множественной проверки условий используют конструкцию switch - переключатель
Синтаксис:
switch(выражение)
{
case значение1:
...
break;
case значение2:
...
break;
default:
...
}


в условиях стоит выражение, значение которого проверяется в каждом case и если оно совпадает с одним из значением то выполняется операнды под этим case.
Внимание, если не будет стоят break то затем будут выполнятся все другие условия, под другими case, которые описаны дальше.

Блок default выполняется как глобальный else - если не один case не подошел.

Иногда специально не ставят break для выполнение какого-то кода.
Вообще switch как и циклы - это все проверки условия (if) и переходы на строку (goto)

Однако использовать goto - некомильфо и презирается гуру.
Однако если у вас вложенный тройной цикл - то плюйте на гуру и пишите goto, между прочим в коде под Linux для обработки изображений jpeg используется goto, так что - вообще нежелательно - но если очень хочется - то можно.

четверг, 9 декабря 2010 г.

Какие страницы не в индексе ПС?

Задался тут вопросом и написал небольшую утилиту для определения страниц не в индексе ПС.

Работаю программистом, а потому отдавать за просто так жаль.
Отдам на тесты первым трем комментаторам к этой записи (укажите на какую почту скинуть ключ) [УЖЕ ЗАВЕРШЕНО] и тому кто скажет красную цену и сможет ее аргументировать.

Думаю некоторым саперам будет интересна.


понедельник, 29 ноября 2010 г.

Указатели, функции и указатели на функции (С, Си)

Итак, в уроке №2 мы разобрали какие бывают переменные и как они хранят свое содержимое.
Всё в мире байты - это как эпиграф.

А байты хранятся в памяти, в виде цепочки - друг-за-другом, чтобы узнать где именно - можно получить указатель на адрес переменной.
Вообще разница между адресами и указателями очень тонка, и отличия возникают все же больше в C++, нежели в простом C. Но об этом позже


В языке C, получить адрес переменной - знак амперсанда - &.

Допустим:int a=5;int *b=&a;
Переменная b - на самом деле указатель на целочисленный тип (int). Чтобы точнее это понять стоит писать int* b, но все пишут (и я тоже) как int *b, потому что в пробелы и их отсутствие - это не суть.

Так вот, переменная b указывает на адрес памяти переменной a или если кратко - b указатель на a.
Для понимания можно выполнить следующий код *b = 6;, звездочка перед b означает действие разыменование, и реально именно переменная a станет равной 6!
Если же выполнить конструкцию просто b = 6; то в результате переменная b будет содержать на область памяти с смещением 6. Само по себе это ничего не даст (и ошибок тоже), но если после этого сделать *b = 6; 99% что ваша программа закроется с ошибкой. Потому что вы меняете значения памяти не глядя, а там может располагаться исполняемые код или другие данные.

Это тоже одна из плавающих ошибок, которую трудно найти.

Функции


Функции это самостоятельный код, который объеденен в группу - функцию.
Функция может принимать любое количество, любых типов переменных и возвращать любой тип переменных. А может и не возвращать - в некоторых языках делят на функции и процедуры - мол процедуры не возвращают ничего, в C - функции могут возвращать тип void - ничего/пусто.

Синтаксис очень просто перед именем функции пишут тип возвращаемых данных, например int, затем имя функции, а в круглых скобках перечисления через запятую типы аргументов и их имена.
Например int my_func(int a,int b,double num)

Тело функции пишутся после объявления функции в фигурных скобках, например
int my_func(int a,int b,double num)
{
int c = a + b;
c = c + (int)num;
return c;
}

Ключевое слово return говорит что в данном месте нужно прекратить выполнение функции и вернуть значение, которое у него указано (в примере - переменная c).
Если функция типа void - то можно конструкция упрощается просто return;.

Теперь про большие проекты, функции используются еще для того чтобы разнести код по его смыслу на разные модули.
Чтобы в другом файле(модуле) использовать функцию другого файла(модуля) нужно написать(указать) ее прототип.

Например в нашем случае int my_func(int a,int b,double num); - описания прототипа заканчивается точкой запятой, а описание функции - телом функции в фигурных скобках.

В прототипе функции(описании) можно не указывать названия переменных или (если хочется) писать любые имена - все равно комплиятор их не смотрит

int my_func(int,int,double); - это тоже прототип функции.

Забегая вперед скажу, что в C++ можно не указывать имя переменной и в описания функции - это означает, что в данной функции вы не используете эту переменную, а ее синтаксис сохранен для совпадения с чем-то. В этом случае компилятор не выдает предупреждение(warning) Parameter 'a' is never used in function

Допустим мы в функции my_func изменем содержание переменной a, например a = 5;, то в сама переменная указаная в функции при вызове - не изменится.

Например:
int my_func(int a,int b,double num)
{
a = 6;
int c = a + b;
return c + (int)num;
}
int main()
{
int i=5,j=6,n;
double k=1;
n=my_func(i,j,k);
printf("n=%d, i=%d\n",n,i);
}
Выдаст n=13, i=5, потому что в функцию передаются значения переменных, а не их адреса

Чтобы изменять значения переменной нужно в описании функции указывать не просто переменную, а указатель на нее.
void my_func2(int *a,int b)
{
*a = b + 5;
}
int main()
{
int i=5,j=6;
my_func2(&i,j);
printf("i=%d\n",i);
}

Код вернет i=11, т.к. в функции мы используем указатель на переменную, и пусть она называется не так как в основной функции (там i, а в myfunc2 - a) - имена не играют никакой роли, все равно в область памяти переменной указанной в качестве первого аргумента, будет записано значение переменной второго аргумента + 5.

С переменными более, менее ясно - теперь - как передавать массивы, в частности строки?


Допустим мы хотим написать функцию, которая будет определять сколько букв 'а', в заданной фразе.
Нам нужно передать в функцию строку - массив символов, так как это сделать?
Очень просто, в описании функции нужно написать, что ожидается указатель на элемент массива (в нашем случае - символ).
Например: int getSymA(char *src);
В функции, чтобы получить элемент массива, можно также просто писать str[1] или *(str+1) - это два идентичных кода вернут второй символ в строке.

В целом наша функция будет выглядеть так:
int getSymA(char *src)
{
int i,n=0;
for(i=0;src[i];i++)
{
if (src[i]=='а') n++;
}
return n;
}

кстати, фигурные скобки после циклов, если код состоит из одной строки можно не указывать, например:
int getSymA(char *src)
{
int i,n=0;
for(i=0;src[i];i++)
if (src[i]=='а') n++;
return n;
}

или вообще не использовать лишние переменные:
int getSymA(char *src)
{
int n=0;
for(;*src;src++)
if (*src=='а') n++;
return n;
}

Это как эволюция понимания, потому рассмотрим последний код построчно.
  1. Первая строка - говорим что нужно создать переменную n и инициализировать ее нулем.

  2. Вторая строка - цикл for - пропускаем блок инициализации (первый после круглой скобки) сразу ставим точку с запятой, второй блок - условия - в нем проверяем является ли указатель на символ 0 - пустым символом, означающим конец строки, третий блок перемещаем указатель в памяти (указатель, а не его значение)

  3. Третья строка - проверяем, а текущий указатель указывает на букву А? Если так увеличиваем счетчик n на один, если нет - то ничего не делаем (нет блока else)


Сделаем вызов, скажем следующего кода:

char s[10]="Hello!";
printf("%d\n",getSymA(s));


Первое - при передаче массива, не надо указывать его адрес - нужно указывать саму переменную, т.к. она и есть уже указатель на переменную.
Второе -
АААА! Мы изменяли указатель! Программа сломается и нельзя использовать переменную дальше! - Вовсе нет, мы передали указатель, который может менять значение переменной, но мы его не модифицировали, а просто изменяли его адрес.
Чтобы модифицировать сам указатель нужно использовать указатель на указатель :)

Код:
void hhh(int **a,int *b)
{
*a = b;
}
int main()
{
int i=5,j=6,*n=&i;
hhh(&n,&j);
printf("i=%d,j=%d,n=%d\n",i,j,*n);
}

результат: i=5,j=6,n=6, в функцию мы передали указатель на указатель переменной i, но в самой функции сказали, что теперь он равен указателю на переменную b.
Сами переменные (i и j) не изменились, а вот указатель n, ранее указывающий на i, стал указывать на переменную j.

И отвечая на ваш вопрос скажу - ДА! Есть указатели на указатели указателей, особенно это любит использовать корпорация Microsoft
Но в реальной жизни, хватает и указателей на указатели. А некоторым и просто указателей.

Указатели на функции


Раз в функции можно передать указатель на область памяти, то почему не передать на ту область где находится функция?
Конечно можно и не так сложно, код:
#include
int pw(int n,int t)
{
int i,r=1;

for(i=0;i>t;i++)
r*=n;
return r;
}
int hhh(int (nn(int,int)),int z)
{
return nn(z,2);
}
int main()
{
printf("%d\n",hhh(pw,3));
}


Вызываем функцию hhh, передавая ей в качестве аргументов адрес на функцию и число.
В функции hhh вызываем функцию указанную в качестве параметра и получаем в результате цифру 9.

Для сложных функций, передаваемых в качестве параметра, лучше использовать заменитель typedef
typedef int (*load_func)(int,int);
int hh(load_func f,int z)
{
if (f) return f(z,2);
return 0;
}
int main()
{
printf("%d\n",hhh(&pw,3));
}


понедельник, 22 ноября 2010 г.

Второй урок - Типы переменных. (С, Си)

Данный урок, продолжение первого урока.
Раберем типы переменных в C.
Их не много, это символ, он же байт - char принимает значения от 0..255 (или -127 .. +127)
Целочисленное - int - значения целые числа
С плавающей точкой - float
С двойной точностью - double
Тип данных float практически не используется в современном программировании.

Существуют несколько префиксов к типам данных, например знаковость это signed и unsgined.
По умолчанию переменные знаковые (signed), хотя такая запись не будет ошибочной signed int a

В чем различия? В диапазоне принимаемых значений в случае знака это от - до +, в беззнаковом случае(unsigned) от 0 до максимального значения.

Максимальное значение для char это 255 (емкость - 28) , а для int (емкость 232) - в 32 битных системах, в 64 - соотвественно 264, а я помню еще времена когда в int можно было загнать только до 216.

Размер памяти выделяемый для каждой переменной, естественно кратный ее максимальному значению (или наоборот - тут спор как про яйцо и курицу), для char - 1 байт, для int (32) - 4 байта.

Для float - 4 байта, для double - 8 байт.

Также есть префиксы изменяющие размер данных - это short и long
Но не все варианты возможны, скажем для char и float нельзя указывать такой префикс.
Можно только для int и double. Т.к. long float это и есть double, а long char - это наверное int.

Так вот short int - это слово (два байта), т.е. максимальное значение 216
Для long int в bcc и gcc - размер равен что и просто int - двойное слово (четыре байта).
Однако для некоторых компиляторов - long int это int64 - 8 байт.

Вариантам short double тоже несуществует, однако есть long double.
Кстати в разных компиляторах это разные размеры данных. В bcc - 10 байт, а в gcc - 12 байт (на 32битной платформе).

По поводу signed/unsigned - тут стоит заметить что переполнение емкости данных, ведет к разным значениям в зависимости от signed.
Например unsined char a = 255; a+=2, "a" будет равна 1. А char a = 127; a+=2, "a" будет равна -127.

Эта нехитрая ошибка приводит к большому количеству багов и глюков множества программ.

А как же строки, спросит тот редкий читатель, что увидел этот текст.
Все просто - строка это массив символов. Размерность массива указывается в квадратных скобках после имени переменной
Например int a[50]; - целочисленный массив, с 50 элементами. Для доступа к конкретному элементу в квадратных скобках указывается его индекс int b= a[5];.
Массивы можно инициализировать сразу при описании, например int a[5] = {1,2,3};, значения указывается через запятую в фигурных скобках. Значений может быть меньше чем размерность массива, но не больше!

Также и строки char str[10] = {'H','e','l','l','o','!',\0};.
Символы указывается в апострофах, и в ковычках может быть только один символ. char a='aa';//ошибка!!!

Но гораздо легче и проще инициализировать строки (а также использовать их для других целей) через строку заключенную в двойные кавычки char str[10] = "Hello!";.
Следует заметить, что 0-символ ставится автоматически.
Т.е. char str[6]="Hello!"; - не сработает, скажет что размер массива меньше чем количество инициализируемых элементов.
Т.е. "Hello!" автоматически преобразуется в {'H','e','l','l','o','!',\0}


вторник, 16 ноября 2010 г.

Первый урок - Hello world на C(си)

В языке C очень малый набор ключевых слов, т.к. только несколько типов переменных, слова управления циклами и функциями.
Еше необходимо заметить, что C язык компилируемый, т.е. для его выполнения необходимо его скопилировать - преобразовать из текста языка в машинный код.

При выполнении программы, написаной на C необходимо описать главную функцию main, которая и будет вызываться при запуске.
Функция main является такой-же обычной функцией как и все остальные, в целом у нее есть два несколько прототипов описания.
void main(), int main(), int main(int,char **) и void main(int,char **).

Первое слово перед main это тип функции - тип значения которое она может веруть int - целочисленное число, void (пусто) ничего.
Затем идет имя функции (в нашем случае main), а далее в круглых скобках - принимаемые параметры, также сначала тип, а затем название переменной.
Причем как в описании, так и в самой функции названия могут отсутствовать.
Отсутствие название переменных и для чего это - обсудим потом


Тут нужно учесть, что компилятор gcc считает что функция main должна обязательно иметь тип int, для того чтобы вернуть код выполнения программы, а вот скажем bcc от Borland допускает и тип void, хотя в этом случае на самом деле возвращает 0.
Чтобы поддерживать общие стандарты лучше описывать функцию main все-же через тип int

Функция main отличается от других библиотечных функций тем, что она противоположная по смыслу, в остальных функциях вы знаете их прототип для вызова, но не знаете/видете код функции, а для main все как раз наоброт - компилятор знает ее описание, но вот код - должны написать вы.

И так самый примитивный рабочий код на C!
int main()
{
return 0;
}

Данный код можно скомпилировать в программу и даже выполнить - правда, он ничего не выполнит, потому как единственная строка кода в нем return 0; - выйти из функции и вернуть значение 0.
Ну да в C - разделитель комманд точка с запятой ';'


Для того. чтобы что-нибудь вывести на экран нужно вызвать функцию для вывода, впрочем большинство стандартных функций уже давно написаны. Например для вывода на экран(консоль) есть специальная библиотека stdio, которая содержит тьму функций.
Но нам интересна пока только одна - printf - форматированный вывод на экран.
Чтобы подключить библиотеку нужно указать директиву include с указанием имени библиотеки, имя библиотеки можно написать в угловых скобках (тогда компилятор библиотеку будет искать в стандартной папке, либо в двойных ковычках тогда он сначала ищет в текущем каталоге, а потом в стандартом)
Все директивы - это команды к препроцессору, т.е. процессу вызываемому до компиляции, это облегчает жизнь программистам, в противном случае им пришлось бы самим писать все прототипы функций вручную.
Ну и директивы пишутся через знак #, всего их не очень много основные: include, define, ifdef, else, error

Для нашего примера это #include <stdio.h> - т.е. включить заголовки(описания прототипов) от библиотеки stdio (расширение .h - как раз указывает что это заголовки от англ. header)

Функция printf поддерживает множество аргуметов, но пока нас интересует только первый - а именно базовая строка, которая будет выводится на экран.
Cамый примитивный рабочий код на C с выводом на экран!
#include <stdio.h>
int main()
{
printf("Hello, World!\n");
return 0;
}



Т.к. в качестве первого аргумента функции printf является строка, то приходится квотировать некоторые символы, например \n - означает перевод строки, а \" - двойную кавычку


Теперь скомпилировав и выполнив это программу, увидем на экране Hello, World

Если, вы конечно, запускаете ее из консоли (в винде через cmd), а в линуксе через терминал.

Ну и чтобы скомпилировать программу - команда gcc hello.c -ohello.exe - это если у вас gcc

понедельник, 15 ноября 2010 г.

Подумал тут

И решил сделаю я курс обучения C/C++ (сначала основы, а потом классы и полиморфизм ;) )
Я все потому, что прочитал я в блоге Шелвина, что это интересует массы.

А прочитал я блог, потому что автор устраивает марафон на 60 дней для набора подписчиков.
Обещает горячие темы и жаркие посты, так что думаю можно и подписаться.

УТКИ НА СТАРТ!

четверг, 11 ноября 2010 г.

Авторизация на ya.ru (через passport.yandex.ru)

Попросили меня (за практически спасибо) написать модуль для авторизации и постинга постов на ярушку (ya.ru).

Быстренько накидал через свои компоненты, а что сложного-то? GET my.ya.ru далее получаем форму для авторизации через passport.yandex.ru заполняем поля и далее через n редиректов в идеале попадаем на my.ya.ru уже авторизованными.

В чем сложность №1. Понятно что авторизация не совсем обычная (не через тривиальные куки) - и понятно что яндекс(домен) свои куки не отдает даже домену ya.ru.

Первый и быстро написаный код не работал - вернее он явно авторизовал на passport.yandex.ru (видно было по выдаче), но на my.ya.ru был редирект без кук и сессий.

Ломал над этим голову долго, причем этот код замечательно работал для mail.yandex.ru и webmaster.yandex.ru - на это и понятно - это один и тот-же домен.

Перебрал все, установил сниффер - вижу что при первичной загрузке my.ya.ru в браузере срабатывает редирерт, на my.ya.ru/pass где получают куки и возвращают опять же редиректом на my.ya.ru.
С точки зрения пользователя ничего не происходит он вбивает my.ya.ru и видит страницу авторизации.

Но в моем случае этого не было! Было просто загрузка формы логина, без редиректа и без принятия кук.

Оказалось что я не передавал в хедере HTTP тэг accept = html/text и прочее.
И именно из-за этого my.ya.ru не делал редирект и не подсовывал кук.
Как только начал указывать - все получилось.

В кратце:
GET my.ya.ru -> my.ya.ru/pass -> my.ya.ru
Заполняем форму
POST passport.ya.ru -> ... -> pass.yandex.ru -> my.ya.ru -> pass.yandex.ru -> my.ya.ru
Мы авторизованы! (В предпоследнем ya.ru передается сессия, а в последнем уже авторизованные куки для ya.ru)

пятница, 29 октября 2010 г.

Непростая сортировка.

Иногда нужно отсортировать данные как числа, но сами данные не совсем числа, а сборная солянка из цифр и букв

Допустим у вас есть такие данные: 90A,89B,90C,102A,89A ;) их нужно отсортировать по возрастанию - на самом деле - код очень простой:



use Data::Dumper;

sub exsortproc
{
return $a<=>$b if ($a != $b) ;
return $a cmp $b;
};


my @data=('90A','89B','90C','102A','89A');
my @out;
@out = sort exsortproc @data;

die Dumper(\@out);


Output:

$VAR1 = [
'89A',
'89B',
'90A',
'90C',
'102A'
];

Все дело в том что если нужно перл кастует скаляр '90A' к числу 90.

Успехов вам и побольше 90C :)

суббота, 16 октября 2010 г.

Рабочее

На работе есть вроде внутреннего корпоративного сайта, так вот с недавних пор он стал странно грузиться.
Боковая панель - подгружалось полностью где-то за 15 секунд.

Искали и нашли причину, в футоре стоял счетчик, сервер который сейчас не доступен, причем ответ что от сервера отрубает именно по таймауту.

пятница, 8 октября 2010 г.

Обитель зла 4 vs Блэйд-ХЗ

Вчера посмотрел обитель зла в 3D, пипец хрень полная - начало так вообще подумал от сучки какие, а потом это мнение закрепилось.

Нет, я не против пары трупов, но ведь хороших когда убивают, значит это - плохой?

Затем эти новые зомби - пипец, лучшие зомби - это "рассвет мертвецов" а эти - как тетки из СССР в очереди за колбасой - и догонят и загрызут!

Эти раскрывающие рты и красные глаза у супер-злодея? Это точно не вампиры из блэйда? Чувствуется один и тот-же реквизит.

Фильм - гавно. Может в три дэ вам было лучше видны сиськи, но все равно это не спасет сюжет

понедельник, 27 сентября 2010 г.

Работа

Знаете как трудно сосредоточиться на работу, когда лень?
Ищешь кучу причин, посмотреть почту, интернет или даже поиграть в конце-концов.

Но!
Стоит понимать, что каждый сделанный час работы, приближает тебя (хочется написать к пенсии ;)) к финалу твоей мечты.

Это и только это заставляет меня работать, когда лень и когда не охота работать.

четверг, 23 сентября 2010 г.

Разное мышление

Вчера еду в лифте, со мной там еще парень и одна девушка.
На этаже 3, внезапно отключается свет.
Я - ого
Парень - ни фига себе
Девушка - ой

:)

пятница, 10 сентября 2010 г.

Не работается

Последние недели две мне катастрофически не работается. Нет, конечно я делаю механическую работу, которую говорят, но как-то не прет по основному проекту, который я курирую. Для программиста – это наверное хуже всего.

Пытаюсь разобраться в чем дело и не понимаю. Вроде бы и заинтересованность есть (проект очень интересный) и материальная выгода (так у нас принято) и в этом проекте я нахожусь как бы сбоку от всех и являюсь сам себе руководителем, но все равно работать не прет.

Наверное лень, а может быть из-за погоды или просто спад умственной активности.

понедельник, 23 августа 2010 г.

Линукс

Вот же трабл!
Есть самописный демон - прихожу сегодня сдох еще в пятницу - все попытки перегрузиться - опять Segmentation Fault

Дебажу код по-старинке на каждой строке - лог. Вижу выпадает на вызове обработки PNG из libpng5.

Хрень думаю, и нажимаю в mc на ентом файлике F3 - Segmentation Fault говорит мне mc.

Хм-хм

четверг, 19 августа 2010 г.

Лишнее

Ну зачем в SQL эти лишние частицы BY?
Почему просто нельзя написать:
SELECT one,sum(total) from table
group one
order one
?
Нафига делать это человекоподобность? Лишние байты в дань традиции :)

четверг, 12 августа 2010 г.

Жара

Жара стала не выносимая, даже теже 480 в июне переносились легче, так как думалось что это не надолго.
В офисе сижу большую часть дня, так как там кондиционер.
Окна не открываем, да и даже не из-за кондера, а из-за гари.
Вернее как раз со вчера стало полегче чуть-чуть, но все равно очень жаркое лето.
Как поет Чичерина - "Жара, жара - жаренное солнце больших городов".

В лес ходить запретили, короче жара во всей центральной части России. Да и пожары большинство из-за окурков.
Когда я еще учился в универе, у нас была традиция в августе ходить в лесную зону на шашлыки. Сейчас, естественно, не пойдем. Хотя очень жаль, что нарушается пятилетняя традиция.
С другой стороны, университетские связи рушатся, все больше завязываюсь на работу, в т.ч. друзья-приятели.

понедельник, 26 июля 2010 г.

Жарко, но надо работать

Жара в офисе, те кто сходили в отпуск в июне, ненавидят тех кто пошел сейчас. Работаем в обнимку с кондиционером.
Мне повысили з/п и теперь уж точно назначили куратором нового проекта.
Сейчас делаю генерацию печатных форм (CSS2) из данных и формата FastReport'а (без использывания их кода, т.к. все кроссплатформено и делаю на чистом g++).

Работа нравится, жара нет. После работы мечтаю сходить на пляж, но ощущения того что нужно выйти из маршрутки, а потом (после) ее заного ловить - это выше моих сил.

Странные дела с пивом - пока выпьешь и дойдешь до точки сбора - оно испаряется через кожу. А после выпиваешь литра два воды - и про пиво напоминает только потраченные деньги.

Начальство вернулось из отпуска и издевается - типа я смогу взять свой первый отпуск уже в сентябре, когда будут дожди и холод :(

понедельник, 7 июня 2010 г.

SQL

Сегодня был нанесен сверх удар по моему восприятию мира.
Дело все в SQL запросе, суть такая есть главный запрос и к нему LEFT JOIN'няться несколько табличек:
Одна основная tbl1 и две добавочных (add1,add2), но у второй добавочной есть поле, которое ссылается на таблицу по типу add1 - add11
(смысл это экземпляры и контейнеры)

Изначальный мой красивый запрос был таким:

left join
(
tbl1
left join add1 on (add1.type = tbl1.value)
left join (add2 inner join add11 on (add11.type=add2.parent)
on (add1.type = tbl1.value)
) on tbl1.value = data.p1


т.е. связка add11.type = add2.parent жесткая.
Но запрос тормозил ужастно (кол-во записей в каждой таблице больше миллиона), и потом я заменил его

left join
(
tbl1
left join add1 on (add1.type = tbl1.value)
left join add2 on (add1.type = tbl1.value)
left join add11 on (add11.type=add2.parent)
) on tbl1.value = data.p1


Стал выполняться в десятки раз быстрее - хоть и стал более некрасивым.

понедельник, 31 мая 2010 г.

Диплом

Почти готов, это радует.

понедельник, 17 мая 2010 г.

Лето,жара и отпуск

Большинство сотрудников уже свалило, либо готовиться к отпуску.
Офис полупустой. Ясно, что мне ближайщий отпуск светит только в сентябре.
Да еще тут диплом, вернее с дипломом все ок, я уже написал и даже относил на проверку.
Но все равно работать летом - это конечно испытание на прочность.
Ждем пока наш босс-гг свалит в отпуск и может будет чуть полегче (а свалит он в конце июня). Остался месяц.

Работать не так сложно, но вот войти в рабочий настрой в такую жару, да еще глядя в окно на беспечных прохожих - трудно.

среда, 5 мая 2010 г.

Забавно

Нашел сегодня забавный глюк.
У меня на стороне сервера генерился js-скрипт, который создается в зависимости от данных.
Так вот там среди прочего был массив строк, которые я квотировал под одинарную ковычки.
Все работало - тут бац не работает, в чем дело думаю. Искал. Около часа.
Сходили с коллегами - выпили пива, пришел - осенило. Среди прочего, что нужно квотировать под одинарную ковычку (а вернее кроме апострофа) нужно еще заменять \n - т.к. в javascript'е перевод на новую строку - разбивает строчку.
Вот так.

пятница, 30 апреля 2010 г.

Сейчас

Сегодня к нам пришел прошлый пришлый программист, из того тех, кто ушел от нас
и вот сегодня, когда (ну меня была трабла с начислением НДС по фактурам, связи с тем что накладые были частичные и их было несколько), так вот он посмотрел на мой код (мимолетом) и сказал тут лучше так - и сказал формулу.

И я понял - лучше так, подумал как я хреново (а кто лучше-то?) знаю бухгалтерию

А потом, Иван сказал мне, что то - что у нас было, уволился по несовпадению взгядов с ГГ.
Я - в ахуе.

четверг, 29 апреля 2010 г.

Ого!

Сегодня просматривал код, который написал при приеме на работу. Что-то вроде вступительного экзамена было, парсить логи от Squid и записывать их в базу.

Так вот сегодня нашел страшный косяк! Дело в том, что я вместо объема трафика считал время выполнения запроса (второе поле в строке). Оно конечно ~ коррелировало с объемом, но все-же было не тем. Однако за два (!) месяца общий объем трафика и цифорка через мои подсчеты примерно были равны (по данным провайдера).

Сегодня в тихоря исправил косяк.

вторник, 27 апреля 2010 г.

А бывает и такое

Бывает же такое кодишь-кодишь, потом приходит мысль, и удаляешь все и переписываешь буквально двумя строчками.

Потом видишь похожий кусок кода и тоже там исправляешь на новую редакцию.
Запускаешь проект - а там ошибка появляется, где-то, незвестно где.

Ищешь-ищешь, а потом обнаруживаешь что просто затер лишнюю строчку, когда второй раз копировал код.
С одной стороны оптимизация, с другой стороны полдня вторника.

вторник, 20 апреля 2010 г.

Бывает

Искал сегодя JavaScript-реалзиацию unix-crypt, перерыл кучу сайтов (кстати нашел) и наткнулся на проект 7maze.ru, по созданию онлайн игры.

Вспомнил - года четыре назад тоже задавался подобными мыслями, а сейчас уже переболел.
Времени нет, нужно делать серьезные вещи и думать о будущем :)
Но внесу свою лепту, в свободное от работы, время. Если оно конечно будет. Работы - тьма.
А деньги как-то быстро заканчиваются :(

среда, 14 апреля 2010 г.

Дубль2

Сегодня наконец получил полную зарплату, как и ожидал в своих худших прогнозах за интернет вычели. Причем опять 500 рублей.
Думаю поговорить с ГГ насчет окончания испытательного срока и соотвественно увеличения зарплаты.

среда, 7 апреля 2010 г.

Скрывает рекурсивно блоки в html

Понадобилось мне рекурсивно скрыть все блоки (div), конечно они и так все скрываются, если скрыть родителя, но вот когда родителя показываем - они тоже показываются все - а у меня там дерево, с вариантами выбора веток, которые по мере выбора показываются.

Накатал такой код

function hideall(e) {
//Тут я скрываю только определенные блоки, а именно у них идентификатор начинается на определенную букву
var k=e.id.substr(0,1);
if (k=='r' || k=='b' || k=='c') e.style.display='none';

for(var i=0;i<e.childNodes.length;i++){
//если тип = 1 то это дочерний элемент, а если другое что-то - то что-то другое
var k=e.childNodes(i); if (k.nodeType==1) hideall(k); }
}

понедельник, 5 апреля 2010 г.

Вложения в письме

Делаю отправку письма по SMTP, нужно отправить вложения - ну естественно смотрю на пример
Content-Type: multipart/mixed; boundary="----==--bound.7042.web145.yandex.ru"

А дальше мол письмо разбито на эти самые boundary, пишу также - не работает, еще раз проверил - нефига, да что такое думаю.

И лишь через пару часов определил, что в хедере письма boundary это строка, а разбивка идет уже с префиксом --, а завершающий boundary еще с суффиксом --,
просто в Яндексе этот ччортов боундарий уже был с --, и я естественно не считал сколько их там 10 или 12 черточек этих.

Вот так :(

пятница, 26 марта 2010 г.

Прощание

Сегодня великий день
Вернее печально-великий. Во-первых нашу контору покидает Руслан, наш ведуший разработчик по БД.
Уезжает с родителями (и это в 28 лет) в Германию, вот так.
по этому поводу пьянка и мое новое рабочее место.

Теперь не посредине комнаты. Теперь я спиной ошущаю твердь холодной стены.
Теперь в мой монитор могут смотреть лишь те кто-живет-в-стенах и только они.

Тараканы, увы, вымерли.

вторник, 23 марта 2010 г.

Девушки

Нет на работе в офисе есть свои плюсы, что-бы там не говорили про фриланс.

Например мимо меня в промежутках от работы дефелируют юные девушки в секси-нарядах.

А что видет фрилансер? Банер с порносайта? ^_^.

четверг, 18 марта 2010 г.

Работа

Наконец-то мне поручили маломальскую задачу.
Нужно сделать веб-обертку для генерируемых списков (списки в XML).

Тружусь как пчелка.

среда, 17 марта 2010 г.

Багги

Два часа мучался с одной неказистой JS-функцией, суть удаление строки по принципу копируем на ее место предыдущую, а потом уменьшаем количество строк на 1.

Не работает и все тут!
Кофе и мат не помогли, только потом решил вывести (просто так) переменные на экран,
row=51, откуда думаю 51 если удаляю 5 строку из 13? Етишкин корень - row+1 срабатывало как для строки и получалась такая ахинея. parseInt и все дела.

Вот так гибнут нервы.

вторник, 16 марта 2010 г.

А вот :(

Короче оппа.
Я конечно знал, что за неделю заплатят не как за целый месяц, а лишь 1/4. Но что у них тут принято вычитать за использованный интернет, это была новость.
Короче из 1800 зарплаты вычели еще 600 за интернет.

А знаете в чем главный писец? То что это интернет за ФЕВРАЛЬ!
А в марте я как минмум уже столько же накачал. Это как миниум.

Вот такие зубки у офисной акулы

Зряплата

Сегодня день зарплаты. И хоть в февраля я проработал всего ничего, зарплата манит меня, как Аргентина негра.

Всем перечислили на карту, а мне как новенькому нужно ехать в главный офис за бумажками.

пятница, 12 марта 2010 г.

И опять

Сегодня как не странно опять пятница. И хоть Грозный Глаз (так зовут в узких кругах нашего босса) не догадыватся (или делат вид что не догадывается) сегодня будет очередная пьянка.
На этот раз только пиво и младший состав дизайнеров - Юля, Надя и Ира. Причем их начальницу зовут тоже Ира, но называются всего, естественно - Ирина Николаевна.
Давно хотел рассказать про программистов их тут 8 человек, а со мной 9. А с ГГ - 10.
Мы(а я безгода неделя) вроде поддерживаем и пишет некую корпаративную система, анализа продаж и отгрузки какого-то производства.
Причем тут производство еще не понял, но это не суть.
Система написана на Delphi (не навижу) + БД SyBase SQL, синтаксис впринципе SQL-T89, но они хотят сделать из всего этого (куча BPL библиотек, сторонних dll и еще куча всего) - тонкий веб клиент.
Собственно для этого и нужны дизайнерши, Миха (он рубит в дизайне&Java&html) и я как специалист по подключаемым модулям (они будут на C++), так решил наш главный гуру - Сергей (с ним всегда советуются ГГ)

среда, 10 марта 2010 г.

Устаналиваем размер окна

На проекте, в котором сейчас работаю нужно мне изменить размер окна - задать точное значение в пикселях, видимой части.
Есть такая штука как window.innerWidth и window.Height, но у меня в опере эти переменные доступны только для чтения,
т.е. присваивай им что угодно лучше не станет.

Есть еще функция resizeTo() которая изменяет размер окна - но делает это для общего размера, включая полоску шапки+отступы+всякая фигня.
А мне нужно именно размер видимой части.

Все гениальное просто:
var ww = window.outerWidth - window.innerWidth;
var hh = window.outerHeight - window.innerHeight;
resizeTo( width+ww,height+hh);

вторник, 9 марта 2010 г.

Работа

На работе все тихо. Это норма - некий ритуал расслабона, говорят что Евгеньевич скорее в курсе про "продолжения банкета".
Меня доспутили в закрытую комнату корпаративный болталки (юзаем джабер)

суббота, 6 марта 2010 г.

Не помню

Да вчера повеселились. Начали ровно в 18:00, когда закончился рабочий день. Не шучу, ровно в !8:00 начали сдвигать столы.

Купили кто-то где-то ведро роз и помоему конфет с открытками. Подарили.

Откуда-то шампанское и вино на столах. (Мой стол был в качестве столика для закусок)
Потому в часиков 7 Михаил Евгеньевич, который не пил, нас покинул.
И тут понеслось - кроме вина оказалось еще есть коньяк и пиво,

Короче никому не советую мешать шампанское, вино, коньяк и пиво.
Ничего не помню после девяти. Домой меня дотащил мой новый друг Миха. Он помощник сисдамина, учится на 4 курсе моего же университета.
Это мне родители сказали. Сегодня.

пятница, 5 марта 2010 г.

Рабочая пятница

Сегодня на работе все гудят.
Потому как мне сказали целых три праздника.
Первая - сегодня пятница, второй - сегодня 5 число и пятница и третье - отмечаем 8 марта.
Ага, вы не ошиблись, оказывается в соседней комнате у нас есть дизайнеры. Вернее дизайнерши в количестве пяти штук и с разбегом возраста 19-35 лет.

Будем поздравлять. (Пришлось скинутся практически последними 300 рублями, и то все со скидкой за малый срок работы).

Продолжение будет. Пишу с работы, я мастерски овладел мастерством писать практически в слепую в свернутый блокнот раземром в одну строку и интуитивно нажимать alt+tab. На звук.

четверг, 4 марта 2010 г.

Первый день

Первый рабочий день.
Ну что сказать, пока нашел дополнительный офис (он кстати почти на противоположном конце города находился), слегонца опоздал.

Захожу в дверь и на меня впираются штук десять бошк торчавших из-под монитора. Большинство в очках. И смотрят как на ненормального.

Ну я спросил - где Михаил Евгеньевич (это тот чел который собеседование проводил), тыкнули пальцом в бок.
Из какой-то каморки выскользнул мой вчерашний интерьвьювер и показал мой стол.
Ипона мать - стол посреди комнаты!!!

Как бы описать - значит остальные столы и компы размазаны по периметру (кроме окна и двери), а ровно посредине стоит стол.
Конечно спиной к окну (лицом к двери), но все равно в монитор смотрят минимум 4 человека (по двое слева и справа).

Мне же на обозрения только вид на дверь. Которая закрыта и на которой объявление, что уходя я должен гасить всех Свет.

P.S.
Сильно выматался, поэтому спать.

среда, 3 марта 2010 г.

Собеседование

Короче по собеседованию. Сразу итоги - меня взяли. Сразу минусы - зарплата на испытательный срок всего 8000, что мало, однако испытательный срок всего месяц.
Еще из минусов - они проповедуют культ Delphi и какой-то странной СУБД, название не запомнил, но это не Oracl и не мускол.

вторник, 2 марта 2010 г.

Не ожидал

Первый раз понял что слово "накаркал" может вызывать положительные эмоции. Вчера зашел к одной старой подруге, а у нее старший брат работает в фирме по продажам оргтехники.
Короче им оказывается нужен программист. Он позвонил боссу, и завтра у меня собеседование.

понедельник, 1 марта 2010 г.

Весна

Первый день весны. Хотя весной и не пахнет. Холодно и мрачно. И хочется добавить беспреспективно.

воскресенье, 28 февраля 2010 г.

Диплом

Пишу диплом, т.к. пока не густо. Вчера звонил по объявлениям в газету - по нулям.
Конечно, понимаю, кризис и все такое - но я ведь тоже планки не задераю по зарплате.
По городу средняя зарплата (рабочим) в районе 10-13 тысяч, я называю 10-15 в принципе около того.

Но я же не рабочий, а без диплома пяти минут инженер.

пятница, 26 февраля 2010 г.

Фриланс

Знакомый уговаривает занятся фрилансом, но думаю пока мне стоит порабоать официально с белой зарплатой и оплачиваемыми обедами (мечтаю).

А фрилансом успею и потом, оно, знаете ли, не убежит.

четверг, 25 февраля 2010 г.

Досада

Как же плохо сыграли наши против канадцев :(

среда, 24 февраля 2010 г.

Истек срок

Прошла неделя и естественно никто не позвонил. Не удивительно.

вторник, 23 февраля 2010 г.

23 февраля

Вчера сходил в институт. Девчонки нам устроили поздравления с днем защитника. Хотя мужское большинство, сказало что не верит ни в этот праздник, ни в армию.

Хорошо посидели.
Оля - наша скромница, показала танец живота.
Это было нечто.

вторник, 16 февраля 2010 г.

Последний звонок

Обзвонил фирм двадцать, неустраивает либо уровень зарплаты либо я :)

Я, кстати, ищу работу программистом. Но всем нужны гребанные 1С'ники, а я его не люблю.
Нет конечно я могу заниматься скриптоложеством, но если только сильно припрет.
Буду ждать завтра. Да пара фирм мне сказaли что перезвонят.

Я верю

понедельник, 15 февраля 2010 г.

Ищу работу

Закончилась последняя сессия, нужно искать работу.
Есть конечно еще диплом, но думаю и его успею. А работа нужней, деньги на кафешки, подруг, разное. Хоть и живу с родителями.

Вчера дал резюме на нескольких сайтах и собрал телефоны буду завтра звонить.

Ах да зовут меня Тимофей и я будущий инженер.

вторник, 9 февраля 2010 г.

Привет, мир!

Следуя новым современным тендециям, решил тоже завести себе блог.
Я - студент-программист.