Передача list в качестве параметра функции
Я хочу передать неинициализированный list в качестве аргумента в функцию add , чтобы там его изменить. Что я делаю не так?
#include #include #include using namespace std; typedef struct < char author[30]; >SONG; void add( * b) < char a[30]; cin >> a; SONG singer; b.push_front(singer); /*тут я хочу получить массив и изменить его, но показывает ошибку*/ strcpy_s(singer.author, a); list::iterator it; it = b.begin(); b.insert(++it, singer); > int main() < list myList; cout > input; switch (input) < case 1: add(list&myList); /*вот тут хочу передать массив по ссылке*/ break; default: cout return 0; >
Отслеживать
219k 15 15 золотых знаков 119 119 серебряных знаков 230 230 бронзовых знаков
Коллекции
Хотя в языке C# есть массивы, которые хранят в себе наборы однотипных объектов, но работать с ними не всегда удобно. Например, массив хранит фиксированное количество объектов, однако что если мы заранее не знаем, сколько нам потребуется объектов. И в этом случае намного удобнее применять коллекции. Еще один плюс коллекций состоит в том, что некоторые из них реализует стандартные структуры данных, например, стек, очередь, словарь, которые могут пригодиться для решения различных специальных задач. Большая часть классов коллекций содержится в пространстве имен System.Collections.Generic .
Класс List из пространства имен System.Collections.Generic представляет простейший список однотипных объектов. Класс List типизируется типом, объекты которого будут хранится в списке.
Мы можем создать пустой список:
List people = new List();
В данном случае объект List типизируется типом string . А это значит, что хранить в этом списке мы можем только строки.
Можно сразу при создании списка инициализировать его начальными значениями. В этом случае элементы списка помещаются после вызова конструктора в фигурных скобках
List people = new List() < "Tom", "Bob", "Sam" >;
В данном случае в список помещаются три строки
Также можно при создании списка инициализировать его элементами из другой коллекции, например, другого списка:
var people = new List() < "Tom", "Bob", "Sam" >; var employees = new List(people);
Можно совместить оба способа:
var people = new List() < "Tom", "Bob", "Sam" >; var employees = new List(people);
В данном случае в списке employees будет четыре элемента ( < "Tom", "Bob", "Sam", "Mike" >) — три добавляются из списка people и один элемент задается при инициализации.
Начиная с версии C# 12 для определения списков можно использовать выражения коллекций, которые предполагают заключение элементов коллекции в квадратные скобки:
List people = ["Tom", "Bob", "Sam"]; List employees = [];// пустой список
Подобным образом можно работать со списками других типов, например:
List people = new List() < new Person("Tom"), new Person("Bob"), new Person("Sam") >; class Person < public string Name < get;>public Person(string name) => Name = name; >
Установка начальной емкости списка
Еще один конструктор класса List принимает в качестве параметра начальную емкость списка:
List people = new List(16);
Указание начальной емкости списка позволяет в будущем увеличить производительность и уменьшить издержки на выделение памяти при добавлении элементов. Поскольку динамическое добавление в список может приводить на низком уровне к дополнительному выделению памяти, что снижает производительность. Если же мы знаем, что список не будет превышать некоторый размер, то мы можем передать этот размер в качестве емкости списка и избежать дополнительных выделений памяти.
Также начальную емкость можно установить с помощью свойства Capacity , которое имеется у класса List.
Обращение к элементам списка
Как и массивы, списки поддерживают индексы, с помощью которых можно обратиться к определенным элементам:
var people = new List() < "Tom", "Bob", "Sam" >; string firstPerson = people[0]; // получаем первый элемент Console.WriteLine(firstPerson); // Tom people[0] = "Mike"; // изменяем первый элемент Console.WriteLine(people[0]); // Mike
Длина списка
С помощью свойства Count можно получить длину списка:
var people = new List() < "Tom", "Bob", "Sam" >; Console.WriteLine(people.Count); // 3
Перебор списка
C# позволяет осуществить перебор списка с помощью стандартного цикла foreach :/p>
var people = new List() < "Tom", "Bob", "Sam" >; foreach (var person in people) < Console.WriteLine(person); >// Вывод программы: // Tom // Bob // Sam
Также можно использовать другие типы циклов и в комбинации с индексами перебирать списки:
var people = new List() < "Tom", "Bob", "Sam" >; for (int i = 0; i
Методы списка
Среди его методов можно выделить следующие:
- void Add(T item) : добавление нового элемента в список
- void AddRange(IEnumerable collection) : добавление в список коллекции или массива
- int BinarySearch(T item) : бинарный поиск элемента в списке. Если элемент найден, то метод возвращает индекс этого элемента в коллекции. При этом список должен быть отсортирован.
- void CopyTo(T[] array) : копирует список в массив array
- void CopyTo(int index, T[] array, int arrayIndex, int count) : копирует из списка начиная с индекса index элементы, количество которых равно count, и вставляет их в массив array начиная с индекса arrayIndex
- bool Contains(T item) : возвращает true , если элемент item есть в списке
- void Clear() : удаляет из списка все элементы
- bool Exists(Predicate match) : возвращает true , если в списке есть элемент, который соответствует делегату match
- T? Find(Predicate match) : возвращает первый элемент, который соответствует делегату match. Если элемент не найден, возвращается null
- T? FindLast(Predicate match) : возвращает последний элемент, который соответствует делегату match. Если элемент не найден, возвращается null
- List FindAll(Predicate match) : возвращает список элементов, которые соответствуют делегату match
- int IndexOf(T item) : возвращает индекс первого вхождения элемента в списке
- int LastIndexOf(T item) : возвращает индекс последнего вхождения элемента в списке
- List GetRange(int index, int count) : возвращает список элементов, количество которых равно count, начиная с индекса index.
- void Insert(int index, T item) : вставляет элемент item в список по индексу index. Если такого индекса в списке нет, то генерируется исключение
- void InsertRange(int index, collection) : вставляет коллекцию элементов collection в текущий список начиная с индекса index. Если такого индекса в списке нет, то генерируется исключение
- bool Remove(T item) : удаляет элемент item из списка, и если удаление прошло успешно, то возвращает true. Если в списке несколько одинаковых элементов, то удаляется только первый из них
- void RemoveAt(int index) : удаление элемента по указанному индексу index. Если такого индекса в списке нет, то генерируется исключение
- void RemoveRange(int index, int count) : параметр index задает индекс, с которого надо удалить элементы, а параметр count задает количество удаляемых элементов.
- int RemoveAll((Predicate match)) : удаляет все элементы, которые соответствуют делегату match. Возвращает количество удаленных элементов
- void Reverse() : изменяет порядок элементов
- void Reverse(int index, int count) : изменяет порядок на обратный для элементов, количество которых равно count, начиная с индекса index
- void Sort() : сортировка списка
- void Sort(IComparer? comparer) : сортировка списка с помощью объекта comparer, который передается в качестве параметра
Добавление в список
List people = new List () < "Tom" >; people.Add("Bob"); // добавление элемента // people = < "Tom", "Bob" >; people.AddRange(new[] < "Sam", "Alice" >); // добавляем массив // people = < "Tom", "Bob", "Sam", "Alice" >; // также можно было бы добавить другой список // people.AddRange(new List()< "Sam", "Alice" >); people.Insert(0, "Eugene"); // вставляем на первое место // people = < "Eugene", "Tom", "Bob", "Sam", "Alice" >; people.InsertRange(1, new string[] ); // вставляем массив с индекса 1 // people = < "Eugene", "Mike", "Kate", "Tom", "Bob", "Sam", "Alice" >; // также можно было бы добавить другой список // people.InsertRange(1, new List()< "Mike", "Kate" >);
Удаление из списка
var people = new List () < "Eugene", "Mike", "Kate", "Tom", "Bob", "Sam", "Tom", "Alice" >; people.RemoveAt(1); // удаляем второй элемент // people = < "Eugene", "Kate", "Tom", "Bob", "Sam", "Tom", "Alice" >; people.Remove("Tom"); // удаляем элемент "Tom" // people = < "Eugene", "Kate", "Bob", "Sam", "Tom", "Alice" >; // удаляем из списка все элементы, длина строки которых равна 3 people.RemoveAll(person => person.Length == 3); // people = < "Eugene", "Kate", "Alice" >; // удаляем из списка 2 элемента начиная с индекса 1 people.RemoveRange(1, 2); // people = < "Eugene">; // полностью очищаем список people.Clear(); // people = < >;
Поиск и проверка элемента
var people = new List () < "Eugene", "Mike", "Kate", "Tom", "Bob", "Sam" >; var containsBob = people.Contains(«Bob»); // true var containsBill = people.Contains(«Bill»); // false // проверяем, есть ли в списке строки с длиной 3 символа var existsLength3 = people.Exists(p => p.Length == 3); // true // проверяем, есть ли в списке строки с длиной 7 символов var existsLength7 = people.Exists(p => p.Length == 7); // false // получаем первый элемент с длиной в 3 символа var firstWithLength3 = people.Find(p => p.Length == 3); // Tom // получаем последний элемент с длиной в 3 символа var lastWithLength3 = people.FindLast(p => p.Length == 3); // Sam // получаем все элементы с длиной в 3 символа в виде списка List peopleWithLength3 = people.FindAll(p => p.Length == 3); // peopleWithLength3
Получение диапазона и копирование в массив
List people = new List() ; // получаем диапазон со второго по четвертый элемент var range = people.GetRange(1, 3); // range = < "Tom", "Mike", "Sam">; // копируем в массив первые три элемента string[] partOfPeople = new string[3]; people.CopyTo(0, partOfPeople, 0, 3); // partOfPeople = < "Eugene", "Tom", "Mike">;
Расположение элементов в обратном порядке
var people = new List () < "Eugene", "Tom", "Mike", "Sam", "Bob" >; // переворачиваем весь список people.Reverse(); // people = < "Bob","Sam", "Mike", "Tom", "Eugene">; var people2 = new List() < "Eugene", "Tom", "Mike", "Sam", "Bob" >; // переворачиваем часть только 3 элемента с индекса 1 people2.Reverse(1, 3); // people2 = < "Eugene","Sam", "Mike", "Tom", "Bob" >;
C# Как передать и вернуть из функции список не явного типа List?

Вот и вся суть вопроса. Мне нужно, чтобы функция хватала список, перетасовывала и возвращала. И не задавалась вопросом какой там тип, кто, что и чего. Просто взяла, миксанула, и выплюнула.
Голосование за лучший ответ
Напиши текстом
вопервых viod замени на List, а потом заполняй свой список и делай return ТвойСписокТипаList
public static IEnumerable FisherYatesShuffle(this IEnumerable list)
<
Random random = new Random();
List shuffled = new List(list);
int n = shuffled.Count;
while (n > 1)
<
n—;
int randomIndex = random.Next(n + 1);
T value = shuffled[randomIndex];
shuffled[randomIndex] = shuffled[n];
shuffled[n] = value;
>
return shuffled;
>
В C# нет типа List, но вы можете использовать List для создания списка неявного типа. Вы можете передать этот список в функцию как параметр и вернуть его из функции, как и любой другой тип данных. Вот пример кода:
public List Shuffle(List list)
<
Random rng = new Random();
int n = list.Count;
while (n > 1)
<
n—;
int k = rng.Next(n + 1);
dynamic value = list[k];
list[k] = list[n];
list[n] = value;
>
return list;
>
В этом примере функция Shuffle принимает список неявного типа List
List myList = new List() ;
myList = Shuffle(myList);
АМудрец (14498) 5 месяцев назад
какой ужас
Александр ГлактионовЗнаток (403) 5 месяцев назад
дженерики для кого придумали?
Функции со списками аргументов переменных (C++)
Функции, в объявлениях которых в качестве последнего члена указано многоточие (. ), могут принимать переменное число аргументов. В таких случаях C++ обеспечивает проверку типа только для явно объявленных аргументов. Переменные списки аргументов можно использовать, если функция должна быть настолько универсальной, что могут изменяться даже количество и типы аргументов. Семейство функций — это пример функций, использующих списки аргументов переменной. printf argument-declaration-list
Функции с переменными аргументами
Чтобы получить доступ к аргументам после объявления, используйте макросы, содержащиеся в стандартном файле , как описано ниже.
Блок, относящийся только к системам Майкрософт
Microsoft C++ допускает указывать многоточие в качестве аргумента, если это последний аргумент и перед многоточием стоит запятая. Поэтому объявление int Func( int i, . ); допускается, а объявление int Func( int i . ); — нет.
Завершение блока, относящегося только к системам Майкрософт
В объявлении функции, которая принимает переменное число аргументов, требуется по крайней мере один аргумент-местозаполнитель, даже если он не используется. Если этот аргумент-местозаполнитель не указан, доступ к остальным аргументам невозможен.
Когда аргументы типа char передаются в качестве аргументов переменной, они преобразуются в тип int . Аналогичным образом, когда аргументы типа float передаются в качестве аргументов переменной, они преобразуются в тип double . Для аргументов остальных типов могут выполняться обычные восходящие приведения целочисленных типов и типов с плавающей запятой. Дополнительные сведения см. в разделе «Стандартные преобразования».
Функции, которым необходимы списки с переменным количеством аргументов, объявляются с многоточием (. ) в списках аргументов. Используйте типы и макросы, описанные в , чтобы получить доступ к аргументам, передаваемым списком переменных. Дополнительные сведения об этих макросах см. в va_arg , va_copy, va_end va_start. в документации по библиотеке времени выполнения C.
В следующем примере показано, как макросы работают вместе с типом (объявленным в ):
// variable_argument_lists.cpp #include #include // Declaration, but not definition, of ShowVar. void ShowVar( char *szTypes, . ); int main() < ShowVar( "fcsi", 32.4f, 'a', "Test string", 4 ); >// ShowVar takes a format string of the form // "ifcs", where each character specifies the // type of the argument in that position. // // i = int // f = float // c = char // s = string (char *) // // Following the format specification is a variable // list of arguments. Each argument corresponds to // a format character in the format string to which // the szTypes parameter points void ShowVar( char *szTypes, . ) < va_list vl; int i; // szTypes is the last argument specified; you must access // all others using the variable-argument macros. va_start( vl, szTypes ); // Step through the list. for( i = 0; szTypes[i] != '\0'; ++i ) < union Printable_t < int i; float f; char c; char *s; >Printable; switch( szTypes[i] ) < // Type to expect. case 'i': Printable.i = va_arg( vl, int ); printf_s( "%i\n", Printable.i ); break; case 'f': Printable.f = va_arg( vl, double ); printf_s( "%f\n", Printable.f ); break; case 'c': Printable.c = va_arg( vl, char ); printf_s( "%c\n", Printable.c ); break; case 's': Printable.s = va_arg( vl, char * ); printf_s( "%s\n", Printable.s ); break; default: break; >> va_end( vl ); > //Output: // 32.400002 // a // Test string
Приведенный выше пример иллюстрирует следующие важные правила:
- Перед тем как обращаться к аргументам из списка переменной длины, необходимо установить его маркер в качестве переменной типа va_list . В приведенном выше примере этот маркер имеет имя vl .
- К отдельным аргументам можно обращаться при помощи макроса va_arg . Макросу va_arg необходимо указать тип получаемых аргументов, чтобы он мог перенести из стека нужное количество байтов. Если вы ошибетесь и укажете другой тип, а его размер не будет совпадать с типом, который вызывающая программа передает макросу va_arg , это может привести к непредсказуемым результатам.
- Результат, полученный при помощи макроса va_arg , необходимо явным образом преобразовывать в нужный вам тип.
Для завершения обработки списка с переменным количеством аргументов необходимо вызвать макрос. va_end