Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
qppq
11 / 11 / 2
Регистрация: 31.08.2016
Сообщений: 163
Завершенные тесты: 1
#1

Нюансы синтаксиса и семантики: ссылки, указатели и массивы в качестве аргументов функций - C++

08.09.2016, 14:30. Просмотров 312. Ответов 14
Метки нет (Все метки)

 Комментарий модератора 
Перенесено из этой темы.


Чтобы вернуть указатели почему вот здесь не надо приводить janr к типу указателя char* на выходе?
C++
1
2
3
4
5
6
char* setJanr()
 {
    cout<<"Vvedite janr:";
    cin>>janr;
    return janr;
 }
а вот здесь для int надо
C++
1
2
3
4
5
6
7
int* setCena()
 {
    cout<<"Vvedite ceny:";
    cin>>cena;
    int *t = &cena;
    return t;
 }
только без помидоров
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.09.2016, 14:30
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Нюансы синтаксиса и семантики: ссылки, указатели и массивы в качестве аргументов функций (C++):

С++ Тема «Указатели и динамические массивы. Использование указателей в качестве аргументов функций» - C++
В целочисленном массиве Х(N) удалить все элементы, расположенные между макси-мальным и минимальным элементами. Найти среднее арифметическое...

Нюансы синтаксиса и семантики: что такое rvalue и lvalue? - C++
Добрый день, всем. Ребят, помогите разобраться в rvalue и lvalue. Читал об этом много чего, но все таки не понимаю, почему этому уделяется...

Указатели или ссылки (в качестве аргументов функции) ? - C++
В каких случая надо использовать ссылки и в каких указатели в качестве аргументов функции? В общем поняла, что и те и другие полезны для...

Константные указатели в качестве аргументов функций - C++
Вскрылся вот такой пробел в знаниях/понимании. Итак, есть предположим однонаправленный список (в общем без разницы что). struct TNode {...

Указатели на массивы в качестве аргументов - C++
Помогите пожалуйста а то вообще идей никаких нет( Напишите функцию поиска минимального элемента в динамическом двухмерном массиве...

Нюансы синтаксиса: что означает символ -> (указатели) - C++
ребят подскажите что означает такой символ: -&gt; вот пример кода: pq-&gt;arr

14
gru74ik
Модератор
Эксперт CЭксперт С++
4189 / 1837 / 198
Регистрация: 20.02.2013
Сообщений: 4,976
Записей в блоге: 21
08.09.2016, 14:47 #2
qppq, синтаксис такой. Когда объявляешь указатель, надо писать звездочку:
C++
1
int * myVeryAwesomePointerToInteger; // объявили указатель на тип int
Можно объявлять указатель и сразу инициализировать его значением (т.е. адресом):
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
26
27
28
29
30
#include <iostream>
 
int main()
{
    int myVariable = 10;
 
    // объявили указатель на тип int и инициализировали его адресом переменной myVariable:
    int * myVeryAwesomePointerToInteger = &myVariable;
 
    // выводим на консоль значение, лежащее по адресу &myVariable:
    std::cout
        << *myVeryAwesomePointerToInteger // разыменование указателя (выводится число 10)
        << "\n";
 
    // выводим на консоль адрес &myVariable:
    std::cout
        << myVeryAwesomePointerToInteger // выводится адрес ячейки памяти (какое-то шестнадцатеричное число)
        << "\n";
 
    // выводим на консоль значение переменной myVariable:
    std::cout
        << myVariable
        << "\n";
 
    // выводим на консоль адрес &myVariable:
    std::cout
        << &myVariable; // выводится то же самый адрес ячейки памяти
 
    return 0;
}
Добавлено через 1 минуту
P.S. Надо убегать. Домой приду, допишу, что и как и почему.
0
gru74ik
Модератор
Эксперт CЭксперт С++
4189 / 1837 / 198
Регистрация: 20.02.2013
Сообщений: 4,976
Записей в блоге: 21
08.09.2016, 18:40 #3
qppq, продолжаем.
Когда ты пишешь в прототипе функции такое:
C++
1
int* setPrice();
int* значит, что возвращаемым значением будет указатель. То есть, в реализации функции
C++
1
2
3
4
5
6
int* doSomething()
{
    // some code here
 
    return someItem;
}
всё, что после оператора return, то есть someItem, вопринимается компилятором как адрес, по которому лежит что-то, что следует воспринимать как значение типа int. Именно это и означает указатель. Это своеобразная команда компилятору: иди туда (по такому-то адресу) и то, что там найдёшь, интерпретируй как данные заданного типа (в нашем случае - int).
Чтобы было понятнее, вот картинка из книжки Стивена Праты:
1
Миниатюры
Нюансы синтаксиса и семантики: ссылки, указатели и массивы в качестве аргументов функций  
gru74ik
Модератор
Эксперт CЭксперт С++
4189 / 1837 / 198
Регистрация: 20.02.2013
Сообщений: 4,976
Записей в блоге: 21
08.09.2016, 18:56 #4
И кстати, да, рекомендую почитать про указатели вышеупомянутую книжку (Глава 4, стр.166).

Добавлено через 13 минут
Ещё раз, для закрепления.

Звёздочка для указателей пишется в трёх случаях:
  1. Когда Вы объявляете указатель, например:
    C++
    1
    
    int* pointerToInteger; // объявление указателя
  2. Когда Вы пишете в прототипе функции, что возвращаемое значение - указатель, например:
    C++
    1
    
    int* doSomething(); // прототип функции, возвращающей указатель
  3. Когда Вы разыменовываете указатель (получаетете значение переменной, на которую указатель указывает), например:
    C++
    1
    
    std::cout << *pointerToInteger; // разыменование указателя (получение значения)
0
qppq
11 / 11 / 2
Регистрация: 31.08.2016
Сообщений: 163
Завершенные тесты: 1
08.09.2016, 22:50  [ТС] #5
Цитата Сообщение от gru74ik Посмотреть сообщение
всё, что после оператора return вопринимается компилятором как адрес, по которому лежит что-то
вот именно, и все же в этом методе
C++
1
2
3
4
5
6
char* setJanr()
 {
    cout<<"Vvedite janr:";
    cin>>janr;
    return janr;
 }
тип возвращаемого char* , return дает просто char массива , почему компилятор не ругается?,
хотя вот тут нашел негласное правило
Цитата Сообщение от Убежденный Посмотреть сообщение
Как известно, при передаче массива в функцию он превращается в указатель.
указатель на первый член массива
0
gru74ik
Модератор
Эксперт CЭксперт С++
4189 / 1837 / 198
Регистрация: 20.02.2013
Сообщений: 4,976
Записей в блоге: 21
09.09.2016, 08:01 #6
qppq, вот Вам ещё одна ссылка, чтобы лучше вникнуть в работу ссылок и указателей.

qppq, с массивами и указателями тут чутка сложнее. Дело в том, что массив не является объектом первого класса (first class citizen), поэтому в функцию передают не массив, а указатель на первый элемент массива:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
char* doSomething( char* cstr ) // аргумент функции - указатель
{
    // some code
 
    return cstr;
}
 
char* doSomeStrangeThings( char cstr[] ) // аргумент функции - тоже указатель!
{
    // some code
 
    return cstr;
}
А имя массива, ЕМНИП, неявно кастуется к указателю на первый элемент массива (если где-то в формулировках ошибся, корифеи меня пусть поправят). То есть cstr - это то же самое, что и &cstr[0]:
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
#include <iostream>
 
char* setGenre( char genre[] ) //синтаксис как у массивов, но это не массив, это указатель!
{
    std::cout << "\nEnter genre: ";
    std::cin >> genre;
 
    return genre;
}
 
int main()
{
    const int CSTR_SIZE = 20;
    char cstr[CSTR_SIZE];
 
    std::cout
        << "User-selected genre is "
        << setGenre( cstr );
 
    std::cout
        << "User-selected genre is "
        << setGenre( &cstr[0] );
 
    return 0;
}
Опять же, очень подробно об этом у Стивена Праты (7 глава, стр. 318).
0
Миниатюры
Нюансы синтаксиса и семантики: ссылки, указатели и массивы в качестве аргументов функций  
HelicopterK52
680 / 205 / 28
Регистрация: 27.07.2016
Сообщений: 474
Завершенные тесты: 1
09.09.2016, 08:15 #7
Цитата Сообщение от qppq Посмотреть сообщение
и все же в этом методе
На неизвестно что такое janr.
Цитата Сообщение от qppq Посмотреть сообщение
а вот здесь для int надо
и здесь нам тоже ничего неизвестно.
И вообще не ясно чего Вы хотите добиться.
Возможно, если Вы дадите компилируемый код,
в котором укажите что Вам конкретно не ясно и
сформулируете это более конкретно, то Вам помогут.
А так это пока что звучит так, - "Зачем здесь я взял ведро, а здесь не взял?".
0
gru74ik
Модератор
Эксперт CЭксперт С++
4189 / 1837 / 198
Регистрация: 20.02.2013
Сообщений: 4,976
Записей в блоге: 21
09.09.2016, 08:23 #8
HelicopterK52, это моя вина. Поправил заглавное сообщение.
1
DrOffset
7351 / 4451 / 1009
Регистрация: 30.01.2014
Сообщений: 7,292
09.09.2016, 09:32 #9
Цитата Сообщение от qppq Посмотреть сообщение
хотя вот тут нашел негласное правило
Прям-таки негласное
Это правило регламентируется стандартом языка.

В С++ и С есть два типа, которые неявно трансформируются в указатель: массив и функция. В С++ правила описаны в разделах стандарта 4.1 Array-to-pointer conversion и 4.2 Function-to-pointer conversion соответственно.
1
qppq
11 / 11 / 2
Регистрация: 31.08.2016
Сообщений: 163
Завершенные тесты: 1
09.09.2016, 09:34  [ТС] #10
0
gru74ik
Модератор
Эксперт CЭксперт С++
4189 / 1837 / 198
Регистрация: 20.02.2013
Сообщений: 4,976
Записей в блоге: 21
09.09.2016, 09:38 #11
qppq, и ещё один нюанс, который часто путает новичков.
Запомните: если в прототипе функции в качестве аргумента используется указатель, то в вызове функции Вы должны подставить в качестве принимаемого значения адрес:
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
26
27
28
29
#include <iostream>
 
// прототип функции:
char* setGenre( char* genre ); // в качестве аргумента используется указатель
 
int main()
{
    const int CSTR_SIZE = 20;
    char cstr[CSTR_SIZE];
 
    std::cout
        << "User-selected genre is "
        << setGenre( cstr ); // вызов функции: в функцию подсовывается адрес
 
    std::cout
        << "User-selected genre is "
        << setGenre( &cstr[0] ); // вызов функции: в функцию подсовывается адрес
 
    return 0;
}
 
// определение функции:
char* setGenre( char *genre )
{
    std::cout << "\nEnter genre: ";
    std::cin >> genre;
 
    return genre; // возвращаемое значение тоже адрес
}
0
qppq
11 / 11 / 2
Регистрация: 31.08.2016
Сообщений: 163
Завершенные тесты: 1
09.09.2016, 10:13  [ТС] #12
как при объявлении:
C++
1
char* genre = &cstr[0]
то есть левая часть в определении функции, правая при вызове, так?

а вот если определение функции стояло перед main, то прототип не обязателен?
0
gru74ik
Модератор
Эксперт CЭксперт С++
4189 / 1837 / 198
Регистрация: 20.02.2013
Сообщений: 4,976
Записей в блоге: 21
09.09.2016, 12:39 #13
Цитата Сообщение от qppq Посмотреть сообщение
левая часть в определении функции, правая при вызове, так?
Так. Смысл-то тот же: значение, которым инициализируется указатель - это адрес. Указатель хранит в себе адрес.

Цитата Сообщение от qppq Посмотреть сообщение
если определение функции стояло перед main, то прототип не обязателен?
Не обязателен.

Добавлено через 2 часа 15 минут
Начните уже дружить, что ли...
0
qppq
11 / 11 / 2
Регистрация: 31.08.2016
Сообщений: 163
Завершенные тесты: 1
09.09.2016, 13:35  [ТС] #14
Цитата Сообщение от gru74ik Посмотреть сообщение
Опять же, очень подробно об этом у Стивена Праты
отредактировать бы эту книжку, очепятки присутствуют однако, будьте бдительны! Вцелом 5 баллов.
0
gru74ik
Модератор
Эксперт CЭксперт С++
4189 / 1837 / 198
Регистрация: 20.02.2013
Сообщений: 4,976
Записей в блоге: 21
09.09.2016, 14:30 #15
Цитата Сообщение от qppq Посмотреть сообщение
очепятки присутствуют
Ну, как бы, вот:
Цитата Сообщение от Роберт Антон Уилсон
Как доказал Клод Шеннон в 1948 году, «шум» попадает в любой канал коммуникации при любом устройстве последнего.
Очипятки будут в любой книге, как бы ты её не вычитывал, как бы не редактировал.
0
09.09.2016, 14:30
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.09.2016, 14:30
Привет! Вот еще темы с ответами:

Указатели, адресная арифметика и передача аргументов функций по значению и по ссылке - C++
Подскажите, пожалуйста, как решить такую задачу вручную. На экзамене предложат задание такого типа НА БУМАГЕ, и надо будет написать, что...

Ссылки, указатели и массивы - C++
Что-то не лезут в голову указатели и ссылки. Вот как я всё понимаю: Ссылки. Ссылочные переменные ссылаются на адрес уже существующих...

C++ | Правильно ли я сделал задание | Массивы | Указатели и Ссылки - C++
Вообще прога должна показывать самое большое число по модулю, что она и делает, но меня интересует другой вопрос, правильно ли я...

Нюансы синтаксиса: использование using - C++
Всем доброе утро, вообщем хотел спросить давно уже, а что делает using, помимо вот такого его применения using std::cout; //... ...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru