Помощь - Поиск - Пользователи - Календарь
Полная версия: Передача и возврат ссылок из функции
Форум «Всё о Паскале» > Современный Паскаль и другие языки > Ада и другие языки
Rocket
Объявил структуру Student, которая содержит четыре поля(фамилию, имя и отчество студента и год рождения), при этом строковые значения храню в виде массивов,а не указателей. Описал и инициализировал переменную st типа Student фамилией, именем и отчеством, не задавая год его рождения.


#include <iostream>
using namespace std;

struct Student {
char Surname;
char Name;
char Patronymic;
int Year;
} ;

Student& trunc(Student& X)
{
return X;
}

int main()
{ Student st;
st.Surname='Ivanov';
st.Name='Ivan';
st.Patronymic='Ivanovich';
trunc(st);
}



Проблемы возникли с написанием функции Student& trunc(Student& X), которая сокращает в структуре
имя и отчество до инициалов (с точкой) и возвращает структуру X. Помогите пожалуйста с реализацией этой функции! Проверка работы функции нужно осуществить, передав ей переменную st, и воспользоваться возвращаемым значением функции для задания года рождения.
volvo
Проблема у тебя начинается с того, что ты пытаешься одному символу присвоить значение строки (и Surname, и Name, и Patronymic - это char-ы, а не строки)...

Кстати, компилятор тебя предупреждал об этом, почему это было проигнорировано?

Ну, и свою попытку - в студию...
Rocket
Цитата(volvo @ 16.03.2008 14:53) *

Проблема у тебя начинается с того, что ты пытаешься одному символу присвоить значение строки (и Surname, и Name, и Patronymic - это char-ы, а не строки)...

Кстати, компилятор тебя предупреждал об этом, почему это было проигнорировано?

Ну, и свою попытку - в студию...


 
Student& trunc(Student& X)
{ char s1,s2;
s1=X.Name;
s2=s1[0]+'.'+'\0'
return X;
}



А саму структуру задать так задавть:


struct Student {
char Surname[255];
char Name[255];
char Patronymic[255];
int Year;
} ;


?
volvo
Цитата
 char s1,s2;
s1=X.Name;
Ну, ты же опять совершаешь ту же самую ошибку... С массивами символов надо работать, а не с символами, чтоб строку представить... Кроме того, строку нельзя копировать через "=", нужно использовать для этого strcpy...

Кстати, тебе обязательно извращаться с возвратом ссылки? Не проще вернуть новый объект из функции:

struct Student {
Student(const char *sn, const char *n, const char *p) {
strcpy(Surname, sn); strcpy(Name, n); strcpy(Patronymic, p);
}

char Surname[255]; // Вообще-то лучше было бы описать все как char * и выделить память
char Name[255];
char Patronymic[255];

int Year;
};

Student trunc(Student& X)
{
// Исправлено, раньше был не совсем корректный вариант...
char n[4], pn[4];
sprintf(n, "%c.%c", X.Name[0], (char)0);
sprintf(pn, "%c.%c", X.Patronymic[0], (char)0);
return Student(X.Surname, n, pn);
}

int main()
{
Student st("Ivanov", "Ivan", "Ivanovich");
Student s = trunc(st);
cout << s.Surname << " " << s.Name << " " << s.Patronymic << endl;
return 0;
}


?
Rocket
Цитата(volvo @ 16.03.2008 15:24) *


struct Student {
Student(const char *sn, const char *n, const char *p) {
strcpy(Surname, sn); strcpy(Name, n); strcpy(Patronymic, p);
}

char Surname[255]; // Вообще-то лучше было бы описать все как char * и выделить память
char Name[255];
char Patronymic[255];

int Year;
};

Student trunc(Student& X)
{
// Исправлено, раньше был не совсем корректный вариант...
char n[4], pn[4];
sprintf(n, "%c.%c", X.Name[0], (char)0);
sprintf(pn, "%c.%c", X.Patronymic[0], (char)0);
return Student(X.Surname, n, pn);
}

int main()
{
Student st("Ivanov", "Ivan", "Ivanovich");
Student s = trunc(st);
cout << s.Surname << " " << s.Name << " " << s.Patronymic << endl;
return 0;
}




Так нужно всё-таки реализовать финкцию "Student& trunc(Student& X)", и чтобы возращалась структура Х, при этом можно было задать год, воспользовавшись возвращаемым значением функции.
И ещё два вопроса:
1. Возможно реализовать без использования конструктора?
2. Как работает "sprintf"?
volvo
Цитата
Возможно реализовать без использования конструктора?
"Возможно ездить на автомобиле задним ходом?" Возможно, но не все же время! Далеко не уедешь. Вот так же и здесь: если ты используешь С++ - так используй, его. А нужен непонятно как урезанный функционал - так пиши на чистых Сях, без конструкторов, ссылок и многих других вещей...

Цитата
Как работает "sprintf"?
Точно так же, как и printf, только печатает в строку, заданную первым параметром. В MSDN написано...

Цитата
Так нужно всё-таки реализовать финкцию "Student& trunc(Student& X)", и чтобы возращалась структура Х
Чтоб возвращалась "структура X" надо делать так, как я написал выше. А то, что хочешь ты - это сделать, чтобы возвращалась "ссылка на структуру X", пойми это наконец! Отсюда до ошибки - одно движение. Ну, извращайся, дело твое:
Student& trunc(Student& X)
{
sprintf(X.Name, "%c.%c", X.Name[0], (char)0);
sprintf(X.Patronymic, "%c.%c", X.Patronymic[0], (char)0);
return X;
}

int main()
{
Student st("Ivanov", "Petr", "Alekseevich");
st.Year = 1990;

trunc(st).Year = 1970; // Можно даже не запоминать результат...
cout << st.Surname << " " << st.Name << " " << st.Patronymic << " " << st.Year << endl;
return 0;
}

Rocket
Цитата(volvo @ 16.03.2008 16:52) *

Отсюда до ошибки - одно движение. Ну, извращайся, дело твое:

Да так в задание написано. Тут ещё нужно проверить работу функции, если:
i) структура передается и возвращается по ссылке
ii) структура передается в функцию по ссылке, а возвращается по значению
iii) структура передается по значению, а возвращается по ссылке
iv) и передача, и возврат из функции производятся по значению


Student& trunc(Student& X)
{
sprintf(X.Name, "%c.%c", X.Name[0], (char)0);
sprintf(X.Patronymic, "%c.%c", X.Patronymic[0], (char)0);
return X;
}

int main()
{
Student st("Ivanov", "Petr", "Alekseevich");
st.Year = 1990;

trunc(st).Year = 1970; // Можно даже не запоминать результат...
cout << st.Surname << " " << st.Name << " " << st.Patronymic << " " << st.Year << endl;
return 0;
}

Это, надо понимать, первый пункт. Проблема в том, что не сокращается имя и отчество...
volvo
Цитата
Проблема в том, что не сокращается имя и отчество...
Ты мою подпись читал внимательно? Перечитай еще раз, особенно то, что выделено красным...

Смотри сюда:
Rocket
Цитата(volvo @ 16.03.2008 18:18) *

Ты мою подпись читал внимательно? Перечитай еще раз, особенно то, что выделено красным...

Смотри сюда:

Всё работает! Нашел свою ошибку...Большое спасибо! good.gif
volvo
Цитата(Rocket @ 16.03.2008 16:16) *
ii) структура передается в функцию по ссылке, а возвращается по значению
Это тоже уже было - см. четвертый пост.

Цитата(Rocket @ 16.03.2008 16:16) *
iii) структура передается по значению, а возвращается по ссылке
Вот тут будет засада:
Student& trunc3(Student X) // передаем по значению, возвращаем ссылку
{
cout << "just before return" << endl;
sprintf(X.Name, "%c.%c", X.Name[0], (char)0);
sprintf(X.Patronymic, "%c.%c", X.Patronymic[0], (char)0);
return X;
}
, потому как будет создаваться временный объект, и здесь-то точно не будет сокращаться имя и отчество. Для того, чтобы поймать создание временного объекта - опиши еще один конструктор:
struct Student {
// ...

Student(Student &s) { // вот этот
cout << "X(X&) constructor" << endl;
}

// ...
};
, и запусти программу с trunc3...

Цитата(Rocket @ 16.03.2008 16:16) *

Да так в задание написано. Тут ещё нужно проверить работу функции, если:iv) и передача, и возврат из функции производятся по значению
А здесь вообще дважды будет создаваться временный объект.

Я не понял, тебе что, нужны 4 разные функции, которые работали бы для 4-х пунктов задания? Или прото написать одну и проверить на ней остальные варианты?
Rocket
Цитата(volvo @ 16.03.2008 19:29) *


Я не понял, тебе что, нужны 4 разные функции, которые работали бы для 4-х пунктов задания? Или прото написать одну и проверить на ней остальные варианты?

Да это нужно на одной все варианты проверить, когда будут изменятся поля, когда нет. В общем разобрался я. Ещё раз спасибо за помощь! smile.gif
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.