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

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

  • автор:

Передача элемента символьного массива в функцию с изменением значения

Как мне передать символьный массив mass[30] в функцию, чтобы при вызове функции function() в массиве находилось слово «Something» ?

Отслеживать
10.8k 1 1 золотой знак 19 19 серебряных знаков 34 34 бронзовых знака
задан 5 мая 2020 в 20:44
1 1 1 серебряный знак 6 6 бронзовых знаков
Я ничего не понял.
5 мая 2020 в 20:55
Вам нужно в функцию передать пустой массив так, чтобы после её вызова в нём появилась строка?
5 мая 2020 в 21:00

@КириллМалышев мне необходимо передать в функцию function мой символьный массив mass[30]. Это делается для того, чтобы изменить его содержимое, но если я передам его как есть, изменения не сохранятся, значит надо изменять адрес, но как сделать это с символьным массивом я без понятия

5 мая 2020 в 21:01
@RomanMitasov да, но не факт что этот массив будет пустым, если это имеет значение
5 мая 2020 в 21:02

Массив передаётся в функцию по адресу. Если вы его там измените, то эти изменения и после выхода из функции будут. Только у вас сигнатура функции неправильная, нужно передавать char *a.

5 мая 2020 в 21:02

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

Во-первых, вам надо изменить тип параметра функции:

function (char* a)

или function (char a[])

Потом при вызове функции передавайте массив в неё вот так:

void function(char a[]) < strcpy_s(a, "Something"); >int main ()

Пояснение

Добавление к типу * делает этот тип указателем. Советую просто найти литературу или просто поискать в гугле про «указатели в C++».

Но если вкратце — char a это тип «символ», а char* a это тип «указатель на символ» или «адрес ячейки в памяти, в которой лежит символ».

Когда мы работаем с массивами в Си и C++, мы можем указывать вместо char* char[] . Квадратные скобки семантически говорят программисту, что это не просто указатель, а указатель на начало массива. Со стороны программы запись char* и char[] совершенно одинакова. Проще говоря — это синтаксический сахар для лучшей читаемости программ.

Именно поэтому, когда нужно сделать функцию, которая что-то делает с переменной или массивом снаружи (то есть пришедшем в параметре), надо всегда делать тип параметра этой функции указателем или ссылкой.

Про ссылки расписывать не буду, ищи-читай на просторах интернета.

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

Здесь рассмотрена операция по передаче массивов в качестве аргументов функции, поскольку существуют исключения из стандартного правила передачи по значению.

Когда массив используется в качестве аргумента функции, передается только адрес массива, а не копия всего массива. При вызове функции с именем массива в функцию передается указатель на первый элемент массива. (Надо помнить, что в С имена массивов без индекса — это указатели на первый элемент массива.) Параметр должен иметь тип, совместимый с указателем. Имеется три способа объявления параметра, предназначенного для получения указателя на массив. Во-первых, он может быть объявлен как массив, как показано ниже:

#include
void display(int num[10]);
int main (void) /* вывод чисел */
int t [10], i;
for (i=0; i display(t);
return 0;
>

Хотя параметр num объявляется как целочисленный массив из десяти элементов, С автоматически преобразует его к целочисленному указателю, поскольку не существует параметра, который мог бы на самом деле принять весь массив. Передается только указатель на массив, поэтому должен быть параметр, способный принять его.

Следующий способ состоит в объявлении параметра для указания на безразмерный массив, как показано ниже:

где num объявлен как целочисленный массив неизвестного размера. Поскольку С не предоставляет проверку границ массива, настоящий размер массива не имеет никакого отношения к параметру (но, естественно, не к программе). Данный метод объявления также определяет num как целочисленный указатель.

Последний способ, которым может быть объявлен num, — это наиболее типичный способ, применяемый при написании профессиональных программ, — через указатель, как показано ниже:

Он допустим, поскольку любой указатель может быть индексирован с использованием [], если он является массивом. (На самом деле массивы и указатели очень тесно связаны друг с другом.) Все три метода объявления параметра приводят к одинаковому результату — указателю. С другой стороны, элемент массива используется как аргумент, трактуемый как и другие простые переменные. Например, программа может быть написана без передачи всего массива:

void display(int num)
printf («%d «, num);
>

Как можно видеть, в display() передается параметр типа int. Не имеет значения, что display() вызывается с элементом массива в качестве параметра, поскольку передается только одно значение.

Важно понять, что при использовании массива в качестве аргумента функции происходит передача в функцию его адреса. Это означает, что код внутри функции действует и может изменять настоящее значение массива, используемого при вызове. Например, рассмотрим функцию print_upper(), выводящую строку прописными буквами:

#include
#include
void print_upper(char *string);
int main(void) /* вывод строки в верхнем регистре */
char s[80];
gets (s);
print_upper(s) ;
return 0;
>

void print_upper(char *string)
register int t;
for(t=0; string[t]; ++t)
string[t] = toupper(string[t]);
printf(«%c», string[t]);
>
>

После вызова print upper() происходит изменение содержимого массива s в main(). Если это не нужно, следует переписать программу следующим образом:

# include
#include
void print upper(char *string);
int main(void) /* вывод строки в верхнем регистре */
char s[80];
gets(s);
print_upper(s);
return 0;
>

void print_upper(char *string)
register int t;
for(t=0; string[t]; ++t)
printf («%c», toupper (string[t]));
>

В данной версии содержимое массива s остается неизменным, поскольку значения не меняются.

Классический пример передачи массивов в функции находится в стандартной библиотечной функции gets(). Хотя gets() из библиотеки Borland С++ гораздо сложнее, функция, показанная в данном примере, содержит основную идею работы. Для того, чтобы избежать путаницы и не вызвать стандартную функцию, данная функция называется xgets().

/* простейшая версия стандартной библиотечной функции gets() */

void xgets (char *s)
register char ch;
register int t;
for(t=0; t ch = getche();
switch(ch)
case ‘ \r’:
s[t] = ‘\0’; /* null завершает строку */
return;
case ‘\b’:
if(t>0) t-;
break;
default:
s[t] = ch;
t++;
>
>
s[79] = ‘ \0’;
>

Функция xgets() должна вызываться с указателем на символ. Это может быть имя символьного массива, который по определению является указателем на символ. xgets() организует цикл for от 0 до 79. Таким образом предотвращается ввод больших строк с клавиатуры. Если набирается более 80 символов, функция завершает работу. Поскольку C не имеет проверки границ массива, следует убедиться, что массив, передаваемый в xgets(), может принять, по крайней мере, 80 символов. По мере набора символов на клавиатуре они вводятся в строку. Если набирается забой, счетчик t уменьшится на 1. При нажатии на ввод помещается нулевой символ в конец строки, то есть строка оканчивается. Поскольку массив, используемый при вызове xgets(), модифицируется, после возврата он будет содержать набранные символы.

Массивы и функции в языке Си. Передача указателя на массив

Массивы, также как остальные переменные, можно передавать в функции в качестве аргументов. Рассмотрим такую программу:

#include #include #include #define N 10 void rand_fill(int arr[], int min, int max); int main() { int numbers[N]; rand_fill(numbers, 30, 90); for (int i = 0; i  N; i++) printf("%d ", numbers[i]); printf("\n"); } void rand_fill(int arr[], int min, int max) { srand(time(NULL)); for (int i = 0; i  N; i++) arr[i] = rand() % (max - min + 1) + min; }

В теле функции main объявляется массив, состоящий из 10 элементов. Далее вызывается функция rand_fill() , которой передаются в качестве аргументов имя массива и два целых числа.

Если посмотреть на функцию rand_fill , то можно заметить, что ее первый параметр выглядит немного странно. Функция принимает массив неизвестно какого размера. Если предположить, что массивы передаются по значению, т. е. передаются их копии, то как при компиляции будет вычислен необходимый объем памяти для функции rand_fill , если неизвестно какого размера будет один из ее параметров?

На прошлом уроке мы выяснили, что имя массива — это константный указатель на первый элемент массива; т.е. имя массива содержит адрес. Выходит, что мы передаем в функцию копию адреса, а не копию значения. Как мы уже знаем, передача адреса приводит к возможности изменения локальных переменных в вызывающей функции из вызываемой. Ведь на одну и ту же ячейку памяти могут ссылаться множество переменных, и изменение значения в этой ячейке с помощью одной переменной неминуемо отражается на значениях других переменных.

Описание вида arr[] в параметрах функций говорит о том, что в качестве значения мы получаем указатель на массив, а не обычную (скалярную) переменную типа int , char , float и т.п.

Если в функцию передается только адрес массива, то в теле функции никакого массива не существует, и когда там выполняется выражение типа arr[i] , то на самом деле arr ‒ это не имя массива, а переменная-указатель, к которой прибавляется смещение. Поэтому цикл в функции rand_fill можно переписать на такой:

for (int i = 0; i  N; i++) *arr++ = rand() % (max - min + 1) + min;

В теле цикла результат выражения справа от знака присваивания записывается по адресу, на который указывает arr . За это отвечает выражение *arr . Затем указатель arr начинает указывать на следующую ячейку памяти, т.к. к нему прибавляется единица ( arr++ ). Еще раз: сначала выполняется выражение записи значения по адресу, который содержится в arr ; после чего изменяется адрес, содержащийся в указателе (сдвигается на одну ячейку памяти определенного размера).

Поскольку мы можем изменять arr , это доказывает, что arr — обычный указатель, а не имя массива. Тогда зачем в заголовке функции такой гламур, как arr[] ? Действительно, чаще используют просто переменную-указатель:

void rand_fill(int *arr, int min, int max);

Хотя в таком случае становится не очевидно, что принимает функция ‒ указатель на обычную переменную или все-таки на массив. В любом случае она будет работать.

Часто при передаче в функцию массива туда же через отдельный аргумент передают и количество его элементов. В примере выше N является глобальной константой, поэтому ее значение доступно как из функции main , так и rand_fill . Иначе, можно было бы определить rand_fill так:

void rand_fill(int *arr, int n, int min, int max) { srand(time(NULL)); for (int i = 0; i  n; i++) *arr++ = rand() % (max - min + 1) + min; }

В данном случае параметр n — это количество обрабатываемых элементов массива.

Следует еще раз обратить внимание на то, что при передаче имени массива в функцию, последняя может его изменять. Однако такой эффект не всегда является желательным. Конечно, можно просто не менять значения элементов массива внутри функции, как в данном примере, где вычисляется сумма элементов массива; при этом сами элементы никак не изменяются:

int arr_sum(int *arr) { int s = 0, i; for(i = 0; i  N; i++) { s = s + arr[i]; } return s; }

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

int arr_sum(const int *arr);

В этом случае, любая попытка изменить значение по адресу, содержащемуся в таком константном указателе, будет приводить к ошибке и программист будет знать, что функция пытается изменить массив.

Усложним программу, которая была приведена в начале этого урока:

#include #include #include #define N 10 void rand_fill(int *arr, int min, int max); void arr_inc_dec(int arr[], char sign); void arr_print(int *arr); int main() { int numbers[N], i, minimum, maximum; char ch; printf("Enter minimum & maximum: "); scanf("%d %d", &minimum, &maximum); rand_fill(numbers, minimum, maximum); arr_print(numbers); scanf("%*c"); // избавляемся от \n printf("Enter sign (+, -): "); scanf("%c", &ch); arr_inc_dec(numbers, ch); arr_print(numbers); } void rand_fill(int *arr, int min, int max) { srand(time(NULL)); for (int i = 0; i  N; i++) *arr++ = rand() % (max - min + 1) + min; } void arr_inc_dec(int *arr, char sign) { for (int i = 0; i  N; i++) { if (sign == '+') arr[i]++; else if (sign == '-') arr[i]--; } } void arr_print(int *arr) { printf("The array is: "); for (int i = 0; i  N; i++) printf("%d ", *arr++); printf("\n"); }

Теперь у пользователя запрашивается минимум и максимум, затем создается массив из элементов, значения которых лежат в указанном диапазоне. Массив выводится на экран с помощью функции arr_print() . Далее у пользователя запрашивается знак + или -. Вызывается функция arr_inc_dec() , которая в зависимости от введенного знака увеличивает или уменьшает на единицу значения элементов массива.

В функциях rand_fill и arr_print используется нотация указателей. Причем в теле функций значения указателей меняются: они указывают сначала на первый элемент массива, затем на второй и т.д. В функции arr_inc_dec используется вид обращения к элементам массива. При этом значение указателя не меняется: к arr прибавляется смещение, которое увеличивается на каждой итерации цикла. Ведь на самом деле запись arr[i] означает *(arr+i) .

При использовании нотации обращения к элементам массива программы получаются более ясные, а при использовании записи с помощью указателей они компилируются чуть быстрее. Это связано с тем, что когда компилятор встречает выражение типа arr[i] , он тратит время на преобразование его к виду *(arr+i) .

Напишите программу, в которой из функции main в другую функцию передаются два массива: «заполненный» и «пустой». В теле этой функции элементам «пустого» массива должны присваиваться значения, так или иначе преобразованные из значений элементов «заполненного» массива, который не должен изменяться.

Курс с решением задач:
pdf-версия

Передать массив char, в функцию

Author24 — интернет-сервис помощи студентам

Добрый день, не понемаю как можно в собственную функцию передать массив char. Собственно есть 2 примера, можете подсказать правильные или же нет? Укажите пожалуйста на ошибки. Среда VS2012. Я только просто начал изучать функции.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
//1 #include using namespace std; int Max=5; void input(char v[],int n); void output(char b[],int m); int main(){ char nas[Max]; input(nas,Max);//ввод output(nas,Max);//вывод return 0; } void input(char v[],int n){ for(int i=0;in;i++){ cout<"Введите элементы = "<(i+1); cin>>v[i]; } } void output(char b[],int m){ for(int i=0;im;i++){ cout<"Индекс "<(i+1)<", элемент= "[i]; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
//2 #include using namespace std; void input(char c[],int n); void output(char h[], int o); int main(){ char * vio= new char[5]; input(vio,5);//ввод output(vio,5);//вывод delete [] vio; return 0; } void input(char c[],int n){ for(int i=0;in;i++){ cout<"Элемент "<(i+1); cin>>c[i]; } } void output(char h[], int o){ for(int i=0;io;i++){ cout<"Ваши элементы "[i]; } }

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

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