Форум программистов Контакты:
О проблемах с регистрацией, почтой и по другим вопросам пишите сюда - post@programmersforum.ru
По необходимости будем регистрировать вручную. И проверяйте папку спам!
Главная  |  Правила форума  |  Исходники Delphi  |  Основы Delphi  |  Блог программистов  |  Рассылка  |  Повторная активизация e-mail  | 

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

Ответ
 
Опции темы
Старый 25.04.2009, 17:04   #1
Iggel
 
Регистрация: 25.04.2009
Сообщений: 3
Репутация: 10
По умолчанию [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, 17:16   #2
ISergeyN
Maniac
Форумчанин
 
Аватар для ISergeyN
 
Регистрация: 03.01.2009
Адрес: Ukraine, Kremenchuk
Сообщений: 452
Репутация: 197
По умолчанию

Код:

char *my = "Tedd";

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

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

Цитата:
Константа в мэйне или становится когда проходит в функцию?
Всегда константа.
нужно так
Код:

	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, 18:11   #5
still_alive
Great Code Monkey
Участник клуба
 
Аватар для still_alive
 
Регистрация: 09.08.2007
Сообщений: 528
Репутация: 371
По умолчанию

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

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 вне форума   Ответить с цитированием
Ответ


Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Указатели и массивы. (С++) Eddie Помощь студентам 8 24.04.2009 18: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




01:19.


Powered by vBulletin® Version 3.8.8 Beta 2
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.

Forex с Admiral Markets — это надежно


Работа на Forex с 2000 года. Очное и дистанционное обучение. Выгодные условия.
магазин горящих туров


более 1000 горящих предложений ежедневно
Бэбиблог - соц сеть для будущих мам


RusProfile.ru


Справочник российских юридических лиц и организаций.