суббота, 20 июня 2009 г.
Информация по изменениям...
Всю информацию по изменениям в блогах по программированию на различных языках, о добавлении новых презентаций, о начале новых курсов можно узнать через twitter: AlexeiBo
четверг, 7 мая 2009 г.
Презентации
Хотел бы напомнить, что презентации по темам, связанным с языками С и С++ и не только, доступны на ресурсе:
SlideShare
SlideShare
Продолжение работы со списками
Рассмотрим работу с одно связанным списком, но предположим, что в списке каждая предыдущая структура хранит указатель на последующую. В этом случае, как я упоминал ранее в предыдущем посте, надо хранить указатель на первую структуру в списке. Если мы потеряем первую структуру, то потеряем и элементы списка. А почему? Она - одно связанная, указатель - с предыдущей на последующую, а, следовательно, мы можем двигаться только от первой к последней структуре в списке. Иначе не получится! ;)
А теперь код. Он похож на предыдущей, только вместо pLast и prev используем pFirst и next:
А теперь код. Он похож на предыдущей, только вместо pLast и prev используем pFirst и next:
typedef struct S2{int a; int b; S2* next;} S2_t;
// одно связанный список
S2_t *p2=0, *pLast2=0, *pFirst=0;
//построение списка
for(int i=0;i<10;++i)
{
p2=(S2_t *)malloc(sizeof(S2_t));
memset(p2,0,sizeof(S2_t));
p2->a=i;
p2->b=i+10;
if(pLast2)
pLast2->next=p2;
else
pFirst=p2;
pLast2=p2;
}
//работа со списком
p2=pFirst;
while(p2){
printf("a: %d b: %d\n", p2->a,p2->b);
p2=p2->next;
}
//Удаляем четные элементы
p2=pFirst;
S2_t* p22=pFirst;
while(p2){
if(!(p2->a&1)){
if(p2==pFirst){
p22=p2->next;
pFirst=p22;
free(p2);
p2=p22;
}else{
p22->next=p2->next;
free(p2);
p2=p22->next;
}
}else{
p22=p2;
p2=p2->next;
}
}
printf("After removing:\n");
p2=pFirst;
while(p2){
printf("a: %d b: %d\n", p2->a,p2->b);
p2=p2->next;
}
//удаление списка
p2=pFirst;
while(p2){
pFirst=p2->next;
free(p2);
p2=pFirst;
}
Работа с динамическими списками
Посмотрим как работают динамические списки. Из чего они состоят? Из структур, в каждой из которой есть указатель на предыдущую либо последующую. Это верно для одно связанных списков. У дву связанных есть указатель на предыдущую и последующую одновременно.
Структура может выглядеть так:
- имеет указатель на предыдущую
- имеет указатель на последующую
Построим для первой структуры список из 10 элементов:
Выведем список на экран:
Удалим из списка структуры, которые содержат первое нулевое поле либо четное:
После работы надо освободить память:
В начале работы со списком я всегда устанавливаю указатель p, с которым работаю, в начало списка.
При работе с одно связанным списком главное хранить указатель на последний элемент списка, если в списке указатели в структурах указывают с последующей на предыдущую структуры.
И надо хранить указатель на первую структуру в списке, если предыдущая структура хранит указатель на последующую.
В следующем посте я приведу пример для такой структуры.
Структура может выглядеть так:
typedef struct S1{int a; int b; S1* prev;} S1_t;
- имеет указатель на предыдущую
typedef struct S2{int a; int b; S2* next;} S2_t;
- имеет указатель на последующую
Построим для первой структуры список из 10 элементов:
printf("first:\n");
// односвязанный список
S1_t *p1=0, *pLast=0;
//построение списка
for(int i=0;i<10;++i)
{
p1=(S1_t *)malloc(sizeof(S1_t));
memset(p1,0,sizeof(S1_t));
p1->a=i;
p1->b=i+10;
if(pLast)
p1->prev=pLast;
pLast=p1;
}
Выведем список на экран:
p1=pLast;
while(p1){
printf("a: %d b: %d\n", p1->a,p1->b);
p1=p1->prev;
}
Удалим из списка структуры, которые содержат первое нулевое поле либо четное:
p1=pLast;
S1_t* p11=pLast;
while(p1){
if(!(p1->a&1)){
if(p1==pLast){
p11=p1->prev;
pLast=p11;
free(p1);
p1=p11;
}else{
p11->prev=p1->prev;
free(p1);
p1=p11->prev;
}
}else{
p11=p1;
p1=p1->prev;
}
}
После работы надо освободить память:
p1=pLast;
while(p1){
pLast=p1->prev;
free(p1);
p1=pLast;
}
В начале работы со списком я всегда устанавливаю указатель p, с которым работаю, в начало списка.
При работе с одно связанным списком главное хранить указатель на последний элемент списка, если в списке указатели в структурах указывают с последующей на предыдущую структуры.
И надо хранить указатель на первую структуру в списке, если предыдущая структура хранит указатель на последующую.
В следующем посте я приведу пример для такой структуры.
понедельник, 17 ноября 2008 г.
__gnu_cxx и __verbose_terminate_handler
Отвлечемся от std. Рассмотрим пространство имен __gnu_cxx, в котором объявлен __verbose_terminate_handler, позволяющий получить больше информации о возникающей исключительной ситуации. Замечу, что это все тот же заголовочный файл exception.
Рассмотрим следующий код:
int main (int argc, char * const argv[]) {
std::cout << "Hello, World!\n";
std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
int k=120;
if(k>100)
throw std::exception();
else
throw k;
for(int i=k;i<1000;++i)
std::cout<<".";
return 0;
}
На выходе получаем следующее:
[Session started at 2008-11-17 23:42:53 +0300.]
Hello, World!
terminate called after throwing an instance of 'std::exception'
what(): St9exception
Как видно из примера, при возникновении исключительной ситуации выводится дополнительная информация о ней, что в некоторых случаях может быть полезным.
Рассмотрим следующий код:
int main (int argc, char * const argv[]) {
std::cout << "Hello, World!\n";
std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
int k=120;
if(k>100)
throw std::exception();
else
throw k;
for(int i=k;i<1000;++i)
std::cout<<".";
return 0;
}
На выходе получаем следующее:
[Session started at 2008-11-17 23:42:53 +0300.]
Hello, World!
terminate called after throwing an instance of 'std::exception'
what(): St9exception
Как видно из примера, при возникновении исключительной ситуации выводится дополнительная информация о ней, что в некоторых случаях может быть полезным.
Использование set_terminate
Решил немного написать по поводу set_terminate.
Функция set_terminate объявлена в заголовочном файле exception. Она имеет следующий вид:
terminate_handler set_terminate(terminate_handler) throw().
В качестве параметра функция берет указатель на функцию, которая будет вызвана в случае терминирования программы.
Данный указатель на функцию имеет следующий вид:
void (* pF)(void).
Если мы через функцию set_terminate устанавливаем новый обработчик, то она вернет нам старый, если ранее такой существовал для данной ситуации.
Возникает вопрос: а зачем нужно использовать set_terminate? В ответ можно сказать только следующее, что при ошибке в программе, которая ведет к терминированию этой программы, может возникнуть необходимость сохранить данные, закрыть файлы, записать в лог информацию о причинах ошибки и т.д.
В заключении привожу пример использования:
#include <iostream>
#include <exception>
void func1()
{
std::cout<<"The end"<<std::endl;
}
int main (int argc, char * const argv[]) {
std::cout<< "Hello, World!\n";
std::set_terminate(func1);
throw std::exception();
return 0;
}
В результате работы программы получаем следующее:
[Session started at 2008-11-17 23:10:04 +0300.]
Hello, World!
The end
Функция set_terminate объявлена в заголовочном файле exception. Она имеет следующий вид:
terminate_handler set_terminate(terminate_handler) throw().
В качестве параметра функция берет указатель на функцию, которая будет вызвана в случае терминирования программы.
Данный указатель на функцию имеет следующий вид:
void (* pF)(void).
Если мы через функцию set_terminate устанавливаем новый обработчик, то она вернет нам старый, если ранее такой существовал для данной ситуации.
Возникает вопрос: а зачем нужно использовать set_terminate? В ответ можно сказать только следующее, что при ошибке в программе, которая ведет к терминированию этой программы, может возникнуть необходимость сохранить данные, закрыть файлы, записать в лог информацию о причинах ошибки и т.д.
В заключении привожу пример использования:
#include <iostream>
#include <exception>
void func1()
{
std::cout<<"The end"<<std::endl;
}
int main (int argc, char * const argv[]) {
std::cout<< "Hello, World!\n";
std::set_terminate(func1);
throw std::exception();
return 0;
}
В результате работы программы получаем следующее:
[Session started at 2008-11-17 23:10:04 +0300.]
Hello, World!
The end
понедельник, 10 ноября 2008 г.
Книга по С++, которую я прочитал первой
Нашел я и книгу, которую прочитал первой при изучении языка С++. Она мне нравилась простотой и последовательностью изложения. Ее удобно использовать, изучая язык. Мне это в ней и нравилось. В настоящее время я, к сожалению, ее уже не имею в своем распоряжении, чтобы подробнее описать. Причина отсутствия: "подарил школьной библиотеке". Так что в школе, где я учился и работал, стало на одну книгу по С++ больше. "Отличный язык в широкие массы!!!".
А вот и ссылка на книгу:

В. В. Подбельский
Язык Си++
А вот и ссылка на книгу:

В. В. Подбельский
Язык Си++
Подписаться на:
Сообщения (Atom)