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

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

Восстановить пароль Регистрация
 
qppq
 Аватар для qppq
5 / 5 / 1
Регистрация: 31.08.2016
Сообщений: 96
Завершенные тесты: 1
08.09.2016, 14:30     Нюансы синтаксиса и семантики: ссылки, указатели и массивы в качестве аргументов функций #1
 Комментарий модератора 
Перенесено из этой темы.


Чтобы вернуть указатели почему вот здесь не надо приводить 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;
 }
только без помидоров
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.09.2016, 14:30     Нюансы синтаксиса и семантики: ссылки, указатели и массивы в качестве аргументов функций
Посмотрите здесь:

Указатели, адресная арифметика и передача аргументов функций по значению и по ссылке C++
Ссылки, указатели и массивы C++
Указатели на массивы в качестве аргументов C++
C++ Нюансы синтаксиса: что означает символ -> (указатели)
C++ Указатели или ссылки (в качестве аргументов функции) ?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
gru74ik
Модератор
 Аватар для gru74ik
3120 / 1346 / 167
Регистрация: 20.02.2013
Сообщений: 3,835
Записей в блоге: 17
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. Надо убегать. Домой приду, допишу, что и как и почему.
gru74ik
Модератор
 Аватар для gru74ik
3120 / 1346 / 167
Регистрация: 20.02.2013
Сообщений: 3,835
Записей в блоге: 17
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).
Чтобы было понятнее, вот картинка из книжки Стивена Праты:
Миниатюры
Нюансы синтаксиса и семантики: ссылки, указатели и массивы в качестве аргументов функций  
gru74ik
Модератор
 Аватар для gru74ik
3120 / 1346 / 167
Регистрация: 20.02.2013
Сообщений: 3,835
Записей в блоге: 17
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; // разыменование указателя (получение значения)
qppq
 Аватар для qppq
5 / 5 / 1
Регистрация: 31.08.2016
Сообщений: 96
Завершенные тесты: 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 массива , почему компилятор не ругается?,
хотя вот тут нашел негласное правило
Цитата Сообщение от Убежденный Посмотреть сообщение
Как известно, при передаче массива в функцию он превращается в указатель.
указатель на первый член массива
gru74ik
Модератор
 Аватар для gru74ik
3120 / 1346 / 167
Регистрация: 20.02.2013
Сообщений: 3,835
Записей в блоге: 17
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).
Миниатюры
Нюансы синтаксиса и семантики: ссылки, указатели и массивы в качестве аргументов функций  
HelicopterK52
634 / 177 / 28
Регистрация: 27.07.2016
Сообщений: 475
Завершенные тесты: 1
09.09.2016, 08:15     Нюансы синтаксиса и семантики: ссылки, указатели и массивы в качестве аргументов функций #7
Цитата Сообщение от qppq Посмотреть сообщение
и все же в этом методе
На неизвестно что такое janr.
Цитата Сообщение от qppq Посмотреть сообщение
а вот здесь для int надо
и здесь нам тоже ничего неизвестно.
И вообще не ясно чего Вы хотите добиться.
Возможно, если Вы дадите компилируемый код,
в котором укажите что Вам конкретно не ясно и
сформулируете это более конкретно, то Вам помогут.
А так это пока что звучит так, - "Зачем здесь я взял ведро, а здесь не взял?".
gru74ik
Модератор
 Аватар для gru74ik
3120 / 1346 / 167
Регистрация: 20.02.2013
Сообщений: 3,835
Записей в блоге: 17
09.09.2016, 08:23     Нюансы синтаксиса и семантики: ссылки, указатели и массивы в качестве аргументов функций #8
HelicopterK52, это моя вина. Поправил заглавное сообщение.
DrOffset
6450 / 3824 / 885
Регистрация: 30.01.2014
Сообщений: 6,618
09.09.2016, 09:32     Нюансы синтаксиса и семантики: ссылки, указатели и массивы в качестве аргументов функций #9
Цитата Сообщение от qppq Посмотреть сообщение
хотя вот тут нашел негласное правило
Прям-таки негласное
Это правило регламентируется стандартом языка.

В С++ и С есть два типа, которые неявно трансформируются в указатель: массив и функция. В С++ правила описаны в разделах стандарта 4.1 Array-to-pointer conversion и 4.2 Function-to-pointer conversion соответственно.
qppq
 Аватар для qppq
5 / 5 / 1
Регистрация: 31.08.2016
Сообщений: 96
Завершенные тесты: 1
09.09.2016, 09:34  [ТС]     Нюансы синтаксиса и семантики: ссылки, указатели и массивы в качестве аргументов функций #10
gru74ik
Модератор
 Аватар для gru74ik
3120 / 1346 / 167
Регистрация: 20.02.2013
Сообщений: 3,835
Записей в блоге: 17
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; // возвращаемое значение тоже адрес
}
qppq
 Аватар для qppq
5 / 5 / 1
Регистрация: 31.08.2016
Сообщений: 96
Завершенные тесты: 1
09.09.2016, 10:13  [ТС]     Нюансы синтаксиса и семантики: ссылки, указатели и массивы в качестве аргументов функций #12
как при объявлении:
C++
1
char* genre = &cstr[0]
то есть левая часть в определении функции, правая при вызове, так?

а вот если определение функции стояло перед main, то прототип не обязателен?
gru74ik
Модератор
 Аватар для gru74ik
3120 / 1346 / 167
Регистрация: 20.02.2013
Сообщений: 3,835
Записей в блоге: 17
09.09.2016, 12:39     Нюансы синтаксиса и семантики: ссылки, указатели и массивы в качестве аргументов функций #13
Цитата Сообщение от qppq Посмотреть сообщение
левая часть в определении функции, правая при вызове, так?
Так. Смысл-то тот же: значение, которым инициализируется указатель - это адрес. Указатель хранит в себе адрес.

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

Добавлено через 2 часа 15 минут
Начните уже дружить, что ли...
qppq
 Аватар для qppq
5 / 5 / 1
Регистрация: 31.08.2016
Сообщений: 96
Завершенные тесты: 1
09.09.2016, 13:35  [ТС]     Нюансы синтаксиса и семантики: ссылки, указатели и массивы в качестве аргументов функций #14
Цитата Сообщение от gru74ik Посмотреть сообщение
Опять же, очень подробно об этом у Стивена Праты
отредактировать бы эту книжку, очепятки присутствуют однако, будьте бдительны! Вцелом 5 баллов.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.09.2016, 14:30     Нюансы синтаксиса и семантики: ссылки, указатели и массивы в качестве аргументов функций
Еще ссылки по теме:

C++ Константные указатели в качестве аргументов функций
C++ С++ Тема «Указатели и динамические массивы. Использование указателей в качестве аргументов функций»
C++ Нюансы синтаксиса и семантики: что такое rvalue и lvalue?

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

Или воспользуйтесь поиском по форуму:
gru74ik
Модератор
 Аватар для gru74ik
3120 / 1346 / 167
Регистрация: 20.02.2013
Сообщений: 3,835
Записей в блоге: 17
09.09.2016, 14:30     Нюансы синтаксиса и семантики: ссылки, указатели и массивы в качестве аргументов функций #15
Цитата Сообщение от qppq Посмотреть сообщение
очепятки присутствуют
Ну, как бы, вот:
Цитата Сообщение от Роберт Антон Уилсон
Как доказал Клод Шеннон в 1948 году, «шум» попадает в любой канал коммуникации при любом устройстве последнего.
Очипятки будут в любой книге, как бы ты её не вычитывал, как бы не редактировал.
Yandex
Объявления
09.09.2016, 14:30     Нюансы синтаксиса и семантики: ссылки, указатели и массивы в качестве аргументов функций
Ответ Создать тему
Опции темы

Текущее время: 02:58. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru