The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"Как вернуть из функции массив (строку?)"
Вариант для распечатки  
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [ Отслеживать ]

"Как вернуть из функции массив (строку?)"  
Сообщение от vladsol (ok) on 20-Ноя-08, 00:38 
Здравствуйте.
Начал изучать С++ недавно, поэтому, прошу прощения за "ламерский" вопрос, просто
не нашёл какого-то однозначного ответа.

Предположим, у меня есть функция. Для упрощения что-то типа:

char func() {

char string[200] = "string";

}

- как мне вывести это значение, чтобы его можно было использовать в вызывающей
данную функцию функции?

Или же, как вариант:
инициализирую переменную вне функции:
char temp[200] = "TEST";
- как к ней можно обратиться (точнее, записать в массив строку) из функции..?

void func() {

//&temp; - при таком обращении, к примеру, из printf() значение возвращается.
// Но как записать строку в этот же массив?

}

Высказать мнение | Ответить | Правка | Cообщить модератору

 Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "Как вернуть из функции массив (строку?)"  
Сообщение от TyLLIKAH on 20-Ноя-08, 01:15 
>// Но как записать строку в этот же массив?

Пользуй strcpy или memcpy, помня о том, что в конце строки должен быть 0
желательно ещё и про memset не забывать

Рекомендую книжку Б.И.Березин С.Б. Березин "Начальный курс C и C++"

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

2. "Как вернуть из функции массив (строку?)"  
Сообщение от TyLLIKAH on 20-Ноя-08, 01:18 
Там где нежелательно пользоваться глобальными переменными логика такая: вызывающая функция выделяет буффер, обнуляет его, передаёт как параметр его и его размер вызываемой функции, вызывает функцию, выводит результат, освобождает буффер.
Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

3. "Как вернуть из функции массив (строку?)"  
Сообщение от const email(??) on 20-Ноя-08, 09:58 
Можно и не обнулять. Это же выходной параметр, вызываемая функция всё равно оттуда ничего читать не будет.

Если требуется возвращать массив фиксированного размера, то хочется написать

int[5] func(...);

но так нельзя. Можно завернуть массив в структуру и возвращать её

struct func_result {
  int data[5];
};
struct func_result func(...);

либо использовать предложенный выше способ.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

5. "Как вернуть из функции массив (строку?)"  
Сообщение от TyLLIKAH on 20-Ноя-08, 15:52 
>Можно и не обнулять.

Можно, можно... Потом можно не найти конец строки и вывести printf ом столько всего смешного на экран. Хотя, это не так забавно, как создавать структуру всякий раз, как хочешь вернуть строку из функции

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

6. "Как вернуть из функции массив (строку?)"  
Сообщение от vic (??) on 20-Ноя-08, 16:41 
>>Можно и не обнулять.
>
>Можно, можно... Потом можно не найти конец строки и вывести printf ом
>столько всего смешного на экран. Хотя, это не так забавно, как
>создавать структуру всякий раз, как хочешь вернуть строку из функции

Если уж функция берет на себя труд вернуть структуру с массивом внутри, то она обязана корректно заполнить его. Таким образом printf() всегда найдет конец строки в таком массиве, если конечно в коде функции нет баги типа возврата не инициализированной структуры. Обнуление в данном случае лишняя операция, т.к. в случае если в сам массив будет записано n байт вместо n-1, или что не менее прикольно n+1 или n+2 байт и т.д. printf() или любая функция оперирующая с массивом как с терминированной строкой будут сильно озадачены.

Естественно при создании "тяжелых" структур на возврате из функции возникнет вопрос оптимизации.

Автор поста спрашивал "как на С++", но при это запрашивает присущие С способы. Автору следует определится с языком, т.к. для C++ есть контейнеры STL (в частности std::string).

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

7. "Как вернуть из функции массив (строку?)"  
Сообщение от TyLLIKAH on 20-Ноя-08, 18:23 
>Если уж функция берет на себя труд вернуть структуру с массивом внутри,
>Обнуление в данном случае лишняя операция

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

Всегда за начальной корректностью выделяемых буферов и указателей, переменных.. должна следить та процедура, которая их объявляет. Если выделяется буфер, он обнуляется. Если объявляется указатель, то он или NULL или действительное значение должен получить. Поверьте моему опыту - это очень часто избавляет от сильного геморроя. Обнуление это не запихивание структуры в стек - оно делается очень быстро.

>Естественно при создании "тяжелых" структур на возврате из функции возникнет вопрос оптимизации.

Лучшая оптимизация в данном случае - не делать через не то место.

>Автор поста спрашивал "как на С++", но при это запрашивает присущие С
>способы.

Ничего "присущего С" и не "присущего" С++ я в его вопросе не увидел, кроме printf

Автору следует определится с языком, т.к. для C++ есть контейнеры
>STL (в частности std::string).

STL это библиотека, а не часть языка. Если человек только начал разбираться с базовыми понятиями, то от STL у него мозги могут закипеть. Не следует ему ни с чем определяться на начальном этапе.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

8. "Как вернуть из функции массив (строку?)"  
Сообщение от vic (??) on 20-Ноя-08, 19:29 
>>Если уж функция берет на себя труд вернуть структуру с массивом внутри,
>>Обнуление в данном случае лишняя операция
>
>Нет. Обнуление не лишняя операция никогда. Обнуление буфера сразу после его выделения
>- признак хорошего стиля и средство, в некоторых случаях, спасающее от
>изрядного геморроя.

Неа,
memset(buf, 0, BUF_LEN)); // BUF_LEN = 1024*1024 мелочь, аха
А теперь другой программист вызвал функцию с таким обнулением раз так 100000, ну надо было..
Обнулять надо только тогда когда не производится заполнение тут же. Если заполняем где-то в другом месте и есть между объявлением и заполнением возможность уйти по другой ветке кода (в том числе exception) или выйти преждевременно из функции, тогда обнуление может пресечь использование _неинициализированной_ переменной.

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

а при обнулении счастья тоже не будет. будет другой но тоже неверный результат. хоть и не всегда.
>
>Всегда за начальной корректностью выделяемых буферов и указателей, переменных.. должна следить та
>процедура, которая их объявляет. Если выделяется буфер, он обнуляется. Если объявляется
>указатель, то он или NULL или действительное значение должен получить. Поверьте
>моему опыту - это очень часто избавляет от сильного геморроя. Обнуление
>это не запихивание структуры в стек - оно делается очень быстро.

выше показана мегаскорость неразумного обнуления.
обнуление должно быть разумным, а не повсеместным.

>
>Ничего "присущего С" и не "присущего" С++ я в его вопросе не
>увидел, кроме printf

Плохо, не надо писать на С++ как на С и тогда откроются новые горизонты и мощь С++ :)


>Автору следует определится с языком, т.к. для C++ есть контейнеры
>>STL (в частности std::string).
>
>STL это библиотека, а не часть языка.

Читайте внимательно, я разве сказал STL часть языка?
Писать на C++ без STL, как-то большого смысла не имеет, сейчас даже части boost стандартизируют как часть языка.

> Если человек только начал разбираться
>с базовыми понятиями, то от STL у него мозги могут закипеть.
>Не следует ему ни с чем определяться на начальном этапе.

Это не так:
std::string func1()
{
    std::string s("1234");
    s += "Hello";
    return s;
}
Что сложного в коде? Все просто для начального уровня.
Ничего не закипит при спокойном вдумчивом последовательном изучении материала.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

9. "Как вернуть из функции массив (строку?)"  
Сообщение от TyLLIKAH on 20-Ноя-08, 20:38 
>Обнулять надо только тогда когда не производится заполнение тут же

Ёлки-палки! Я же написал, зачем нужно обнулять. Вы пытаетесь напугать меня большим объёмом буфера. Внутри memset ассемблерная вставка, которая отработает максимально быстро.

>Обнулять надо только тогда когда не производится заполнение тут же.

Это вопрос надёжности. Когда не производится заполнение туда же или когда есть вероятность, что такое заполнение не будет произведено или будет произведено неправильно. И уж никак нельзя подменять надёжность быстродействием на этапе обучения языку.

>Писать на C++ без STL, как-то большого смысла не имеет,

Есть много областей, где не используется stl или его альтернативы. В любом случае, сначала изучается язык, потом библиотеки к этому языку. От простого к сложному.

>Что сложного в коде?

Человек пытается разобраться с базовыми операциями над базовыми типами языка. Если он это пропустит, то до конца своих дней потом будет засовывать структуры в стек.

Короче, ВСЕХ, КТО НЕ БУДЕТ ОБНУЛЯТЬ БУФЕР, УКАЗАТЕЛИ, И ПЕРЕМЕННЫЕ - ПРОКЛЯНУ!

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

10. "Как вернуть из функции массив (строку?)"  
Сообщение от TyLLIKAH on 20-Ноя-08, 20:54 
Вот, кстати, пример из истории: в начале тысячилетия в борландовском линкире был такой баг - он пихал в экзешник в неиспользуемые области (вроде в релокационную таблицу или ещё куда. не помню уже) всякий мусор. Заметили это когда кто-то обнаружил в только что скомпилированном экзешнике части своих (вроде даже вордовских) документов, которых там ну никак не могло оказаться. Всё потому, что линкер мерзавец не чистил буфер. А чё? Зато быстро работал.
Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

14. "Как вернуть из функции массив (строку?)"  
Сообщение от vic (??) on 21-Ноя-08, 14:37 
>Вот, кстати, пример из истории: в начале тысячилетия в борландовском линкире был
>такой баг - он пихал в экзешник в неиспользуемые области (вроде
>в релокационную таблицу или ещё куда. не помню уже) всякий мусор.
>Заметили это когда кто-то обнаружил в только что скомпилированном экзешнике части
>своих (вроде даже вордовских) документов, которых там ну никак не могло
>оказаться. Всё потому, что линкер мерзавец не чистил буфер. А чё?
>Зато быстро работал.

Из вашего описания бага следует что линкер не пихал туда вообще ничего, оно там было т.к. винда не почистила где-то что-то (в памяти/на диске), иначе откуда взялись доки там :))
а все потому что винда и стандарты рядом не валялись :)

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

18. "Как вернуть из функции массив (строку?)"  
Сообщение от TyLLIKAH on 21-Ноя-08, 15:45 
>оно там было т.к. винда не почистила где-то что-то (в памяти/на

Кто бы не почистил, он не почистил. В следствии, что кто-то не почистил система отработала некорректно.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

13. "Как вернуть из функции массив (строку?)"  
Сообщение от vic (??) on 21-Ноя-08, 14:15 
>>Обнулять надо только тогда когда не производится заполнение тут же
>
>Ёлки-палки! Я же написал, зачем нужно обнулять. Вы пытаетесь напугать меня большим
>объёмом буфера. Внутри memset ассемблерная вставка, которая отработает максимально быстро.

Сколько надо времени на обнуление 4GB? Несколько раз подряд?
Я не пугаю, я говорю о том что подход должен быть разумным, а не параноидальным.

>
>>Обнулять надо только тогда когда не производится заполнение тут же.
>
>Это вопрос надёжности. Когда не производится заполнение туда же или когда есть
>вероятность, что такое заполнение не будет произведено или будет произведено неправильно.
>И уж никак нельзя подменять надёжность быстродействием на этапе обучения языку.

Не стоит аккуратность подменять паранойей.

>
>
>>Писать на C++ без STL, как-то большого смысла не имеет,
>
>Есть много областей, где не используется stl или его альтернативы. В любом
>случае, сначала изучается язык, потом библиотеки к этому языку. От простого
>к сложному.

Да что вы говорите, изучается совместно с азов :)

язык С:
#include <stdio.h>  // <----- библиотека io, не часть языка
int main(int argc, char *argv[])
{
   printf("Hello world\n"); // <-------- библиотека io, не часть языка
   return 0;
}

язык С++:
#include <iostream> // <----- библиотека stl io, не часть языка
int main(int argc, char *argv[])
{
   std::cout << "Hello world" << std::endl; // <----- библиотека stl io, не часть языка
   return 0;
}

>
>>Что сложного в коде?
>
>Человек пытается разобраться с базовыми операциями над базовыми типами языка. Если он
>это пропустит, то до конца своих дней потом будет засовывать структуры
>в стек.

Если он будет внимательно изучать матчасть проблем не будет, не стоит думать за него, сам разберется.
Кстати, автоматические переменные в том числе и структуры размещаются в общем-то в стеке, так что и он и вы и я, запихиваем, запихивали и будем запихивать структуры в стек ;) гг))

>
>Короче, ВСЕХ, КТО НЕ БУДЕТ ОБНУЛЯТЬ БУФЕР, УКАЗАТЕЛИ, И ПЕРЕМЕННЫЕ - ПРОКЛЯНУ!
>

ПвП?)

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

16. "Как вернуть из функции массив (строку?)"  
Сообщение от TyLLIKAH on 21-Ноя-08, 15:37 
>Сколько надо времени на обнуление 4GB? Несколько раз подряд?
>Я не пугаю, я говорю о том что подход должен быть разумным,
>а не параноидальным.

А чего только 4 ? А чего не 10 ? Вот хотел человек вернуть строчку из процедуры, а его бац и уже обвиняют в обнулении 4х гиг памяти! Сходил, называется, за хлебушком :-(

Чисто логически: Буфер выбирается таким, чтобы его заполнить данными. Значит будет получено 4 гб данных. 4 гб данных, как продукт алгоритма, который сложнее простого обнуления памяти. Значит обнуление не будет бутылочным горлышком в любом случае.

Какие же бонусы мы получим от этого ? Например, strlen и printf отработают корректно в случае сбоя функции, не залезут за границы памяти выделенной для буфера в поисках терминатора строки. Можно нафантазировать множество других примеров.

Какова вероятность сбоя в ходе обучения ? Весьма высокая.

Существенны ли потери быстродействия в данном случае ? Абсолютно нет.

Нужно ли думать каждый раз, создавая алгоритм ? Да

В интернете масса статей и книг по безопасному кодированию на С. Почитайте их пожалуйста. В обмен я обещаю вас не проклинать, даже если вы будете делить на ноль!

Я всё сказал по этой теме. Дальше её обсуждать не планирую. Если вы меня не поняли - жаль. Наверное, я плохо объяснял.

>Не стоит аккуратность подменять паранойей.

Я к говорю о надёжности. У меня есть подозрение, что вы раньше на Pascalе программировали... Или (о ужас!) на бейсике ?

>Да что вы говорите, изучается совместно с азов :)

Не надо петь военных песен. STL в качестве части стандартной библиотеки с++ был принят относительно недавно.

>#include <stdio.h>  // <----- библиотека io, не часть языка

Какое тонкое наблюдение!

>Если он будет внимательно изучать матчасть проблем не будет, не стоит думать
>за него, сам разберется.

Я говорил о том, что сначала нужно разобраться в вещах, а потом уже постигать чем они друг от друга отличаются, а не наоборот. Я думаю он даже разберётся с тем, почему у него strlen неправильно работает на необнулённом буфере. И китайцы с индусами когда-нибудь драйвера начнут качественные писать... Я вообще в человечество верю! Да

>Кстати, автоматические переменные в том числе и структуры размещаются в общем-то в
>стеке, так что и он и вы и я, запихиваем, запихивали

Да? А каково прокачать через стек 4гб памяти с точки зрения быстродействия ?

>ПвП?)

IDDQD

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

20. "Как вернуть из функции массив (строку?)"  
Сообщение от vic (??) on 21-Ноя-08, 16:52 
>А чего только 4 ? А чего не 10 ? Вот хотел
>человек вернуть строчку из процедуры, а его бац и уже обвиняют
>в обнулении 4х гиг памяти! Сходил, называется, за хлебушком :-(

И где это я его в этом обвинил?.
Лишнее обнуление 100 байт при многократном повторении выльются запросто в 4гб.
Еще раз, _лишнее_ обнуление, об этом говорю с самого начала.
Вы же считаете что я говорю о не нужности инициализации вообще, а это не так.


Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

12. "Как вернуть из функции массив (строку?)"  
Сообщение от const email(??) on 21-Ноя-08, 10:18 
>Хотя, это не так забавно, как создавать структуру всякий раз, как хочешь вернуть строку из функции

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

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

17. "Как вернуть из функции массив (строку?)"  
Сообщение от TyLLIKAH on 21-Ноя-08, 15:43 
>удобен в некоторых довольно специфичных ситуациях. Кстати, для передачи строки он
>совсем не подходит: массив должен иметь фиксированную на этапе компиляции длину.

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


Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

4. "Как вернуть из функции массив (строку?)"  
Сообщение от phpcoder email(??) on 20-Ноя-08, 12:19 
>Здравствуйте.
> Начал изучать С++ недавно, поэтому, прошу прощения за "ламерский" вопрос, просто

Есть вариант использовать std::string и не париться.


Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

11. "Как вернуть из функции массив (строку?)"  
Сообщение от vladsol (ok) on 20-Ноя-08, 23:30 
Не ожидал, честно говоря, что столько людей откликнутся :)
Спасибо за ответы! На данном этапе для меня самым простым (и понятным для меня) способом оказалось использование memcpy. Т.е., я просто инициализировал массив для "временных" данных и таким образом получилось передавать данные от функции к функции (не забывая обнулять эту "переменную"). Так что пока что всё :) Буду учиться дальше..:) Ещё раз спасибо!


Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

15. "Как вернуть из функции массив (строку?)"  
Сообщение от vic (??) on 21-Ноя-08, 14:47 
> Не ожидал, честно говоря, что столько людей откликнутся :)
>Спасибо за ответы! На данном этапе для меня самым простым (и понятным
>для меня) способом оказалось использование memcpy. Т.е., я просто инициализировал массив
>для "временных" данных и таким образом получилось передавать данные от функции
>к функции (не забывая обнулять эту "переменную"). Так что пока что
>всё :) Буду учиться дальше..:) Ещё раз спасибо!

Позволю себе порекомендовать для начального изучения и понимания основ программирования на С и С++ книги написанные _авторами_ этих языков (кто как не они лучше всех знают о своем языке):
С:
Керниган, Ричи. Язык программирования С
http://www.ozon.ru/context/detail/id/96537
С++:
Б. Страуструп. Язык программирования C++
http://www.ozon.ru/context/detail/id/85559


Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

19. "Как вернуть из функции массив (строку?)"  
Сообщение от TyLLIKAH on 21-Ноя-08, 15:50 
>и С++ книги написанные _авторами_ этих языков (кто как не они
>лучше всех знают о своем языке):

Книги разные важны, книги всякие важны. Только из того, что они сделали гениальный язык программирования, совершенно не значит, что они так же гениально могут ему научить - тут другой талант нужен. Керниган,Ричи неподготовленным пользователем читается адски трудно.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

Архив | Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Оцените тред (1=ужас, 5=супер)? [ 1 | 2 | 3 | 4 | 5 ] [Рекомендовать для помещения в FAQ]




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру