Как передать строку в функцию си
Перейти к содержимому

Как передать строку в функцию си

  • автор:

Как передать строку в функцию си

Скачай курс
в приложении

Перейти в приложение
Открыть мобильную версию сайта

© 2013 — 2023. Stepik

Наши условия использования и конфиденциальности

Get it on Google Play

Public user contributions licensed under cc-wiki license with attribution required

Передача строки в функцию

Просматривая статьи о функциях на разных сайтах для новичков в С++, прихожу к выводу, что, зачастую, в примерах показано, как передавать функциям, в качестве параметров, числовые типы данных ( int , float , double и т.д.). Так появилась идея написать данную статью, где на практике хочу показать, как передать строку (она же — массив символов) в функцию в виде параметра. И просто замечательно, что в С++ таких способов несколько. Вы можете выбрать тот, который вам просто понравится или который больше подойдет для решения поставленной перед вами задачи.

Способы передачи строки в функцию хочу показать на одном примере. Чтобы лучше освоить материал и взять максимум пользы от прочитанного, открывайте свою среду разработки и переписывайте код по мере прочтения. Практика – лучший способ что-то понять и запомнить. Под примером будут расположены подробные комментарии и разъяснения по данному коду.

#include using namespace std; //определяем функции void showText1 (char str[])//функция принимает строку, как массив < cout void showText2 (char *str)//указатель *str будет указывать на адрес первого символа в строке < cout void showText3 (char (&str)[150])// адрес строки из 150-ти символов < cout int main()

Задача всех наших созданных функций – отобразить на экране строки, которые переданы им, как параметры. Пойдем по порядку:

1) первый способ — функция void showText1 (char str[]) принимает строку, как массив — строка 4 . П ри определении функции, в круглых скобках надо вписать тип массива (строки) char , имя строки и квадратные скобки [] . Обратите внимание, что нам не надо указывать размерность массива (количество символов в строке). С помощью символа ‘\0′, который автоматически добавляется в конец любой строки , функция сама найдет последний элемент массива и прекратит вывод элементов на экран.

2) второй способ, передача строки в функцию при помощи указателя, самый распространенный вариант — строка 9. При определении функции, перед именем строки ставим оператор * — void showText2 (char *str) .

3) ну и третий способ, передача в функцию строки по адресу — строка 14. В нашем примере это функция void showText3 (char (&str)[150]) . Тут следует быть внимательным, т.к. необходимо указывать точный размер строки. Без этого компилятор выдаст ошибку (Мы проверяли :)). А так же важно взять в круглые скобки оператор & с именем строки — (&str) . В строке 38 нашего кода, вы можете видеть, что строка char str3[150] содержит явно меньше символов. Остальным, не инициализированным, будет присвоено значение ‘\0’ .

Думаю, строки 23-25 говорят сами за себя и комментировать не стоит. Иногда, так удобно сделать, не объявляя и не определяя строку заранее.

При вызове функций все просто – надо лишь внести название необходимой строки в круглые скобки. Строки 29, 34, 39.

CppStudio.com

Можно ввести строку в круглых скобках при вызове функции:
~~~ ~~~ ~~~ cppstudio.com ~~~ ~~~ ~~~

str1 — передаем, как массив в функцию void showText1 (char str[]);

str2 — передаем, в функцию void showText2 (char *str); используя указатель.

str3 — передаем, в функцию void showText3 (char &str[]);
Тут используем адрес строки (адрес первого элемента символьного массива)

А вот еще один пример, который покажет насколько удобно работать с указателем в функциях. В нем функция примет, в качестве параметра, указатель на строку символов, с помощью указателя пройдет по каждой ячейке памяти строки и изменит числовые символы на знак ~ или на букву O . В результате строка, содержащая числовые символы 1234123412341234 и т.д., с легкостью превратится в “новогоднюю гирлянду”. В этом коде указатель покажет себя, как альтернатива управляющей переменной в цикле while :

#include using namespace std; void changeSymbol(char *str) < while(*str != '\0')//пока значение ячейки не равно символу конца строки < if (*str == '4') *str = 'O'; else *str = '~'; str++;//на каждой итерации цикла, указатель смещается на одну ячейку >> int main() < setlocale(LC_ALL, "rus"); char str[] = ; cout << "Исходная строка: " << str << endl << endl; changeSymbol(str);//передаем исходную строку в функцию cout

Смотрите, как интересно получается: как мы знаем, указатель указывает на адрес первой ячейки памяти строки, т.е. в нашем случае на str[0] . Значит, используя операцию разыменовывания указателя * , мы можем посмотреть, какой символ в этой ячейке хранится и, если надо, заменить его на другой — строки 6, 8, 9. Плюс, мы можем использовать указатель на строку, вместо управляющей переменной в нашем цикле while . Для этого, на каждой итерации цикла, инкрементируем указатель str++ — строка 11. Таким образом, указатель будет указывать уже на очередную ячейку памяти нашей строки. Так будет происходить до тех пор, пока указатель не перейдет на ячейку с символом ‘\0’ . Тут цикл while прекратит работу.

Результат — наша «новогодняя гирлянда» 🙂

CppStudio.com

Исходная строка: 12341234123412341234123

Каким способом передать строку в функцию — определяйтесь сами. Если у вас остались вопросы по теме, задавайте их нам в комментариях к этой статье. Мы вам обязательно ответим и поможем разобраться.

Си: передача предопределённых строк в функцию

Всегда думал, что при предопределении строковой переменной *s = «habr» и s[] = «habr» — практически полные синонимы.

Тогда почему в коде ниже (компилировал в GCC, различные версии, на Linux) работает лишь вариант I, а варианты II и III валятся с Segmentation Fault?

// Вариант I #include void test(char *s) < s[2] = 'X'; puts(s); >int main() < char x[] = "123456"; test(x); return 0; >// Вариант II #include void test(char *s) < s[2] = 'X'; puts(s); >int main() < char *x = "123456"; test(x); return 0; >// Вариант III #include void test(char *s) < s[2] = 'X'; puts(s); >int main()

Возможно, это что-то элементарное для языка, но сам я не разобрался.

  • Вопрос задан более трёх лет назад
  • 6505 просмотров

1 комментарий

Оценить 1 комментарий

Передача строки в функцию в Си

Это код для STM32F030, он компилируется без ошибок, но если залить этот код в микроконтроллер — он даже не запускается. Подскажите, сам код написан правильно?

void print(char * string) < while(*string) < while(!(USART_GetFlagStatus(USART1, USART_FLAG_TXE))); USART_SendData(USART1, *string++); >> int main (void)

Почему всё работает нормально, если вызвать функцию вот так:

char hello[] = ; print(hello); 

Как правильно передать строку в функцию?
Отслеживать
задан 25 сен 2018 в 7:20
61 5 5 бронзовых знаков

С контроллерами дел не имел, но с точки зрения чистого языка — разница в том, что в первом случае вы передаете указатель на литерал, который не изменяем (представляет собой const char* ), а во втором — вполне изменяем. Попробуйте интереса ради объявить print(const char*) . Еще раз — в контроллерах я не смыслю; комментирую только с точки зрения чисто языка как такового.

25 сен 2018 в 7:31

Мне и нужно с точки зрения языка как такового) Хочу понять, это я коряво пишу или особенность микроконтроллера. const пробовал — код ведёт себя точно так же

25 сен 2018 в 7:37

Вы скомпилируйте оба варианта так, чтобы компилятор Вам вывел ассемблерный листинг. И сравните ассемблерные листинги для обоих вариантов. Сразу все станет понятно.

25 сен 2018 в 7:51

Скорее всего во втором варианте строка расположена на стеке и инициализируется константой из секции кода. А в первом варианте строка расположена в секции кода в константах. То есть имеется какая-то проблема с доступом к константам в коде. Транслятор-то какой? GCC или самодельный от фирмы-производителя контроллера? А, вижу. Контроллер ARM так что транслятор скорее всего GCC. Это странно. GCC для ARM хорошо отлажен, там не должно быть таких очевидных косяков.

25 сен 2018 в 7:57

Еще проверьте под тот ли тип ядра ARM у Вас компилируется код. Похоже, что указатель string как-то с ошибкой ползает по константным строкам, но без ошибок ползает по строкам, расположенным в памяти или на стеке.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *