Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.87/86: Рейтинг темы: голосов - 86, средняя оценка - 4.87
1569 / 505 / 48
Регистрация: 04.04.2009
Сообщений: 1,891
1

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

08.06.2012, 22:18. Показов 15741. Ответов 24
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Ребят, никогда раньше не задумывался каким же образом передаются аргументы. Сейчас же дошел до передачи аргументов через указатель и ссылку. И вот зашел в небольшой тупик.

Вот 3 простейших примера передачи аргументов:

а) через указатель:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
using namespace std;
 
void fn(int* pintArg) { //как это понять?
    *pintArg = 10;
}
 
int main(int nNumberofArgs, char* pszArgs[]) {
    int n = 0;
    fn(&n);
    cout << n << endl;
    system("PAUSE");
}
б) по ссылке:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
using namespace std;
 
void fn(int& intArg) { //как это понять?
    intArg = 10;
}
 
int main(int nNumberofArgs, char* pszArgs[]) {
    int n = 0;
    fn(n);
    cout << n << endl;
    system("PAUSE");
}
в) "простая" передача аргумента (смысла в данном случае не имеет):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
using namespace std;
 
void fn(int intArg) { //как это понять?
    intArg = 10;
}
 
int main(int nNumberofArgs, char* pszArgs[]) {
    int n = 0;
    fn(n);
    cout << n << endl;
    system("PAUSE");
}
Все три случая просты и понятны. Но мне они понятны лишь на словах, т.к. передачу аргумента я представляю в абстрактном виде.

Хочется же узнать что конкретно происходит (не на словах, а кодом), когда функция получает аргумент во всех 3 случаях.

Я понимаю это так:

а)
C++
1
int* pintArg = &n // где &n - адрес переменной n
б)
C++
1
2
int& intArg = n // где n - адрес переменной n, 
//хотя это не очевидно, т.к. ожидается значение переменной n
в)
C++
1
int intArg = n // где n - значение переменной n
В общем, я слегка разжевал для себя содержимое скобочек у функций.

1) правильно ли я это сделал?
2) насчет "разжевок" под "б" и "в". Все-таки немного не понимаю, почему в случае "б" от n берется адрес, а в случае "в" - значение? Это определяет тип переменной? int& и int соответственно? Хм, они выступают в качестве операторов, что ли? Я просто как думал: есть у нас что-то, что мы собираемся послать в качестве аргумента в функцию. И это что-то при посылке и при попадании в качестве аргумента в функцию не меняется. Т.е. в данном случае что-то это n. У этой переменной есть значение - мы его и посылаем... Правда у этой переменной есть и адрес =/ Ммм, короче опять залез в кашу, которая ни для кого не каша...

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

Надеюсь на поддержку
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
08.06.2012, 22:18
Ответы с готовыми решениями:

Передача аргументов функции
В книге Стенли Липпмана C++ Primer дошел до программы, которая выполняет замену слов в одном файле,...

Передача аргументов функции
Как передать функции переменную неизвестного типа?

Функции и передача аргументов
Здравствуйте! Совсем не понимаю передачи в функции массивов и векторов.. Ну как пример. Почему так...

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

24
348 / 269 / 128
Регистрация: 14.11.2010
Сообщений: 482
08.06.2012, 22:33 2
Лучший ответ Сообщение было отмечено как решение

Решение

В пункте А) ты передаешь адрес переменной, а так как ф-ия получает адрес она может использовать операцию разыменования для доступа к значению передаваемой переменной. А дальше её использует.
В пункте Б) ты передаешь по ссылке, а это значит что ты будешь работать напрямую с переменной.
В пункте В) ты передаешь по значению, а это значит что ты будешь работать с копией передаваемого аргумента, после выхода из ф-ю значение переменной останется прежним, а когда по ссылке по изменится.
3
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
08.06.2012, 22:58 3
Ну как я понимаю в любом случае будут создаваться копии...
Вопрос в том только копии чего? адреса(указателя или ссыки) или самой переменной.
в первом случае можно изменить значение переменной(значение по адресу) из нутри ф-ции, а во втором нет.

По указателю и по ссылке есть смысл передавать в двух случаях:
1. Что бы изменить (возвратить) больше чем одно значение переменной.
2. Для повышения эффективности( например при передаче const T& параметров) но я как понимаю это имеет смысл когда ссылка размером меньше чем сам объект
1
1569 / 505 / 48
Регистрация: 04.04.2009
Сообщений: 1,891
08.06.2012, 23:00  [ТС] 4
Andrey.K, спасибо, конечно, но я вроде написал:


Цитата Сообщение от The_Immortal Посмотреть сообщение
Все три случая просты и понятны.
Цитата Сообщение от The_Immortal Посмотреть сообщение
Хочется же узнать что конкретно происходит (не на словах, а кодом)



Цитата Сообщение от The_Immortal Посмотреть сообщение
В общем, я слегка разжевал для себя содержимое скобочек у функций.
1) правильно ли я это сделал?
?



Avazart,

Цитата Сообщение от Avazart Посмотреть сообщение
1. Что бы изменить (возвратить) больше чем одно значение переменной.
Мм... А можно примерчик какой-нибудь?

Цитата Сообщение от Avazart Посмотреть сообщение
2. Для повышения эффективности( например при передаче const T& параметров) но я как понимаю это имеет смысл когда ссылка размером меньше чем сам объект
С подобным не сталкивался, но если действительно есть такое, то тогда да - смысл использовать указатель/ссылки действительно имеется.

Добавлено через 1 минуту
Цитата Сообщение от Avazart Посмотреть сообщение
Ну как я понимаю в любом случае будут создаваться копии...
Хм... Копии? Т.е. типа в любом случае создается условная ссылка?
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
08.06.2012, 23:11 5
А можно примерчик какой-нибудь?
C++
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
//using namespace std; - не использую так как там уже есть эта ф-ция
template<class T>
void swap(T &a,T &b)
{
T temp=a;
a=b;
b=temp;
}
//--------------------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
system("chcp 1251");
 
int a=5,b=7;
 
std::cout<<"a= "<<a<<"\tb= "<<b<<std::endl;
 
swap(a,b);
 
std::cout<<"a= "<<a<<"\tb= "<<b<<std::endl;
 
system("pause");
return 0;
}
//---------------------------------------------------------------------------
Текущая кодовая страница: 1251
a= 5 b= 7
a= 7 b= 5
Для продолжения нажмите любую клавишу . . .
Хм... Копии? Т.е. типа в любом случае создается условная ссылка?
Локальна ссылка которая существует только внутри ф-ции
1
1569 / 505 / 48
Регистрация: 04.04.2009
Сообщений: 1,891
08.06.2012, 23:12  [ТС] 6
Avazart, блин... Придется попутно спросить, не дошел еще до этого


Цитата Сообщение от Avazart Посмотреть сообщение
C++
1
template<class T>
Если по-простому то что это такое? Некий абстрактный класс, которому без разницы с чем работать? В смысле с какими типами.

Добавлено через 54 секунды
Цитата Сообщение от Avazart Посмотреть сообщение
Локальна ссылка которая существует только внутри ф-ции
Согласен. Только вот как-то... В случае "б" - получается локальная ссылка на ссылку?
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
08.06.2012, 23:14 7
Тоже что и
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void swap(int &a,int &b)
{
int temp=a;
a=b;
b=temp;
}
//--------------------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
system("chcp 1251");
int a=5,b=7;
std::cout<<"a= "<<a<<"\tb= "<<b<<std::endl;
swap(a,b);
std::cout<<"a= "<<a<<"\tb= "<<b<<std::endl;
system("pause");
return 0;
}
//------------------------------------------------------
Только обобщенно для разных типов( которые потдерживаю операции которые делаются внутри ф-ции)
1
348 / 269 / 128
Регистрация: 14.11.2010
Сообщений: 482
08.06.2012, 23:15 8
Цитата Сообщение от The_Immortal Посмотреть сообщение
Avazart, блин... Придется попутно спросить, не дошел еще до этого



Если по-простому то что это такое? Некий абстрактный класс, которому без разницы с чем работать? В смысле с какими типами.
C++
1
2
3
4
5
template<class T>
T abs(T n)
{
return (n<0)?-n:n;
}
Слово template означает что сейчас будет шаблонная функция. Если у нас например есть три ф-и которые считают модуль числа, только возвращают разные типы, то удобно использовать шаблон.
1
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
08.06.2012, 23:17 9
Согласен. Только вот как-то... В случае "б" - получается локальная ссылка на ссылку?
Почему? Ссылка на переменную...
0
1569 / 505 / 48
Регистрация: 04.04.2009
Сообщений: 1,891
08.06.2012, 23:22  [ТС] 10
Avazart,

Цитата Сообщение от Avazart Посмотреть сообщение
Ну как я понимаю в любом случае будут создаваться копии...
Цитата Сообщение от Avazart Посмотреть сообщение
Локальна ссылка которая существует только внутри ф-ции
Значит я Вас не понял. Вы что имели тут в виду?


Andrey.K,

Цитата Сообщение от Andrey.K Посмотреть сообщение
Если у нас например есть три ф-и которые считают модуль числа, только возвращают разные типы, то удобно использовать шаблон.
Не догнал Вы привели такой пример?
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
08.06.2012, 23:34 11
Пример с шаблоном - хотя это уже другая тема!!!
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
template <class T>
T plus(const T& a,const T& b)
{
return a+b;
}
//--------------------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
system("chcp 1251");
int a=5,b=7;
 
std::string s1="abcd",s2="efg";
 
std::cout<< plus(a,b)   <<std::endl;
std::cout<< plus(s1,s2) <<std::endl;
 
system("pause");
return 0;
}
Код
Текущая кодовая страница: 1251
12
abcdefg
Для продолжения нажмите любую клавишу . . .
1
1569 / 505 / 48
Регистрация: 04.04.2009
Сообщений: 1,891
08.06.2012, 23:50  [ТС] 12
Avazart,

Цитата Сообщение от Avazart Посмотреть сообщение
хотя это уже другая тема!!!
Согласен.

Так все-таки, что Вы там имели в виду про копию и локальную ссылку? Я так это понял: при задействовании функции внутри нее условно создается локальная ссылка на переменную, с которой работает данная функция.

Вы про это?
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
09.06.2012, 00:03 13
Про это, но почему "условная" ?

Добавлено через 7 минут
"Копии указателей"
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void swap(int* pa,int* pb)
{
int *ptemp=pa;
pa=pb;
pb=ptemp;
}
//--------------------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
system("chcp 1251");
 
int a=5,b=7;
int *pa= &a;
int *pb= &b;
 
std::cout<<"a= "<<a<<"\tb= "<<b<<std::endl;
swap(pa,pb);
std::cout<<"a= "<<a<<"\tb= "<<b<<std::endl;
 
system("pause");
return 0;
}
//---------------------------------------------------------------------------
Код
Текущая кодовая страница: 1251
a= 5    b= 7
a= 5    b= 7
Для продолжения нажмите любую клавишу . . .
1
1569 / 505 / 48
Регистрация: 04.04.2009
Сообщений: 1,891
09.06.2012, 12:38  [ТС] 14
Avazart, все-таки не могу понять почему после вызова функции
Цитата Сообщение от Avazart Посмотреть сообщение
swap(pa,pb);
не меняются значения... Ведь в самой функции мы адреса, на которые указывают указатели, местами поменяли... Или это и есть "локальная замена"? А почему так?
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
09.06.2012, 14:05 15
Мы получили копии переменных содержащих адреса а и b(т.е копии указателей на а и b) а затем меняли не значения переменных а сами адреса.
Например такое бы проканало
C++
1
2
3
4
5
6
void swap(int* pa,int* pb)
{
int temp= *pa;
*pa=*pb;
*pb=temp;
}
0
1569 / 505 / 48
Регистрация: 04.04.2009
Сообщений: 1,891
09.06.2012, 18:26  [ТС] 16
Avazart,

Цитата Сообщение от Avazart Посмотреть сообщение
не значения переменных а сами адреса
Да это понятно. Вот вопрос как раз в том почему после выполнения данной функции адреса не поменялись?
В самой же функции замена произошла. pa получила адрес pb и наоброт.
А после выполнения функции этой замены нет.
Почему?
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
09.06.2012, 18:48 17
после выполнения данной функции адреса не поменялись?
Поменялись, но только не в pa и pb- указателях а в их копиях...

Добавлено через 3 минуты
Т.е равносильно
C++
1
2
3
4
5
6
int*  _pa = pa;
int*  _pb = pb;
 
int *ptemp= _pa;
_pa= _pb;
_pb= ptemp;
1
1569 / 505 / 48
Регистрация: 04.04.2009
Сообщений: 1,891
09.06.2012, 19:10  [ТС] 18
Avazart, хм. Ладно. А как тогда поменять там адреса оригиналов(пользуясь указателями)?


Цитата Сообщение от Avazart Посмотреть сообщение
C++
1
2
3
4
5
6
void swap(int* pa,int* pb) 
{ 
int temp= *pa; 
*pa=*pb; 
*pb=temp; 
}
- здесь мы играемся со значениями. А как вот чисто адрес поменять?
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
09.06.2012, 19:52 19
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void swap(int* &pa,int* &pb)
{
int* ptemp= pa;
pa= pb;
pb= ptemp;
}
//--------------------------------------------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
system("chcp 1251");
 
int a=5,b=7;
 
int *pa= &a;
int *pb= &b;
 
std::cout<<"a= "<<a<<"\tb= "<<b<<"\t*pa= "<<*pa<<"\t*pb= "<<*pb<<std::endl;
swap(pa,pb);
std::cout<<"a= "<<a<<"\tb= "<<b<<"\t*pa= "<<*pa<<"\t*pb= "<<*pb<<std::endl;
 
system("pause");
return 0;
}
//---------------------------------------------------------------------------
Код
Текущая кодовая страница: 1251
a= 5    b= 7    *pa= 5  *pb= 7
a= 5    b= 7    *pa= 7  *pb= 5
Для продолжения нажмите любую клавишу . . .
1
10 / 10 / 2
Регистрация: 26.02.2012
Сообщений: 36
09.06.2012, 20:05 20
Все очень просто .))
если ты создаешь указатель допустим int* PtrInt - то он указывает на адрес ячейки в памяти.(причем указывая тип int ты объясняешь указателю какой объем ячейка занимает)
Используя PtrInt - ты меняешь адресс на который указывает данный указатель.
Используя *PtrInt - ты изменяешь сами данные в этой ячейке.


По ссылке. <&> очень удобная штука если не охота заморачиваться - мол функция должна что то выдавать и бла-бла-бла .))
В твоем примере видно как это обыгрывается. В функцию выдается адрес ячейки.(Узнать адресс любой ячейки можно через добавочную &) так вот отдавая в функцию адрес - ты уже внутри работаешь с той же частью памяти, а не создаешь дополнительную копию, загромождая память(как в твоем 3 примере, хотя и эта переменная будет удалена по окончанию функции).

Главное их отличие:
Указатель - указывает первоначально на адрес ячейки (без снежинки).
Ссылка - указывает на данные в ячейки (без &).

Так же забыл сказать. Указатели в основном используются для динамических переменных, а ссылки для статических.
p.s. Динамические - забирают память в процессе работы программы, а статические при его загрузке.
2
09.06.2012, 20:05
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.06.2012, 20:05
Помогаю со студенческими работами здесь

Передача аргументов функции и параметры
Здравствуйте, никак не могу написать правильно параметры функции prntls string...

Передача аргументов в функции по ссылке
#include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;conio.h&gt; #include &lt;iomanip&gt; #include &lt;math.h&gt;...

Рекурсивная функция и передача аргументов функции
Помогите пожалуйста!!!!! Пропустила занятие, а разобраться не получается!!!!!!!!А нужно на...

Передача аргументов командной строки функции main()
Добрый день Дана задача: Напишите программу, которая запрашивает пароль, задаваемый в команд-...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru