http://www.programmersforum.ru/showthread.php?t=59399
http://www.improvement.ru/zametki/bischke/
http://www.connect.ru/article.asp?id=8046
http://ru.wikipedia.org/wiki/Getting_Things_Done
http://ru.wikipedia.org/wiki/Лайфхакер
http://ru.wikipedia.org/wiki/Мнемотехника
Ярлыки
- С++ (3)
- Стихи (1)
- тонировка (1)
- Цитаты (2)
- ALTlinux (1)
- Apache (2)
- big-endian (1)
- Blogger (1)
- books (3)
- books links (1)
- Buisness (10)
- C (1)
- C# (5)
- c++ (27)
- car (8)
- Cheat (1)
- CSS (1)
- DLL (1)
- Draw (1)
- Eclipse (2)
- Films (1)
- Firefox (4)
- Flash (1)
- GTK (2)
- GUI (1)
- Home server (1)
- Hotels (1)
- HTML (6)
- IE (1)
- Internet (2)
- Java (1)
- JavaScript (6)
- jQuery (1)
- KDE (1)
- KeeTouch (1)
- Linux (34)
- little-endian (1)
- Makefile (1)
- MFC (6)
- multi-thread (2)
- Music (1)
- ODBC (2)
- OpenBox (2)
- photo (4)
- PHP (38)
- programing (2)
- proxy (1)
- QML (37)
- Qt (41)
- QtCreator (2)
- RegExp (3)
- Shopping (12)
- shutdown (1)
- Soft (1)
- Sound Card (1)
- SQL (1)
- SQL Server (14)
- Subversion (1)
- SVN (1)
- teach (4)
- text-editor (1)
- Travels (1)
- Ubuntu (38)
- Upstart (1)
- Vi (2)
- VirtualBox (2)
- Virtualization (1)
- vkontakte.ru (1)
- Web (2)
- Web-Kit (5)
- WinAPI (7)
- Windows (4)
пятница, 29 апреля 2011 г.
среда, 27 апреля 2011 г.
понедельник, 25 апреля 2011 г.
Статические библиотеки в Linux
1) Статическая библиотека - это такая библиотека, которая связывается (линкуется) с программой в момент компиляции оной. При этом объектный код библиотеки помещается в исполняемый файл программы. С этой точки зрения статическая библиотека похожа на исходный код программы, с которой она связывается, за исключением того, что библиотека компилируется "кем-то еще" и программист, использующий библиотеку, имеет дело исключительно только с результатом этой компиляции.
В Linux, как правило, файл-статическая_библиотека имеет расширение ".a"
2) Статические библиотеки на языке C.
Исходный код библиотеки:
######################
#include
extern int hello()
{
printf("Hello world! I'm static library\n");
return 0;
};
######################
Сохраните его в файле static.c
Ключевое слово extern необходимо для того, чтобы функция была видна в программе.
Теперь скомпилируем (! без линковки) библиотеку:
gcc -c static.c -o static.o
(на выходе имеем файл static.o, содержащий объектный код нашей библиотеки)
ar rc libMY_STATIC.a static.o
ar упаковывает несколько (! Это важно. Дело не ограничивается только одним объектным файлом) объектных файлов в одну статическую библиотеку. Статическая библиотека имеет расширение ".a", при этом ее название должно начинаться с "lib" (дань традиции).
Параметры ar:
r - предписывает заменять старые версии объектных файлов новыми - необходим для переупаковки библиотеки;
c - создать статическую библиотеку, если та еще не существует.
Проиндексируем функции внутри библиотеки для более быстрой линковки:
ranlib libMY_STATIC.a
Итак, мы получили статическую библиотеку libMY_STATIC.a.
Теперь попытаемся использовать библиотеку в нашей программе:
Исходный текст программы (C):
######################
#include
int main()
{
int x = hello();
printf("Return code: %d\n",x);
return 0;
}
######################
Сохраните его в файле program1.c
Способы связывания библиотеки и программы:
- Скомпилируем и слинкуем (в том числе с нашей библиотекой) нашу программу:
gcc program1.c libMY_STATIC.a
(предполагается, что в качестве аргумента gcc будут переданы полные пути (!) к вашим библиотекам)
И запустим:
./a.out
На выходе получим:
Hello world! I'm static library
Return code: 0
Отлично!
- Скомпилируйте с помощью команды:
gcc program1.c -L. -lMY_STATIC -o a1.out
Смысл аргументов:
-L - путь к каталогу, содержащему наши библиотек (используйте "-L -L - название нашей библиотеки (это важно - название (!), а не имя файла - собственно, если библиотека имеет своим именем "libBLABLABLA.a", то ее названием будет "BLABLABLA" - т.е. имя без приставки "lib" и расширения ".a") (для нескольких библиотек используйте "-l -l ...")
Запустите файл a1.out на выполнение и удостовертесь, что результаты те же, что и в предыдущем пункте.
- Видоизменим предыдущий способ - уберем аргументы "-L":
В начале проверим значение переменной LD_LIBRARY_PATH и содержимое файла /etc/ld.so.conf:
echo $LD_LIBRARY_PATH ; cat /etc/ld.so.conf
На экране появился некоторый список каталогов - это те каталоги, в которых система ищет библиотеки при их линковке с программой (еще к таким каталогам относятся:
/lib
/usr/lib
. Поместите libMY_STATIC.a в один из этих каталогов:
(Я, к примеру, засуну нашу библиотеку в каталог /usr/lib):
su -c 'cp libMY_STATIC.a /usr/lib'
(в Ubuntu - sudo cp libMY_STATIC.a /usr/lib)
ldconfig
(ldconfig обновляет кеш данных о библиотеках линковщика)
Теперь скомпилируем и запустим нашу программу:
gcc program1.c -lMY_STATIC -o a2.out
./a2.out
Результат:
Hello world! I'm static library
Return code: 0
Бинго! Кстати, таким вот способом вы можете подключать к своей программе любые статические библиотеки из приведенных выше каталогов.
* Бывает полезно определить все прототипы функций библиотеки в некотором заголовочном файле, который будет потом включаться в вашу программу. Это не обязательно, но удобно.
3) Статические библиотеки на языке Assembler.
Представьте, что вам необходимо оптимизировать выполнение некоторых действий в вашей программе. Разумеется, вы может применить ключевое слово asm (если пишите программу на C/C++), но лучшим решением будет создание оптимизированной вами библиотеки на языке Assembler и подключение ее к вашей программе. Давайте попробуем:
*Кстати, углубляться в процесс компиляции библиотеки и ее линковки с вашей программой я не буду (!). Этот процесс идентичен полностью (!) тому же процессу для библиотек, написанных на языке C.
Итак, имеем вот такую программу:
######################
#include
int main()
{
printf("Hello world!\n");
return 0;
};
######################
Сохраните ее в файле program2.c
Скомпилируйте ее и запустите:
gcc program2.c
./a.out
Я получил:
Hello world!
Отлично.
Я привел этот пример, чтобы показать действительно возможность оптимизации программы с помощью библиотеки на Assembler'е. Вы можете заметить, что вызов printf в main() не оптимален, т.к. printf, по крайней мере, один раз использует цикл while для поиска вхождений конструкций "%..." в строку. Это не оптимально, т.к. очевидно, что таковых символов у нас нет. Оптимизируем нашу программу с помощью библиотеки на Assebmler'е:
######################
.text
.globl my_printf
my_printf:
movl $4,%eax
xorl %ebx,%ebx
incl %ebx
movl $hw,%ecx
movl $hw_e,%edx
int $0x80
xorl %eax,%eax
ret
.data
hw:
.string "Hello world!\012"
hw_e = . - hw
######################
Сохраните исходный код библиотеки в файле static2.s
Это AT&T наречие Assembler'а.
.globl my_printf - "my_printf" описывается как глобальная (видимая в других объектных файлах) последовательность
my_printf: - начало описание функции my_printf
movl $4,%eax - поместим 4 в eax (4 - номер системного вызова write)
xorl %ebx,%ebx и incl %ebx - поместим в ebx единицу - номер STDOUT
movl $message,%ecx - в ecx запишем адрес начала сообщения
movl $message_l,%edx - в edx поместим адрес конца сообщения
int $0x80 - произведем системный вызов write
xorl %eax,%eax - в eax - код возврата (0)
ret - вернемся в вызывающую процедуру
.data - секция данных (разумеется, мы могли бы передавать выводимую строку как параметр, но тогда вычисление ее конца потребовало бы от нас дополнительных усилий, что, согласитесь, лениво :-) )
Теперь получим библиотеку:
gcc -c static2.s -o static2.o
ar rc static2.a static2.o
ranlib static2.a
На выходе имеем статическую библиотеку static2.a
Теперь напишем программу, использующую эту статическую библиотеку (язык C):
######################
#include
int my_printf();
int main()
{
int x = my_printf();
return 0;
}
######################
Сохраните текст программы в файле program3.c
Заметьте, я добавил прототип библиотечной функции для удобства.
Скомпилируем и слинкуем программу с библиотекой, после чего запустим программу на выполнение:
gcc program3.c static2.a
./a.out
На выходе получим:
Hello world!
* Принцип линкования статических библиотек с программами на Assembler'е аналогичен принципу для программ на C. Просто, когда будете использовать статические библиотеки в Assembler'е, помните о соглашениях C по передаче аргументов в функцию и возвращению результата.
4) Статические библиотеки на языке C++.
Принцип создания аналогичен статическим библиотекам на C, но перед каждой экспортируемой функцией не забывайте добавлять:
extern "C"
(экспортировать как функцию на C - т.е. без расширения имен).
* Кстати, используйте g++ вместо gcc, если захотите протестировать приведенные выше примеры.
Подключение к вашей программе аналогично подключению к программе, написанной на C, за исключением необходимости явно добавлять к тексту программы прототипы импортируемых функций в следующем виде:
extern "C" PROTOTYPE
Где PROTOTYPE - прототип импортируемой функции.
* При подключении статических библиотек на C++ к программе на C сопряжено с некоторыми трудностями - т.к. при компиляции и линковки программы необходимо будет также вручную подключить системные библиотеки для реализации функционала, предоставляемого библиотекой Standart C++ сверх того, что предоставляет библиотека Standart C.
----------------------------------------------------------------------------------------------------------------
link
В Linux, как правило, файл-статическая_библиотека имеет расширение ".a"
2) Статические библиотеки на языке C.
Исходный код библиотеки:
######################
#include
extern int hello()
{
printf("Hello world! I'm static library\n");
return 0;
};
######################
Сохраните его в файле static.c
Ключевое слово extern необходимо для того, чтобы функция была видна в программе.
Теперь скомпилируем (! без линковки) библиотеку:
gcc -c static.c -o static.o
(на выходе имеем файл static.o, содержащий объектный код нашей библиотеки)
ar rc libMY_STATIC.a static.o
ar упаковывает несколько (! Это важно. Дело не ограничивается только одним объектным файлом) объектных файлов в одну статическую библиотеку. Статическая библиотека имеет расширение ".a", при этом ее название должно начинаться с "lib" (дань традиции).
Параметры ar:
r - предписывает заменять старые версии объектных файлов новыми - необходим для переупаковки библиотеки;
c - создать статическую библиотеку, если та еще не существует.
Проиндексируем функции внутри библиотеки для более быстрой линковки:
ranlib libMY_STATIC.a
Итак, мы получили статическую библиотеку libMY_STATIC.a.
Теперь попытаемся использовать библиотеку в нашей программе:
Исходный текст программы (C):
######################
#include
int main()
{
int x = hello();
printf("Return code: %d\n",x);
return 0;
}
######################
Сохраните его в файле program1.c
Способы связывания библиотеки и программы:
- Скомпилируем и слинкуем (в том числе с нашей библиотекой) нашу программу:
gcc program1.c libMY_STATIC.a
(предполагается, что в качестве аргумента gcc будут переданы полные пути (!) к вашим библиотекам)
И запустим:
./a.out
На выходе получим:
Hello world! I'm static library
Return code: 0
Отлично!
- Скомпилируйте с помощью команды:
gcc program1.c -L. -lMY_STATIC -o a1.out
Смысл аргументов:
-L - путь к каталогу, содержащему наши библиотек (используйте "-L -L - название нашей библиотеки (это важно - название (!), а не имя файла - собственно, если библиотека имеет своим именем "libBLABLABLA.a", то ее названием будет "BLABLABLA" - т.е. имя без приставки "lib" и расширения ".a") (для нескольких библиотек используйте "-l -l ...")
Запустите файл a1.out на выполнение и удостовертесь, что результаты те же, что и в предыдущем пункте.
- Видоизменим предыдущий способ - уберем аргументы "-L":
В начале проверим значение переменной LD_LIBRARY_PATH и содержимое файла /etc/ld.so.conf:
echo $LD_LIBRARY_PATH ; cat /etc/ld.so.conf
На экране появился некоторый список каталогов - это те каталоги, в которых система ищет библиотеки при их линковке с программой (еще к таким каталогам относятся:
/lib
/usr/lib
. Поместите libMY_STATIC.a в один из этих каталогов:
(Я, к примеру, засуну нашу библиотеку в каталог /usr/lib):
su -c 'cp libMY_STATIC.a /usr/lib'
(в Ubuntu - sudo cp libMY_STATIC.a /usr/lib)
ldconfig
(ldconfig обновляет кеш данных о библиотеках линковщика)
Теперь скомпилируем и запустим нашу программу:
gcc program1.c -lMY_STATIC -o a2.out
./a2.out
Результат:
Hello world! I'm static library
Return code: 0
Бинго! Кстати, таким вот способом вы можете подключать к своей программе любые статические библиотеки из приведенных выше каталогов.
* Бывает полезно определить все прототипы функций библиотеки в некотором заголовочном файле, который будет потом включаться в вашу программу. Это не обязательно, но удобно.
3) Статические библиотеки на языке Assembler.
Представьте, что вам необходимо оптимизировать выполнение некоторых действий в вашей программе. Разумеется, вы может применить ключевое слово asm (если пишите программу на C/C++), но лучшим решением будет создание оптимизированной вами библиотеки на языке Assembler и подключение ее к вашей программе. Давайте попробуем:
*Кстати, углубляться в процесс компиляции библиотеки и ее линковки с вашей программой я не буду (!). Этот процесс идентичен полностью (!) тому же процессу для библиотек, написанных на языке C.
Итак, имеем вот такую программу:
######################
#include
int main()
{
printf("Hello world!\n");
return 0;
};
######################
Сохраните ее в файле program2.c
Скомпилируйте ее и запустите:
gcc program2.c
./a.out
Я получил:
Hello world!
Отлично.
Я привел этот пример, чтобы показать действительно возможность оптимизации программы с помощью библиотеки на Assembler'е. Вы можете заметить, что вызов printf в main() не оптимален, т.к. printf, по крайней мере, один раз использует цикл while для поиска вхождений конструкций "%..." в строку. Это не оптимально, т.к. очевидно, что таковых символов у нас нет. Оптимизируем нашу программу с помощью библиотеки на Assebmler'е:
######################
.text
.globl my_printf
my_printf:
movl $4,%eax
xorl %ebx,%ebx
incl %ebx
movl $hw,%ecx
movl $hw_e,%edx
int $0x80
xorl %eax,%eax
ret
.data
hw:
.string "Hello world!\012"
hw_e = . - hw
######################
Сохраните исходный код библиотеки в файле static2.s
Это AT&T наречие Assembler'а.
.globl my_printf - "my_printf" описывается как глобальная (видимая в других объектных файлах) последовательность
my_printf: - начало описание функции my_printf
movl $4,%eax - поместим 4 в eax (4 - номер системного вызова write)
xorl %ebx,%ebx и incl %ebx - поместим в ebx единицу - номер STDOUT
movl $message,%ecx - в ecx запишем адрес начала сообщения
movl $message_l,%edx - в edx поместим адрес конца сообщения
int $0x80 - произведем системный вызов write
xorl %eax,%eax - в eax - код возврата (0)
ret - вернемся в вызывающую процедуру
.data - секция данных (разумеется, мы могли бы передавать выводимую строку как параметр, но тогда вычисление ее конца потребовало бы от нас дополнительных усилий, что, согласитесь, лениво :-) )
Теперь получим библиотеку:
gcc -c static2.s -o static2.o
ar rc static2.a static2.o
ranlib static2.a
На выходе имеем статическую библиотеку static2.a
Теперь напишем программу, использующую эту статическую библиотеку (язык C):
######################
#include
int my_printf();
int main()
{
int x = my_printf();
return 0;
}
######################
Сохраните текст программы в файле program3.c
Заметьте, я добавил прототип библиотечной функции для удобства.
Скомпилируем и слинкуем программу с библиотекой, после чего запустим программу на выполнение:
gcc program3.c static2.a
./a.out
На выходе получим:
Hello world!
* Принцип линкования статических библиотек с программами на Assembler'е аналогичен принципу для программ на C. Просто, когда будете использовать статические библиотеки в Assembler'е, помните о соглашениях C по передаче аргументов в функцию и возвращению результата.
4) Статические библиотеки на языке C++.
Принцип создания аналогичен статическим библиотекам на C, но перед каждой экспортируемой функцией не забывайте добавлять:
extern "C"
(экспортировать как функцию на C - т.е. без расширения имен).
* Кстати, используйте g++ вместо gcc, если захотите протестировать приведенные выше примеры.
Подключение к вашей программе аналогично подключению к программе, написанной на C, за исключением необходимости явно добавлять к тексту программы прототипы импортируемых функций в следующем виде:
extern "C" PROTOTYPE
Где PROTOTYPE - прототип импортируемой функции.
* При подключении статических библиотек на C++ к программе на C сопряжено с некоторыми трудностями - т.к. при компиляции и линковки программы необходимо будет также вручную подключить системные библиотеки для реализации функционала, предоставляемого библиотекой Standart C++ сверх того, что предоставляет библиотека Standart C.
----------------------------------------------------------------------------------------------------------------
link
пятница, 22 апреля 2011 г.
среда, 20 апреля 2011 г.
Qt работа с локалью
Покопался в Qt-шных аналогах функции atof! Выяснилось, что функция ToDouble(bool* ok) тоже зависит от локали. Но есть отличия:
1) есть возможность увидеть ошибку быстрее, так как программисту предлагают после преобразования проверять значение ok
2) очень важное отличие - при установке такого формата setlocale(LC_ALL, 0) функция преобразует и строчку "1234,45" and "1234.45" в вещественное число 1234.45!
Так что, если используете библиотеку Qt есть такие советы:
1) Указывать в приложении напрямую setlocale()!
2) Использовать qt-шные средства преобразования в вещественные числа! Преобразование легче отследить и немного универсальнее!
P.S. Немцы молодцы!
QLocale::setDefault(QLocale::C);
d = QString( "1234,56" ).toDouble(&ok); // ok=false
d = QString( "1234.56" ).toDouble(&ok); // ok=true, d = 1234.56
QLocale::setDefault(QLocale::German);
d = QString( "1234,56" ).toDouble(&ok); // ok=true, d = 1234.56
d = QString( "1234.56" ).toDouble(&ok); // ok=true, d = 1234.56
link
1) есть возможность увидеть ошибку быстрее, так как программисту предлагают после преобразования проверять значение ok
2) очень важное отличие - при установке такого формата setlocale(LC_ALL, 0) функция преобразует и строчку "1234,45" and "1234.45" в вещественное число 1234.45!
Так что, если используете библиотеку Qt есть такие советы:
1) Указывать в приложении напрямую setlocale()!
2) Использовать qt-шные средства преобразования в вещественные числа! Преобразование легче отследить и немного универсальнее!
P.S. Немцы молодцы!
QLocale::setDefault(QLocale::C);
d = QString( "1234,56" ).toDouble(&ok); // ok=false
d = QString( "1234.56" ).toDouble(&ok); // ok=true, d = 1234.56
QLocale::setDefault(QLocale::German);
d = QString( "1234,56" ).toDouble(&ok); // ok=true, d = 1234.56
d = QString( "1234.56" ).toDouble(&ok); // ok=true, d = 1234.56
link
c++ работа с локалью
функция localeconv() возвращает структуру содержащую настройки локали
структуру можно посмотреть тут
#include
#include
int main ()
{
setlocale (LC_MONETARY,"");
struct lconv * lc;
lc=localeconv();
printf ("Local Currency Symbol: %s\n",lc->currency_symbol);
printf ("International Currency Symbol: %s\n",lc->int_curr_symbol);
return 0;
}
link
структуру можно посмотреть тут
#include
#include
int main ()
{
setlocale (LC_MONETARY,"");
struct lconv * lc;
lc=localeconv();
printf ("Local Currency Symbol: %s\n",lc->currency_symbol);
printf ("International Currency Symbol: %s\n",lc->int_curr_symbol);
return 0;
}
link
понедельник, 18 апреля 2011 г.
c++ пример gmplib
#include
#include
using namespace std;
//sin(M_PI_4) = 0,70710678118654752440084436210485
#define M_PI_4 0.78539816339744830962
#define top 100
#define numsize 400
string msin( long double x )
{
mpf_t ret, temp, num;
mp_exp_t exp;
int i, j;
string str;
mpf_init_set_d( num, x );
mpf_init2( ret, numsize );
mpf_init2( temp, numsize );
for( i = 1 ; i <= top ; i += 2 )
{
mpf_pow_ui( temp, num, i );
for( j = 1 ; j <= i ; ++j )
mpf_div_ui( temp, temp, j );
if ( (i-1)%4 )
mpf_sub( ret, ret, temp );
else
mpf_add( ret, ret, temp );
}
str = mpf_get_str( NULL, &exp, 10, 100, ret );
str.insert( exp, "." );
if ( str[0] == '.' )
str.insert( 0, "0" );
mpf_clear( ret );
mpf_clear( temp );
mpf_clear( num );
return str;
}
string mcos( long double x )
{
mpf_t ret, temp, num;
mp_exp_t exp;
int i, j;
string str;
mpf_init_set_d( num, x );
mpf_init2( ret, numsize );
mpf_set_ui( ret, 1 );
mpf_init2( temp, numsize );
for( i = 2 ; i <= top ; i += 2 )
{
mpf_pow_ui( temp, num, i );
for( j = 1 ; j <= i ; ++j )
mpf_div_ui( temp, temp, j );
if ( i%4 )
mpf_sub( ret, ret, temp );
else
mpf_add( ret, ret, temp );
}
str = mpf_get_str( NULL, &exp, 10, 100, ret );
str.insert( exp, "." );
if ( str[0] == '.' )
str.insert( 0, "0" );
mpf_clear( ret );
mpf_clear( temp );
mpf_clear( num );
return str;
}
int main( int argc, char **argv )
{
cout << msin(M_PI_4) << "\n" << mcos(M_PI_4) << endl;
return 0;
}
link
#include
using namespace std;
//sin(M_PI_4) = 0,70710678118654752440084436210485
#define M_PI_4 0.78539816339744830962
#define top 100
#define numsize 400
string msin( long double x )
{
mpf_t ret, temp, num;
mp_exp_t exp;
int i, j;
string str;
mpf_init_set_d( num, x );
mpf_init2( ret, numsize );
mpf_init2( temp, numsize );
for( i = 1 ; i <= top ; i += 2 )
{
mpf_pow_ui( temp, num, i );
for( j = 1 ; j <= i ; ++j )
mpf_div_ui( temp, temp, j );
if ( (i-1)%4 )
mpf_sub( ret, ret, temp );
else
mpf_add( ret, ret, temp );
}
str = mpf_get_str( NULL, &exp, 10, 100, ret );
str.insert( exp, "." );
if ( str[0] == '.' )
str.insert( 0, "0" );
mpf_clear( ret );
mpf_clear( temp );
mpf_clear( num );
return str;
}
string mcos( long double x )
{
mpf_t ret, temp, num;
mp_exp_t exp;
int i, j;
string str;
mpf_init_set_d( num, x );
mpf_init2( ret, numsize );
mpf_set_ui( ret, 1 );
mpf_init2( temp, numsize );
for( i = 2 ; i <= top ; i += 2 )
{
mpf_pow_ui( temp, num, i );
for( j = 1 ; j <= i ; ++j )
mpf_div_ui( temp, temp, j );
if ( i%4 )
mpf_sub( ret, ret, temp );
else
mpf_add( ret, ret, temp );
}
str = mpf_get_str( NULL, &exp, 10, 100, ret );
str.insert( exp, "." );
if ( str[0] == '.' )
str.insert( 0, "0" );
mpf_clear( ret );
mpf_clear( temp );
mpf_clear( num );
return str;
}
int main( int argc, char **argv )
{
cout << msin(M_PI_4) << "\n" << mcos(M_PI_4) << endl;
return 0;
}
link
c++ Implicit declaration of function
Интересный аспект стандарта языка Си, на который я раньше никогда не обращал внимания. Итак, следующий код:
int main() {
void *a, *b;
a = foo(b);
return 0;
}
Прототип функции foo не объявлен. Если теперь оттранслировать этот код (без линковки), то код соберется нормально и мы не получим никаких сообщений об ошибках, только предупреждения:
$ gcc -c -Wall test.c
test.c: In function ‘main’:
test.c:4: warning: implicit declaration of function ‘foo’
test.c:4: warning: assignment makes pointer from integer without a cast
Компилятор сообщает нам, что функция foo объявлена неявно и т.к. он не видел прототипа этой функции, то (по стандарту) делается ряд предположений. Например предполагается, что функция возвращает int, что влечет за собой следующее предупреждение о том, что из этого самого предполагаемого int‘а мы пытаемся неосторожно сделать указатель. Об этом и других предполложениях сказано в стандарте C89, раздел 3.3.2.2 Function calls. В новом стандарте C99 о неявном преобразовании возвращаемого типа функции ничего не говориться, или я не заметил. См. также Draft ANSI C Rationale, 3.3.2.2 Function calls.
В общем и целом, сделано всё это для совместимости со старыми библиотеками.
Ошибка о том, что данная функция не определена вылезает только на этапе линковки:
$ gcc -Wall test.o
test.o: In function `main':
test.c:(.text+0x12): undefined reference to `foo'
collect2: ld returned 1 exit status
link
link
int main() {
void *a, *b;
a = foo(b);
return 0;
}
Прототип функции foo не объявлен. Если теперь оттранслировать этот код (без линковки), то код соберется нормально и мы не получим никаких сообщений об ошибках, только предупреждения:
$ gcc -c -Wall test.c
test.c: In function ‘main’:
test.c:4: warning: implicit declaration of function ‘foo’
test.c:4: warning: assignment makes pointer from integer without a cast
Компилятор сообщает нам, что функция foo объявлена неявно и т.к. он не видел прототипа этой функции, то (по стандарту) делается ряд предположений. Например предполагается, что функция возвращает int, что влечет за собой следующее предупреждение о том, что из этого самого предполагаемого int‘а мы пытаемся неосторожно сделать указатель. Об этом и других предполложениях сказано в стандарте C89, раздел 3.3.2.2 Function calls. В новом стандарте C99 о неявном преобразовании возвращаемого типа функции ничего не говориться, или я не заметил. См. также Draft ANSI C Rationale, 3.3.2.2 Function calls.
В общем и целом, сделано всё это для совместимости со старыми библиотеками.
Ошибка о том, что данная функция не определена вылезает только на этапе линковки:
$ gcc -Wall test.o
test.o: In function `main':
test.c:(.text+0x12): undefined reference to `foo'
collect2: ld returned 1 exit status
link
link
четверг, 14 апреля 2011 г.
вторник, 12 апреля 2011 г.
C++ Удалить одинаковые элементы в массиве
#include | ||||||||
#include <vector> | ||||||||
using namespace std; | ||||||||
int main() | ||||||||
{ | ||||||||
// заполняем массив и выводим его на экран | ||||||||
cout << "Исходный массив" << endl; | ||||||||
vector<int> a; | ||||||||
for (int i = 0; i < 100; ++i) | ||||||||
{ | ||||||||
int r = rand() % 15; | ||||||||
a.push_back(r); | ||||||||
cout << r << " "; | ||||||||
} | ||||||||
cout << endl; | ||||||||
// заполняем другой массив уникальными значениями | ||||||||
cout << "Результирующий массив" << endl; | ||||||||
set<int> s; | ||||||||
vector<int> u; | ||||||||
for (vector<int>::iterator i = a.begin(); i != a.end(); ++i) | ||||||||
if (s.find(*i) == s.end()) | ||||||||
{ | ||||||||
s.insert(*i); | ||||||||
u.push_back(*i); | ||||||||
cout << *i << " "; | ||||||||
} | ||||||||
cout << endl; | ||||||||
} | link |
C++ Аргументы функции main(): argv и argc
#include#include int main(int argc, char *argv[]) { if(argc!=2) { printf("Вы забыли ввести свое имя.\n"); exit(1); } printf("Привет %s", argv[1]); return 0; }
link
C++ удаление объектов из вектора
void remove(Student &obj) {
std::vector<Student>::iterator it;
for(it=data.begin(); it!=data.end(); it++)
if(strcmp((*it).get_name(),obj.get_name())) {
it = data.erase(it);
--it;
}
--it делается для того, чтобы итератор не указывал на удаленный элемент.
Ещё вариант --
data.erase(std::remove_if(data.begin(), data.end(), <сюда впихни фугнкцию-сравнивалку>), data.end());
link
printf, fprintf, sprintf - форматный вывод
Описание
Осуществляют форматную печать. fprintf - пишет литеры в поток fp. printf - пишет литеры в поток stdout. sprintf - пишет литеры в память buffer. Аргументы интерпретируются в соответствии со строкой формата, оканчивающейся 0. Строка формата является последовательностью литер со встроенными командами преобразования. Литеры, не являющиеся частью команд, подлежат выводу. Команды преобразования состоят из : '%'{flag}[field_width]['.'precision][l или L]conversion_char где : % Означает начало команды преобразования. Чтобы напечатать '%', надо использовать '%%'. flag characters Литеры режимов - - Означает необходимость выравнивания информации по левому краю поля вывода. + - Означает, что преобразование, включающее знак, должно начинаться с + или -. пробел (space) - Означает, что в случае преобразования поло- жительного результат начинается с пробела. Режим + перекрывает режим space. # - Имеет смысл для преобразования 'x' или 'X' и приводит к добавлению перед выводом сим- волов 0x или 0X. Для преобразования 'о' в вывод добавляется лидирующий ноль. В случае преобразований e, E, f, g, G всег- да появляется десятичная точка. Если это преобразование g или G, замыкающие 0 не будут опускаться. Field_width Ширина поля Десятичное целое, управляющее минимальным количест- вом печатаемых литер. Если действительное число литер меньше, чем field_width, это число допол- няется пробелами. Если строка цифр field_width на- чинается с 0, для дополнения используется 0. Если field_width есть литера *, действительное зна- чение длины поля вывода берется из следующего цело- го аргумента. Если field_width отрицательно, счита- ется, что задан флаг '-', а в качестве field_width берется абсолютное значение. Если действительное число литер превосходит field_width, это поле соот- ветственно увеличивается. Precision Точность Эта строка цифр, следующая за '.', определяет точ- ность преобразования. Если цифры за точкой отсутст- вуют, точность равна 0. Для преобразования целых точность есть минимальное количество выводимых цифр. Для 'g' и 'G'- это максимальное количество значащих цифр. Для 'e', 'E' и 'f'- это количество цифр после десятичной точки. Для 's' - это максимальное коли- чество литер в строке. Если точность включает лиди- рующий 0, тогда свободное поле вывода заполняется 0. l В случае спецификаций преобразования o, b, u, x, X, i, d используемый аргумент должен быть типа long, исключение составляет преобразование p, когда аргу- мент должен быть дальним указателем. Для других преобразований этот флаг игнорируется. L Этот флаг игнорируется. Conversion_char Преобразующая литера Это одна из литер d, i, o, b, u, x, X, f, e, E, g, G, c, s, p, n, %. Действие других литер неопре- делено. d,i,o,b,u,x,X Соответсвующий целый аргумент преобразуется в стро- ку цифр, причем, 'o' производит беззнаковое восьме- ричное, `b' - беззнаковое двоичное, 'u' - беззнако- вое десятичное, 'x' и 'X' - беззнаковое шестнадца- тиричное, 'i' и 'd' - десятичное со знаком. В слу- чае 'x' используются строчные цифры, в случае 'X' - заглавные. Если не специфицирована точность, используется умолчание 1. Если реально выводится меньше цифр, чем определено точностью, вывод до- полняется лидирующими пробелами. Если аргумент и точность равны 0, ничего не печатаются. c Младший значащий байт целого аргумента печатается как литера. e,E Аргумент типа double печатается, используя пред- ставление ([-]d.dddddd+-dd). Здесь перед десятичной точкой одна цифра и precision цифр после. Умолчание для precision равно 6. Если precision 0, десятичная точка не печатается. В экспоненте вместо 'e' будет использовано 'E', если задана литера 'E'. В экспо- ненте присутствуют как минимум две цифры. f Аргумент типа double печатается в виде строки [-]dd.dddd. Количество цифр после десятичной точки задается precision, которое по умолчанию равно 6. Если precision 0, дробная часть и десятичная точка не печатаются. g,G Аргумент типа double печатается c помощью формата 'f' или 'e' (или 'E', если задан 'G' формат) в зависимости от величины аргумента. 'e' используется, если экспонента < 3 или экспонента > precision. Precision задает количество значащих цифр; умолча- ние равно 6. Десятичная точка появляется, если предшествует цифре. Замыкающие 0 опускаются. n Аргумент является указателем на целое, в которое записывается количество цифр, напечатанных к этому моменту. Никакие литеры не печатаются и не преобра- зуются. p Аргумент является указателем, значение которого (адрес) печатается в виде segment:offset для даль- него указателя или в виде XXXX для ближнего указа- теля. s Аргумент является указателем на строку. Литеры печа- таются до замыкающего 0, или до исчерпания литер, ко- личество которых задано precision. Умолчание precision равно 32767. Замыкающий 0 не печатается. % Печатается литера '%'.
Использование
#includeint fprintf(FILE *fp,char *format,...); /* ANSI */ int printf(char *format,...); /* ANSI */ int sprintf(char *buffer,char *format,...); /* ANSI */
Возвращаемое значение
Возвращает количество напечатанных литер. Если име- ла место ошибка, возвращаемое значение отрицательно.
Пример
#include#include main() { char * msg="Целыми форматами являются:"; int number=10; double num=345.2356; printf("%s Hex: 0%x, Decimal:%d, Octal: %o\n", msg, number, number, number); printf("\n Точность плавающей точки для PI: %.2f, %.4f, %.8f\n", PI,PI,PI); printf("\n %.4f Экспоненциальный формат : %E\n", num,num); }
link
среда, 6 апреля 2011 г.
Ubuntu узнать характеристики оборудования
Есть хорошая команда которая выводит характеристики обородования компютера-lshw.Введите в терминале;
sudo lshw
Можна используя следующую команду сохранить в виде HTML документа данные о своей системе;
sudo lshw -html > your-file-name.html
Если нужно данные о каком то конкретном устройстве добавляем -C и имя устройства.
link
sudo lshw
Можна используя следующую команду сохранить в виде HTML документа данные о своей системе;
sudo lshw -html > your-file-name.html
Если нужно данные о каком то конкретном устройстве добавляем -C и имя устройства.
link
пятница, 1 апреля 2011 г.
PHP Оптимизация кода
- Если метод может быть статическим, сделайте его статическим.
- echo быстрее, чем print.
- Передавайте в echo несколько параметров, вместо использования конкатенацию строк.
- Устанавливайте максимальное количество повторений ваших циклов for до цикла, а не во время его выполнения.
- Удаляйте свои переменные для освобождения памяти, особенно если это большие массивы.
- Остерегайтесь волшебных методов, таких как __set, __get, __autoload.
- require_once дорого обходится.
- Указывайте полные пути в командах include/require, поиск файла будет идти быстрее.
- Если вам необходимо определить время, когда скрипт был запущен, лучше используйте $_SERVER[’REQUEST_TIME’] вместо time().
- Старайтесь применять strncasecmp, strpbrk и stripos вместо регулярных выражений.
- str_replace быстрее, чем preg_replace, но strtr быстрее, чем str_replace.
- Если функции замены строк, может принимать в качестве аргументов как массивы, так и одиночные символы, и если ваш список аргументов не слишком длинный, подумайте над тем, чтобы записать несколько одинаковых выражений замены, проходя один символ за раз, вместо одной строки кода, которая принимает массив поиска и замены
- Лучше использовать конструкции else if, чем несколько конструкций if.
- Подавление кодов ошибок при использовании @ работает очень медленно.
- Используйте модуль Apache mod_deflate.
- Прерывайте свои соединения с БД, когда закончите работать с ними.
- $row["id"] в семь раз быстрее, чем $row[id].
- Сообщения об ошибках дорого стоят
- Не используйте функции внутри условия цикла for, например как здесь: for ($x=0; $x < count($array); $x). Здесь функция count() будет вызываться при каждом проходе цикла.
- Инкремент локальной переменной в методе - самый быстрый. Почти также работает инкремент локальной переменной в функции.
- Инкремент глобальной переменной в 2 раза медленее, чем локальной.
- Инкремент свойства объекта (т.е. $this->prop++) в 3 раза медленнее, чем локальной переменной.
- Инкремент неопределённой переменной в 9-10 раз медленнее, чем заранее инициализированной.
- Объявление глобальной переменной, без использования её в функции, также замедляет работу (примерно на ту же величину, что и инкремент локальной переменной). Вероятно, PHP выполняет проверку на существование этой переменной.
- Скорость вызовов метода, не зависит от количества методов в классе. Я добавил 10 методов в тестовый класс (до и после тестового метода) и производительность не изменилась.
- Методы в производных классах работают быстрее, чем они же, определённые в базовом классе.
- Вызов функции с одним параметром и пустым телом функции в среднем равняется 7-8 инкрементам локальной переменной ($localvar++). Вызов похожего метода - примерно равен 15 инкрементам.
- Ваши строки, определённые при помощи апострофа, а не двойной кавычки, будут интерпретироваться чуть быстрее, т.к. PHP ищет переменные внутри текста в двойных кавычках. Конечно, вы можете использовать это только тогда, когда в вашей строке нет переменных.
- Строки, разделённые запятыми, выводятся быстрее, чем строки, разделённые точкой. Примечание: это работает только с функцией echo, которая может принимать несколько строк в качестве аргументов.
- PHP-скрипты будут обрабатываться, как минимум, в 2-10 раз медленнее, чем статические HTML-страницы. Попробуйте использовать больше статических HTML-страниц и меньше скриптов.
- Ваши PHP-скрипты компилируются каждый раз, если скрипты они не кэшируются. Кэширование обычно увеличивает производительность на 25-100% за счёт экономии времени на компиляцию.
- Кэшируйте, насколько это возможно. Используйте memcached — это высокопроизводительная система кэширования объектов в памяти, которая повышает скорость веб-приложений за счёт уменьшения времени загрузки БД. Кэшированный микрокод полезен тем, что позволяет вашему скрипту не перекомпилироваться заново для каждого запроса.
- При работе со строками, для определения длины строки, вы, разумеется, захотите использовать функцию strlen(). Эта функция работает очень быстро, ведь она не выполняет каких-либо вычислений, а лишь возвращает уже известную длину строки, доступную в zval-структуре (внутренняя структура C, используемая при работе с переменными в PHP). Однако потому, что strlen() — функция, она будет работать медленно за счёт вызова некоторых операций, таких как приведение строки в нижний регистр и поиска в хэш-таблице, только после которых будут выполнены основные действия функции. В некоторых случаях вы сможете ускорить свой код за счёт использования хитрости с isset(). Было: if (strlen($foo) < 5) { echo "Foo is too short"; }
Стало: if (!isset($foo{5})) { echo "Foo is too short"; }
Вызов isset() быстрее, чем strlen() потому, что isset() - не функция, а языковая конструкция. За счёт этого isset() не имеет практически никаких накладных расходов на определение длины строки.
- Инкремент или декремент переменной при помощи $i++ происходит немного медленнее, чем ++$i. Это особая специфика PHP, и не нужно таким образом модифицировать свой C и Java-код думая, что он будет работать быстрее, этого не произойдёт. ++$i будет быстрее в PHP потому, что вместо четырёх команд, как в случае с $i++, вам понадобится только три. Пост-инкремент обычно используется при создании временных переменных, которые затем увеличиваются. В то время, как пре-инкремент увеличивает значение оригинальной переменной. Это один из вариантов оптимизации PHP-кода в байт-код утилитой Zend Optimizer. Тем не менее, это хорошая идея, поскольку не все байткод-оптимизаторы оптимизируют это, также остаётся немало скриптов, работающих без оптимизации.
- Не всё должно быть написано с использованием ООП. Часто это излишне, поскольку методы и объекты занимают много памяти.
- Не определяйте каждую структуру данных в виде класса - массивы бывают намного полезнее.
- Не слишком разбивайте методы. Думайте, что вы действительно будете повторно использовать.
- Вы всегда можете разбить код на методы позже, если возникнет такая необходимость.
- Используйте сколько угодно предопределённых функций.
- Если в вашем коде есть функции, работающие очень долго, может стоит их переписать на C в виде расширения?
- Профилируйте свой код. Профилирование покажет вам, сколько времени выполняются части вашего кода.
- mod_gzip — модуль Apache, который позволяет сжимать ваши данные на лету и может существенно уменьшить объем передаваемых клиенту данных.
Curl GET-запросы
- function qwe($qerpay)
- {
- $chp = curl_init("http://xxx/?$qerpay";
- curl_setopt($chp, CURLOPT_HEADER, 0);
- curl_setopt($chp, CURLOPT_RETURNTRANSFER,1);
- curl_setopt($chp, CURLOPT_SSL_VERIFYPEER,0);
- $resultp=curl_exec($chp);
- curl_close($chp);
- $pp = xml_parser_create();
- xml_parse_into_struct($pp,$resultp,$valsp,$indexp);
- xml_parser_free($pp);
- return $valsp['1']['value']; }
PHP Ограничение на размер закачиваемого файла
По умолчанию в PHP стоит ограничение на загрузку файлов не больше 2 Мб. Обычно этого хватает но бывают случаи что необходимо загрузить большие объемы и для этого потребуется увеличить лимиты на загрузку. Для этого нужно сделать небольшие изменения в /etc/php5/cli/php.ini.
Пропишите (измените, если такие уже присутствуют) вот такие строки:
Если у вас нет прав доступа к файлу php.ini попробуйте прописать эти параметры в файле .htaccess который должен находится в корне вашего сайта:
В данных примерах мы поставили ограничение на загрузку файла максимальным размером в 10Мб и отправку POST данных с максимальным размером в 12Мб.
link
Пропишите (измените, если такие уже присутствуют) вот такие строки:
1 2 | upload_max_filesize = 10М post_max_size = 12М |
1 2 | php_value upload_max_filesize 10M php_value post_max_size 12M |
link
Подписаться на:
Сообщения (Atom)