Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 25.04.2009, 18:04   #1
Iggel
 
Регистрация: 25.04.2009
Сообщений: 3
По умолчанию [C] массивы, указатели, двойные указатели.

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

У меня не ладятится несколько вещей, попробую объяснить как думаю, а вы подсобите .

Код:
// указатель на сорс
void my(int *source)
{
	*source = 8; // меняем на 8
}  

int main(int argc, char *argv[])
{
	int src = 7; // переменная
	int *srcp;   // пустой указатель
	srcp = &src; // в указателе теперь адрес переменной

	printf("src = %d\n", src);	
	my(srcp);
	printf("src2 = %d\n", src);
}
Вывод:
src = 7
src2 = 8
Логично.

Если пишем
char c[10];
char *pc = c; // pc показывает на первый элемент в с.

Код:
// сорс все еще указатель, на этот раз на первые элемент в массиве.
void my_3(char *source)
{
	printf("------ my3 ------\n");
	while(*source != '\0')
	{
		printf("%c", *source);
		*source = 'k'; // меняем все буквы на к
		source++;
	}
}  

int main(int argc, char *argv[])
{
	char my_char[] = "Tedd2";
	
	printf("my_int = %s\n", my_char);	// пишем до
	my_3(my_char);  // 
	printf("\nmy_int2 = %s\n", my_char); // пишем после
	
  printf("\n");
  system("PAUSE");	
  return 0;
}
Вывод:

my_int = Tedd2
------ my3 ------
Tedd2
my_int2 = kkkkk

Тоже в общем-то логично. Идем дальше.
На этот раз создаем массив через указатель. Задата та же, изменить все буквы на к.

char *my = "Tedd"; // my показыват опять же на первую букву в массике, K. То есть содержит ее адрес в памяти.
printf("my_int = %c\n", *my); // выдает T

Код:
void my_2(char *source)
{
	printf("------ my2 ------\n");
	while(*source != '\0')
	{
		printf("%c", *source);
		*source = 'k';
		source++;
	}
} 

int main(int argc, char *argv[])
{
	char *my = "Tedd";

	printf("my_int = %c\n", *my);	
	my_2(my);
	printf("\nmy_int2 = %s\n", my);
	
  printf("\n");
  system("PAUSE");	
  return 0;
}
На этот раз вылетает с ошибкой после:

my_int = Tedd
------ my2 ------
T

Вылетает на строчке
*source = 'k';
Если ее откомментировать, то Tedd пишется нормально. Другими словами *source содержит элемент массива но изменить его не дает.
Почему?
Iggel вне форума Ответить с цитированием
Старый 25.04.2009, 18:16   #2
ISergeyN
Maniac
Форумчанин
 
Аватар для ISergeyN
 
Регистрация: 03.01.2009
Сообщений: 450
По умолчанию

Код:
char *my = "Tedd";
это константа и по этому не дает изменять вам массив.
Стандартные библиотеки разработаны с учетом многолетнего опыта лучших программистов и они не больны "детскими болезнями крутизны в программизме"....
ISergeyN вне форума Ответить с цитированием
Старый 25.04.2009, 18:39   #3
Iggel
 
Регистрация: 25.04.2009
Сообщений: 3
По умолчанию

Константа в мэйне или становится когда проходит в функцию?
Я так понимаю, что тогда надо брать двойной указатель?
Iggel вне форума Ответить с цитированием
Старый 25.04.2009, 18:45   #4
ISergeyN
Maniac
Форумчанин
 
Аватар для ISergeyN
 
Регистрация: 03.01.2009
Сообщений: 450
По умолчанию

Цитата:
Константа в мэйне или становится когда проходит в функцию?
Всегда константа.
нужно так
Код:
	char *my = new char[7];
	strcpy(my,"string");

	printf("my_int = %c\n", *my);	
	my_2(my);
	printf("\nmy_int2 = %s\n", my);

	printf("\n");
	system("PAUSE");	
	delete[] my;
Стандартные библиотеки разработаны с учетом многолетнего опыта лучших программистов и они не больны "детскими болезнями крутизны в программизме"....
ISergeyN вне форума Ответить с цитированием
Старый 25.04.2009, 19:11   #5
still_alive
Great Code Monkey
Форумчанин
 
Аватар для still_alive
 
Регистрация: 09.08.2007
Сообщений: 533
По умолчанию

Iggel
Когда вы пишете char my_char[] = "Tedd2", вы объявляете в стеке массив, в который автоматом заносятся копии символов. Поэтому массив изменять можно.
Когда вы пишете char *my_char = "Tedd2", вы объявляете указатель, который содержит адрес строки Tedd2 в неизменяемой статической области памяти. Поэтому данные по этому адресу менять нельзя.
still_alive вне форума Ответить с цитированием
Старый 05.05.2009, 12:39   #6
Iggel
 
Регистрация: 25.04.2009
Сообщений: 3
По умолчанию

ISergeyN, still_alive
Спасибо Когда прочитал долго смеялся.

Собственно еще вопрос:
Код:
// скопировать из source в out2. Создаем временный указатель, копируем в него, потом меняем адрес out2 на адрес нового указателя.
void my_2(char *source, char **out2)
{
	char *out = (char*)malloc (6*sizeof(char));   // создаем временную переменную
	if (out == NULL)
		printf("TMP ERR\n");   // создать не удалось.
	printf("------ my2 ------\n");
	while(*source != '\0')
	{
		*out = *source;   // копируем символ из одной переменной в другую.
		printf("%c - %c\n", *out, *source);
		
                //  увеличиваем адрес, переходим на след. символ.
		out++;
		source++;
	}
	//strcpy(out, "Banderlog"); // а вот с этим почему-то работает.
	*out = '\0';	// добавить конец строки 
	printf("tmp %s, size: %d\n", out, sizeof(out)); // пишем что получилось и резмер получившегося.
	*out2 = out; // меняем адрес на новый.
}


int main(int argc, char *argv[])
{
	char *out = NULL;
	char *my = "Tedd";
	
	my_2(my, &out);
	printf("\nout = %s\n", out);
	
  printf("\n");
  system("PAUSE");	
  return 0;
}
Что конкретно происходит я не понимаю.
Printf пишет пустую строку без ничего размером 4 (Tedd), хотя туда вроде копируются символы. Потом вылетаем с ошибкой.

Но если делать так:
strcpy(out, "Banderlog"); // а вот с этим почему-то работает.
//*out = '\0'; // добавить конец строки
То printf пишет бандерлога, но размер все равно 4. На этот раз ничего не вылетает и бандерлог виден даже вне функции.
Iggel вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Указатели и массивы. (С++) Eddie Помощь студентам 8 24.04.2009 19:48
Задачка для Бонард Си... тема: указатели и массивы... Катюшенька Помощь студентам 2 26.01.2009 22:18
Указатели и динамические массивы. Airou Общие вопросы C/C++ 5 16.01.2009 19:05
С++.Указатели и массивы Wia Помощь студентам 1 15.12.2008 18:29
Задачи на массивы и указатели в СИ D@rk_Spirit Общие вопросы C/C++ 3 29.12.2007 08:01