При написании списка с использованием указателей на Си возникла проблема. Суть такова=) Каждый элемент списка содержит свое значение и указатель на следующий элемент. Список это просто указатель на первый элемент. Вот код с комментариями. Проблема - если я создаю список в ручную, то есть указатель каждого элемента направляю на другой элемент все ок. Но я попробовал автоматизировать этот процесс функцией insert. Эта функция добавляет в конец списка новый элемент. После ее использования первый элемент это последний добавленный, а указатель по видимому указывает непонятно куда, хотя в insert любому указателю нового элемента перед добавлением его в список присваивается NULL. Вот код программы с комментариями. Заранее спасибо!!!=)
#include <stdio.h>
#include <conio.h>
//Структура элемента списка
struct element {
int content; //содержимое элемента
struct element *next; //указатель на следующий элемент
};
//Структура списка
struct list {
struct element *root; //указатель на первый элемент
};
//Функция проверяет длину списка
void testLength(struct list L) {
struct element *position;
position = L.root; //с самого начала позиция равна первому элементу списка
int i=0;
printf("Spisoc > ");
while (position != NULL) {
//пока позиция не равна NULL i++
//и перемещаем позицию на следующий элемент
i++;
printf("[%d] ", position->content);
position = position->next;
if (i==10) {break;} //добавлено, чтобы остановить цикл если он не остановиться сам
}
printf("\n dlinna > %d\n\n", i);
}
//функция возвращает указатель на последний элемент списка
struct element* END(struct list *L) {
struct element *position;
position = L->root;
while (position->next != NULL) {
//пока указатель на следующую позицию не равен NULL
//перемещаем позицию на следующий элемент
position = position->next;
}
return position;
}
//Функция вставляет элемент с значением Х в конец списка
void insert(int x, struct list *L) {
//создаем новый элемент
struct element e;
e.content = x;
e.next = NULL;
//если список пуст то элемент ставим в корень
//иначе находим последний элемент и его указатель
//перенаправляем в новый элемент
if (L->root == NULL) {
L->root = &e;
} else {
struct element *position;
position = END(L);
position->next = &e;
}
}
int main(void) {
struct list L1; //создаем список
L1.root = NULL;
testLength(L1); //длинна = 0
//создаем 3 элемента
struct element x1,x2,x3;
x1.content = 111;
x2.content = 222;
x3.content = 333;
//в ручную создаем список
x3.next = NULL;
x2.next = &x3;
x1.next = &x2;
L1.root = &x1;
//проверяем работает ли END
struct element x4;
x4.content = 444;
x4.next = NULL;
struct element *q; //указатель на конец списка
q = END(&L1);
q->next = &x4;
testLength(L1); //длинна 4, значит END работает правильно
//Обнуляем список
L1.root = NULL;
//и создаем его используя insert
insert(111, &L1);
insert(222, &L1);
insert(333, &L1);
insert(444, &L1);
printf("%d\n", L1.root->content); //должен выдавать содержимое первого элемента, то есть 111, выдает 444
//если написать testLength(L1);
//то на экране начнет выводиться последовательность от 1 до бесконечности
getch();
return 1;
}
Другие языки программирования и технологии
Список с использованием указателей на Си
Достаточно одной структуры!
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <locale.h>
#include <windows.h>
struct mylist
{
int num;
unsigned char * word;
mylist * next;
};
struct mylist * start(struct mylist *);
struct mylist * show(struct mylist *);
void clean(struct mylist *);
void menu();
void main()
{
menu();
}
void menu()
{
struct mylist * beg = NULL;
char k;
do
{
system("cls");
setlocale(LC_CTYPE, "Russian_Russia.1251");
printf("\n\n\t\t\t 1: Добавить в список");
printf("\n\t\t\t 2: Просмотреть список");
printf("\n\n\tДля удаления списка и выхода из прогрммы нажмите любую клавишу... ");
k = getch();
printf("\n\n\n ");
switch (k)
{
case 49: beg = start(beg); break;
case 50: beg = show(beg); break;
default: clean(beg);
}
}
while (1);
}
struct mylist * start(struct mylist * beg)
{
struct mylist * p = (struct mylist *) malloc(sizeof(mylist));
p -> word = (unsigned char *) malloc(16 * sizeof(char));
if (beg == NULL)
{
printf("Введите число: ");
scanf("%d", &p->num);
printf(" Введите слово: ");
scanf("%s", p->word);
p->next = NULL;
beg = p;
}
else
{
struct mylist * r = (struct mylist *) malloc(sizeof(mylist));
r = beg;
while (r->next != NULL) r = r->next;
printf("Введите число: ");
scanf("%d", &p->num);
printf(" Введите слово: ");
setlocale(LC_CTYPE, "English_United States.866");
scanf("%s", p->word);
r->next = p;
p->next = NULL;
}
system("cls");
return beg;
}
struct mylist * show(struct mylist * beg)
{
if (beg == NULL)
{
printf("\a Список не содержит элементов! ");
Sleep(1500);
return beg;
}
struct mylist * p = beg;
while (p != NULL)
{
setlocale(LC_CTYPE, "English_United States.866");
printf("\n %d\t%s", p->num, p->word);
p = p->next;
}
_getch();
return beg;
}
void clean(struct mylist * beg)
{
struct mylist * p = beg;
while (p != NULL)
{
beg = p->next;
free(p->word);
free(p);
p = beg;
}
beg = NULL;
printf("\a\n Список удалён! ");
Sleep(1500);
exit(0);
}
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <locale.h>
#include <windows.h>
struct mylist
{
int num;
unsigned char * word;
mylist * next;
};
struct mylist * start(struct mylist *);
struct mylist * show(struct mylist *);
void clean(struct mylist *);
void menu();
void main()
{
menu();
}
void menu()
{
struct mylist * beg = NULL;
char k;
do
{
system("cls");
setlocale(LC_CTYPE, "Russian_Russia.1251");
printf("\n\n\t\t\t 1: Добавить в список");
printf("\n\t\t\t 2: Просмотреть список");
printf("\n\n\tДля удаления списка и выхода из прогрммы нажмите любую клавишу... ");
k = getch();
printf("\n\n\n ");
switch (k)
{
case 49: beg = start(beg); break;
case 50: beg = show(beg); break;
default: clean(beg);
}
}
while (1);
}
struct mylist * start(struct mylist * beg)
{
struct mylist * p = (struct mylist *) malloc(sizeof(mylist));
p -> word = (unsigned char *) malloc(16 * sizeof(char));
if (beg == NULL)
{
printf("Введите число: ");
scanf("%d", &p->num);
printf(" Введите слово: ");
scanf("%s", p->word);
p->next = NULL;
beg = p;
}
else
{
struct mylist * r = (struct mylist *) malloc(sizeof(mylist));
r = beg;
while (r->next != NULL) r = r->next;
printf("Введите число: ");
scanf("%d", &p->num);
printf(" Введите слово: ");
setlocale(LC_CTYPE, "English_United States.866");
scanf("%s", p->word);
r->next = p;
p->next = NULL;
}
system("cls");
return beg;
}
struct mylist * show(struct mylist * beg)
{
if (beg == NULL)
{
printf("\a Список не содержит элементов! ");
Sleep(1500);
return beg;
}
struct mylist * p = beg;
while (p != NULL)
{
setlocale(LC_CTYPE, "English_United States.866");
printf("\n %d\t%s", p->num, p->word);
p = p->next;
}
_getch();
return beg;
}
void clean(struct mylist * beg)
{
struct mylist * p = beg;
while (p != NULL)
{
beg = p->next;
free(p->word);
free(p);
p = beg;
}
beg = NULL;
printf("\a\n Список удалён! ");
Sleep(1500);
exit(0);
}
в функции insert создается автоматическая переменная struct element e;
Она создается на стеке, поэтому при выходе из функции - уничтожается, а ее область памяти может быть использована как угодно.
В результате стирается заголовок списка.
Нужно создавать в куче через вызов malloc:
struct element* e;
e=(struct element*) malloc(sizeof(*e));
и дальше использовать этот указатель
Она создается на стеке, поэтому при выходе из функции - уничтожается, а ее область памяти может быть использована как угодно.
В результате стирается заголовок списка.
Нужно создавать в куче через вызов malloc:
struct element* e;
e=(struct element*) malloc(sizeof(*e));
и дальше использовать этот указатель
void insert(int x, struct list *L) {
//создаем новый элемент
struct element e;
e - локальная переменная, при выходе из функции она умрет. Раз уж пишете на си, то нужно malloc
struct element * e = (struct element *) malloc(sizeof(struct element));
//создаем новый элемент
struct element e;
e - локальная переменная, при выходе из функции она умрет. Раз уж пишете на си, то нужно malloc
struct element * e = (struct element *) malloc(sizeof(struct element));
Похожие вопросы
- Указатель в Си
- Объясните пожалуйста на бытовом языке, что такое указатель в СИ, приведите бытовой пример, описывающий эту операцию?
- C++. Указатели. Связный список. Как добавить элемент в конец списка? Вопрос для разбирающихся
- Указатели в языке Си
- Программирование на языке СИ с использованием подпрограммы-функции
- сильно ли си шарп отличается от си. а то очень охота си изучить, но там какита указатели и какита >
- Си. Указатели и массивы.
- C++: в чем принципиальная разница между использованием членов класса и указателей на них?
- Два вопроса про указатели в С++ внутри.
- Вопрос про указатели в С++ внутри