powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / передача массива char между функциями
17 сообщений из 17, страница 1 из 1
передача массива char между функциями
    #38042670
MaximuS_G
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем привет!
Пытаюсь заполнить массив char в другой функции, и вернуть его значение в вызывающую функцию - не получается. Такое возможно вообще? Для int все работает четко.
void f1(char *v)
{
v="jh";
}

void f1(int *v)
{
*v=5;
}

void main()
{
char *myString = new char[100];
int *myInt = new int[10];
f1(myString);
f1(myInt);
cout<<myString;
cout<<*myInt;
}
сout<<myString выводит мусор, cout<<*myInt выводит 5.
...
Рейтинг: 0 / 0
передача массива char между функциями
    #38042687
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximuS_G,

Вы в функции копируете указатель на строку в локальную переменную (а аргументы - это локальные переменные), значение которой при выходе из функции теряется.
Вместо этого надо копировать саму строку в переданный массив с помощью strcpy
Код: plaintext
1.
2.
3.
4.
void f1(char *v)
{
  strcpy(v, "jh"); // при этом надо помнить о размере массива и не выйти за границы (контроля нет)
}



А лучше использовать std::string для строк.

PS. Используйте тег SRC для выделения кусков кода в сообщениях.
...
Рейтинг: 0 / 0
передача массива char между функциями
    #38042699
MaximuS_G
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky
Вы в функции копируете указатель на строку в локальную переменную (а аргументы - это локальные переменные), значение которой при выходе из функции теряется.
Вы имеете ввиду, что внутри функции f1 создался новый массив символов "jh", потом указатель на этот массив был скопирован в указатель v, а при выходе из функции созданный массив символов "jh" был удален?
Спасибо! Сейчас попробую с использованием strcpy.
PS. Используйте тег SRC для выделения кусков кода в сообщениях.
Всегда использую, просто иногда забываю, а редактировать созданный пост нельзя :)
...
Рейтинг: 0 / 0
передача массива char между функциями
    #38042721
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximuS_GВы в функции копируете указатель на строку в локальную переменную (а аргументы - это локальные переменные), значение которой при выходе из функции теряется.
Вы имеете ввиду, что внутри функции f1 создался новый массив символов "jh", потом указатель на этот массив был скопирован в указатель v, а при выходе из функции созданный массив символов "jh" был удален?

Не совсем (см. в соседнем топике про присвоение строки в указатель ). Но суть не в этом, а в том что присвоение в локальную переменную никак не влияет на значение переменной в вызывающем коде.
...
Рейтинг: 0 / 0
передача массива char между функциями
    #38042729
MaximuS_G
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ага, спасибо. Еще один уточняющий вопрос. Если константа вводиться через cin, тогда так делать?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
void f1(char *v)
{
  char *Buff = new char[100];
  cin>>Buff;
  strcpy(v, Buff);
  delete [] Buff;
}
...
Рейтинг: 0 / 0
передача массива char между функциями
    #38042744
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximuS_G,

То что вводится - это по определению не константа.
Так что вводите сразу в переданный указатель.
...
Рейтинг: 0 / 0
передача массива char между функциями
    #38042760
MaximuS_G
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky
Отлично, заработало! :) Спасибо большое!
У меня просто такой кусок был:
Код: plaintext
1.
2.
3.
4.
5.
6.
cout<<"Введите жанр фильма\n";
varGetch = getch();
if (varGetch != 27)
  cin>>genre;
else
  genre = " ";


Переделал последнюю строчку на
Код: plaintext
1.
strcpy(genre, " ");


Так что вводите сразу в переданный указатель.
Правильно ли я понимаю, что указатель должен указывать на динамический массив длинной больше, чем то, что будет введено через cin ?
...
Рейтинг: 0 / 0
передача массива char между функциями
    #38042766
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximuS_GПравильно ли я понимаю, что указатель должен указывать на динамический массив длинной больше, чем то, что будет введено через cin ?
Да.
...
Рейтинг: 0 / 0
передача массива char между функциями
    #38042823
MaximuS_G
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо! Удачи! :)
...
Рейтинг: 0 / 0
передача массива char между функциями
    #38053070
MaximuS_G
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyMaximuS_G,

Вы в функции копируете указатель на строку в локальную переменную (а аргументы - это локальные переменные), значение которой при выходе из функции теряется.
Вместо этого надо копировать саму строку в переданный массив с помощью strcpy
Код: plaintext
1.
2.
3.
4.
void f1(char *v)
{
  strcpy(v, "jh"); // при этом надо помнить о размере массива и не выйти за границы (контроля нет)
}



Кто-то может подсказать, что имелось ввиду в выделенном предложении?
Я могу предположить, что это как-то связанно с объяснением Anatoly Moskovsky .
Anatoly MoskovskyМы можем объявить явно массив char и присвоить ему строку/массив. В этом случае создается копия , которая уже не константа.
Код: plaintext
1.
char s[] = "aaa"; //  массив размером 4 (включая завершающий 0) и скопировали туда строк

у
Заранее спасибо!
...
Рейтинг: 0 / 0
передача массива char между функциями
    #38054104
MaximuS_G
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
up :)
...
Рейтинг: 0 / 0
передача массива char между функциями
    #38054164
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximuS_G,

Первая цитата не имеет отношение ко второй (хотя и там и там - копирование)

Допустим у вас есть функция
Код: plaintext
1.
2.
3.
void f1(char *v)
{
}


или даже чтобы вы не отвлекались на указатель, возмем какой-то другой тип
Код: plaintext
1.
2.
3.
void f1(XXX v)
{
}


Когда вы вызываете f1 и передаете в нее значение:
Код: plaintext
1.
2.
XXX x;
f1(x);


то происходит так называемая передача параметра "по значению".
Она заключается в том что переданное значение x копируется в v .
Т.е. это теперь два отдельных значения хранящихся в разных переменных.
Теперь если функция модифицирует аргумент, то модифицируется копия, а не оригинальная переменная переданная в функцию
Код: plaintext
1.
2.
3.
4.
5.
6.
void f1(XXX v)
{
   v = ...;  // меняется v, но не x
}
XXX x;
f1(x);



Теперь вернемся к указателям.
Вот у вас был первоначально код:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
void f1(char *v)
{
	v="jh";
}
void main()
{
	char *myString = new char[100];
	f1(myString);
}


Здесь вы передаете указатель myString по значению в функцию. А внутри функции присваиваете в копию указателя, а сам myString при этом остается неизменным. Т.е. это явно не то что вы хотели получить.

Но на самом деле вам и не надо было менять сам указатель, вам надо было поменять строку, на которую он указывает.
И тут мы уже спокойно можем работать с копией указателя, т.к. копия указывает на тот же буфер что и исходный указатель.
Таким образом получаем такой код функции:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
void f1(char *v)
{
	strcpy(v, "jh"); // копируем строку в буфер на который указывает копия указателя
}
void main()
{
	char *myString = new char[100];
	f1(myString);
}



Ну и для полноты картины надо сказать что кроме передачи "по значению", в С++ можно объявлять аргументы для передачи "по ссылке".
Код: plaintext
1.
2.
3.
4.
5.
6.
void f1(XXX& v)
{
   v = ...;  // меняется x, а v - это просто ссылка на x (синоним)
}
XXX x;
f1(x);


В С эквивалентный код можно было записать так:
Код: plaintext
1.
2.
3.
4.
5.
6.
void f1(XXX* v)
{
   *v = ...;  // меняется x, т.к. v - это указатель на x
}
XXX x;
f1(&x);


Вы уже встречались с таким кодом когда делали односвязный список:
Код: plaintext
1.
2.
3.
4.
5.
6.
void slstore(struct address *i,
             struct address **last)
{
...
  *last = i;
}


Так вот это был С-шный вариант, а в С++ такой код можно записать так:
Код: plaintext
1.
2.
3.
4.
5.
6.
void slstore(struct address *i,
             struct address *&last)
{
...
   last = i; // здесь last - ссылка на указатель, переданный вторым аргументом
}
...
Рейтинг: 0 / 0
передача массива char между функциями
    #38055679
MaximuS_G
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky
Спасибо огромное за расширенный ответ!
Anatoly Moskovsky
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
void f1(char *v)
{
	v="jh";
}
void main()
{
	char *myString = new char[100];
	f1(myString);
}

Здесь вы передаете указатель myString по значению в функцию. А внутри функции присваиваете в копию указателя, а сам myString при этом остается неизменным. Т.е. это явно не то что вы хотели получить.
Тогда я могу преположить, что в коде ниже в обоих случаях указатель тоже передается по ссылке. Но так как копия указателя, которая создается в функциях f1 и f2 указывает на тот же адрес, что и оригинальный указатели из функции main , выводиться значение 10. Такое предположение верно?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
void f1(int *v)
{
	*v=10;
}

void f2(int *vp)
{
	*vp=10;
}

void main()
{
	int v = 5;
	f1(&v);
	int *vp = new int[1];
	f2(vp);
	cout<<v; // 10
	cout<<*vp; //10
	system("pause");
}


Я считал, или нам так объяснили, что в случае с передачей переменной по указателю, как и по ссылке, копия не создается. Но получается в случае с передачей по указателю создается копия не переменной, а указателя. Так?
Заранее спасибо!
...
Рейтинг: 0 / 0
передача массива char между функциями
    #38055693
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximuS_GТогда я могу преположить, что в коде ниже в обоих случаях указатель тоже передается по ссылке.Нет. Там копируется указатель, можно сказать что он передается по значению.

MaximuS_G Но так как копия указателя, которая создается в функциях f1 и f2 указывает на тот же адрес, что и оригинальный указатели из функции main , выводиться значение 10. Такое предположение верно? Да. Хотя все же там "копии указателей" :)

MaximuS_GЯ считал, или нам так объяснили, что в случае с передачей переменной по указателю, как и по ссылке, копия не создается. Но получается в случае с передачей по указателю создается копия не переменной, а указателя. Так?Да. Указатель это тоже переменная и он подчиняется всем законам обычных переменных. Он копируется при передаче в функцию и на него можно сделать указатель.

Чтобы разобраться с указателями лучше всего нарисуй себе память в виде длинной ленты поделенной на ячейки. Каждая ячейка это один байт. Создаешь переменную или выделяешь память - помечай несколько последовательных ячеек на этой ленте.
А теперь идем по твоей программе и рисуем: Где-то в памяти (не важно где) у тебя лежит переменная int v, пометь ее. Теперь ты заходишь в функцию f1 и у тебя автоматически создается переменная int *v, в ней будет лежать номер первой ячейки от первого v.
Обратно в main(): ты где-то в памяти создаешь переменную int *vp, потом выделяешь еще один кусок памяти и записываешь в vp адрес перевого байта этого куска. Заходишь в f2() и у тебя автоматически создается еще одна переменная int *vp в которую копируется значание из переменной vp принадлежащей main().
...
Рейтинг: 0 / 0
передача массива char между функциями
    #38056044
MaximuS_G
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White Owl
Спасибо большое за комментарии!
White OwlMaximuS_GТогда я могу преположить, что в коде ниже в обоих случаях указатель тоже передается по ссылке.
Нет. Там копируется указатель, можно сказать что он передается по значению.
Тут я ошибся конечно когда писал, я имел ввиду по значению. Что Вы и подтвердили :)
White OwlУказатель это тоже переменная и он подчиняется всем законам обычных переменных. Он копируется при передаче в функцию и на него можно сделать указатель.
Ага, теперь лучше понятен пример с передачей указателя по указателю в односвязных списках.
Тогда у меня появляется вопрос.
Anatoly MoskovskyВот у вас был первоначально код:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
void f1(char *v)
{
	v="jh";
}
void main()
{
	char *myString = new char[100];
	f1(myString);
}


Здесь вы передаете указатель myString по значению в функцию. А внутри функции присваиваете в копию указателя, а сам myString при этом остается неизменным . Т.е. это явно не то что вы хотели получить.
Но ведь здесь копия указателя указывает на тот же самый адрес, что и указатель myString, и значение в ячейках памяти должны остаться?
Как в этом примере:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
void f2(int *vp)
{
	*vp=10; // здесь vp это копия указателя
}

void main()
{
	int *vp = new int[1]; // как и в примере выше выделяется память и создается указатель
	f2(vp);
	cout<<*vp; //но результат все равно 10 
	system("pause");
}


Я думаю здесь конечно вся хитрость в том (и что я не понимаю), что массив присваивается вот так
Код: plaintext
1.
v="jh";
...
Рейтинг: 0 / 0
передача массива char между функциями
    #38056956
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximuS_GЯ думаю здесь конечно вся хитрость в том (и что я не понимаю), что массив присваивается вот так
Код: plaintext
1.
v="jh";

Это не присваивание массива. В С вообще нету такого понятия как присваивание массивов.
Это задание нового значения для указателя.

Вот в этом коде:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
void f1(char *v)  //  A 
{
	v="jh";  //  B 
}
void main()
{
	char *myString = new char[100];
	f1(myString);  //  C 
}

При вызове f1, в строке C , создается копия указателя mystring, и эта копия обозначается как v в строке A . А в строке B , в эту копию записывается новое значение: адрес строки "jh" лежащей в сегменте статических данных. До строки B значение v совпадает со значением myString, после - не совпадают. Но так-как v и myString это разные переменные, то и после выхода из f1() myString продолжает показывать на кусок памяти в сто байт выделенный на куче.
...
Рейтинг: 0 / 0
передача массива char между функциями
    #38057118
MaximuS_G
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо большое, White Owl ! Теперь все понятно!
Удачи! :)
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / передача массива char между функциями
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]