Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.50/4: Рейтинг темы: голосов - 4, средняя оценка - 4.50
39 / 34 / 10
Регистрация: 31.08.2016
Сообщений: 330
1

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

08.09.2016, 14:30. Просмотров 719. Ответов 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
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
08.09.2016, 14:30
Ответы с готовыми решениями:

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

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

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

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

14
Эксперт CЭксперт С++
5047 / 2230 / 330
Регистрация: 20.02.2013
Сообщений: 5,600
Записей в блоге: 24
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
Эксперт CЭксперт С++
5047 / 2230 / 330
Регистрация: 20.02.2013
Сообщений: 5,600
Записей в блоге: 24
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
Миниатюры
Нюансы синтаксиса и семантики: ссылки, указатели и массивы в качестве аргументов функций  
Эксперт CЭксперт С++
5047 / 2230 / 330
Регистрация: 20.02.2013
Сообщений: 5,600
Записей в блоге: 24
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
39 / 34 / 10
Регистрация: 31.08.2016
Сообщений: 330
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
Эксперт CЭксперт С++
5047 / 2230 / 330
Регистрация: 20.02.2013
Сообщений: 5,600
Записей в блоге: 24
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
Миниатюры
Нюансы синтаксиса и семантики: ссылки, указатели и массивы в качестве аргументов функций  
823 / 247 / 34
Регистрация: 27.07.2016
Сообщений: 497
Записей в блоге: 1
09.09.2016, 08:15 7
Цитата Сообщение от qppq Посмотреть сообщение
и все же в этом методе
На неизвестно что такое janr.
Цитата Сообщение от qppq Посмотреть сообщение
а вот здесь для int надо
и здесь нам тоже ничего неизвестно.
И вообще не ясно чего Вы хотите добиться.
Возможно, если Вы дадите компилируемый код,
в котором укажите что Вам конкретно не ясно и
сформулируете это более конкретно, то Вам помогут.
А так это пока что звучит так, - "Зачем здесь я взял ведро, а здесь не взял?".
0
Эксперт CЭксперт С++
5047 / 2230 / 330
Регистрация: 20.02.2013
Сообщений: 5,600
Записей в блоге: 24
09.09.2016, 08:23 8
HelicopterK52, это моя вина. Поправил заглавное сообщение.
1
13890 / 7424 / 1761
Регистрация: 30.01.2014
Сообщений: 12,420
09.09.2016, 09:32 9
Цитата Сообщение от qppq Посмотреть сообщение
хотя вот тут нашел негласное правило
Прям-таки негласное
Это правило регламентируется стандартом языка.

В С++ и С есть два типа, которые неявно трансформируются в указатель: массив и функция. В С++ правила описаны в разделах стандарта 4.1 Array-to-pointer conversion и 4.2 Function-to-pointer conversion соответственно.
1
39 / 34 / 10
Регистрация: 31.08.2016
Сообщений: 330
09.09.2016, 09:34  [ТС] 10
0
Эксперт CЭксперт С++
5047 / 2230 / 330
Регистрация: 20.02.2013
Сообщений: 5,600
Записей в блоге: 24
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
39 / 34 / 10
Регистрация: 31.08.2016
Сообщений: 330
09.09.2016, 10:13  [ТС] 12
как при объявлении:
C++
1
char* genre = &cstr[0]
то есть левая часть в определении функции, правая при вызове, так?

а вот если определение функции стояло перед main, то прототип не обязателен?
0
Эксперт CЭксперт С++
5047 / 2230 / 330
Регистрация: 20.02.2013
Сообщений: 5,600
Записей в блоге: 24
09.09.2016, 12:39 13
Цитата Сообщение от qppq Посмотреть сообщение
левая часть в определении функции, правая при вызове, так?
Так. Смысл-то тот же: значение, которым инициализируется указатель - это адрес. Указатель хранит в себе адрес.

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

Добавлено через 2 часа 15 минут
Начните уже дружить, что ли...
0
39 / 34 / 10
Регистрация: 31.08.2016
Сообщений: 330
09.09.2016, 13:35  [ТС] 14
Цитата Сообщение от gru74ik Посмотреть сообщение
Опять же, очень подробно об этом у Стивена Праты
отредактировать бы эту книжку, очепятки присутствуют однако, будьте бдительны! Вцелом 5 баллов.
0
Эксперт CЭксперт С++
5047 / 2230 / 330
Регистрация: 20.02.2013
Сообщений: 5,600
Записей в блоге: 24
09.09.2016, 14:30 15
Цитата Сообщение от qppq Посмотреть сообщение
очепятки присутствуют
Ну, как бы, вот:
Цитата Сообщение от Роберт Антон Уилсон
Как доказал Клод Шеннон в 1948 году, «шум» попадает в любой канал коммуникации при любом устройстве последнего.
Очипятки будут в любой книге, как бы ты её не вычитывал, как бы не редактировал.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.09.2016, 14:30

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

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

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

Указатели, адресная арифметика и передача аргументов функций по значению и по ссылке
Подскажите, пожалуйста, как решить такую задачу вручную. На экзамене предложат задание такого типа...

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


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

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

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