Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.09.2010, 19:16   #1
fs444
Форумчанин
 
Регистрация: 18.08.2009
Сообщений: 289
По умолчанию Задача на указатели: правильно ли я понял условие?

Есть задание
Цитата:
Решите следующие задачи. Полагайте, что беззнаковые целые хранятся в 2 байтах, и
что начальный адрес массива находится в ячейке памяти 1002500.
a) Объявите массив values типа unsigned int с 5 элементами и присвойте элементам на-
чальные значения в виде четных чисел от 2 до 10. Полагайте, что определена символи-
ческая константа SIZE, равная 5.
b) Объявите указатель vPtr, который указывает на объект типа unsigned int.
c) Напечатайте элементы массива values, используя запись с индексом массива. Ис-
пользуйте структуру for и считайте, что целая управляющая переменная i уже была
объявлена.
Я написал такой код:
Код:
#include<iostream>
using namespace std;
#include<windows>

int main()
{
   const size = 5;
   unsigned int values[size] = {2, 4, 6, 8, 10};
   unsigned int *vPtr = &values;
   int i;

   for (i = 0; i <= size; i++)
   {
      cout << "values[" << i << "] = " << values[i] << endl;
   }


   system("pause");
   return 0;
}
Получаю ошибку
Цитата:
[C++ Error] N5_9_P405.cpp(10): E2034 Cannot convert 'unsigned int ( *)[5]' to 'unsigned int *'
[C++ Warning] N5_9_P405.cpp(21): W8004 'vPtr' is assigned a value that is never used
1) Не могу преобразовать массив (имя которого является указателем на его первый элемент, так?) в указатель. Чуствую, что где то здесь
Код:
unsigned int *vPtr = &values;
сделал неправильно. А задании написано:
Цитата:
b) Объявите указатель vPtr, который указывает на объект типа unsigned int.
Может, "объект типа unsigned int" - это не конкретно массив values, а что-то другое?
fs444 вне форума Ответить с цитированием
Старый 01.09.2010, 19:30   #2
f.hump
C/C++, Asm
Участник клуба
 
Аватар для f.hump
 
Регистрация: 02.03.2010
Сообщений: 1,323
По умолчанию

Код:
int main()
{
   const size = 5;
   unsigned int values[] = {2, 4, 6, 8, 10}, *vPtr = values;
   int i;

   for (i = 0; i < size; i++)
   {
      cout << "values[" << i << "] = " << values[i] << endl;
   }


   system("pause");
   return 0;
}
f.hump вне форума Ответить с цитированием
Старый 02.09.2010, 12:02   #3
atenon
Форумчанин
 
Регистрация: 05.12.2009
Сообщений: 253
По умолчанию

Цитата:
Может, "объект типа unsigned int" - это не конкретно массив values, а что-то другое?
Судя по заданию решение такое:
Код:
unsigned int *vPtr;
Что касается кода то:
1.Так как имя массива это есть указатель на первый элемент массива то код
Код:
unsigned int *vPtr = &values;
дословно можно расшифровать так, присвоить указателю vPtr адрес ячейки которая содержит адрес 1 го элемента массива. Для корректной работы программы нужно убрать операцию взятия адреса.
2.
Код:
 const size = 5;
Правильно будет
Код:
const int size = 5;
3. Цикл
Код:
 for (i = 0; i <= size; i++)
выходит за границы массива size принимает значение 5. Индекс последнего элемента массива 4.
Приходится бежать со всех ног, чтобы только остаться на том же месте! Если хочешь попасть в другое место, тогда нужно бежать по меньшей мере вдвое быстрее! Льюис Кэрол

Последний раз редактировалось atenon; 02.09.2010 в 12:09.
atenon вне форума Ответить с цитированием
Старый 02.09.2010, 23:22   #4
fs444
Форумчанин
 
Регистрация: 18.08.2009
Сообщений: 289
По умолчанию

Доделал задание до конца, но есть опасения, что каша получилась =) Проверьте, пожалуйста.
Полный текст задания:
Цитата:
Решите следующие задачи. Полагайте, что беззнаковые целые хранятся в 2 байтах, и
что начальный адрес массива находится в ячейке памяти 1002500.
a) Объявите массив values типа unsigned int с 5 элементами и присвойте элементам на-
чальные значения в виде четных чисел от 2 до 10. Полагайте, что определена символи-
ческая константа SIZE, равная 5.
b) Объявите указатель vPtr, который указывает на объект типа unsigned int.
c) Напечатайте элементы массива values, используя запись с индексом массива. Ис-
пользуйте структуру for и считайте, что целая управляющая переменная i уже была
объявлена.
d) Укажите два разных оператора, которые присваивают начальный адрес массива
address переменной указателю vPtr.
e) Напечатайте элементы массива values, используя запись указатель-смещение.
f) Напечатайте элементы массива values, используя запись указатель-смещение с име-
нем массива как указателем.
g) Напечатайте элементы массива values, используя индексацию указателя на массив.
h) Сошлитесь на элемент 5 массива values, используя запись с индексом массива, за-
пись с именем массива как указателем, запись с индексом указателя и запись указа-
тель-смещение.
i) На какой адрес ссылается выражение vPtr + 3? Какое значение хранится в этой
ячейке?
j) Предполагая, что vPtr указывает на values[4], укажите, на какой адрес ссылается
выражение vPtr *-= 4. Какое значение хранится в этой ячейке?
Код:
#include<iostream>
using namespace std;
#include<windows>

char* rt(char* str)
{
    char* buf = new char[strlen(str) + 1];
    CharToOemA(str, buf);
    return buf;
}

int main()
{
   const size = 5;
   unsigned int values[size] = {2, 4, 6, 8, 10};
   unsigned int *vPtr = values;
   int i;
   int adress[5];
   int *aPtr;
   int offset;
   unsigned int *sPtr;

   //печатаем массив values, используя запись с индексом массива
   cout << rt("Печать массива values, используя запись с индексом массива") << endl;
   for (i = 0; i < size; i++)
   {
      cout << "values[" << i << "] = " << values[i] << endl;
   }
   // ПУНКТ "d"
   //присваиваем адрес массива adress указателю vPtr
   aPtr = adress;
   aPtr = &adress[0];

   // ПУНКТ "e"
   //печатаем массив values, используя запись указатель-смещение
   cout << endl << rt("Печать массива values, используя запись указатель-смещение") << endl;
   for (offset = 0; offset < 5; offset++)
   {
      cout << "*(vPtr + " << offset << ") = "
           << *(vPtr + offset) << "\n";
   }

   // ПУНКТ "f"
   //печатаем массив values, используя запись указатель-смещение с именем массива как указатель
   cout << endl << rt("Печать массива values, используя запись указатель-смещение c именем массива как указатель") << endl;
   for (offset = 0; offset < 5; offset++)
   {
      cout << "*(values + " << offset << ") = "
           << *(values + offset) << "\n";
   }

   // ПУНКТ "g"
   //печатаем массив values, используя индексацию указателя на массив
   cout << endl << rt("Печать массива values, используя индексацию указателя на массив") << endl;
   for (i = 0; i < 5; i++)
      cout << "vPtr[" << i << "] = " << vPtr[i] << "\n";

   // ПУНКТ "h"
   //ссылаемся на values[5], используя запись с индексом массива
   cout << endl << rt("Ссылаемся на values[5], используя запись с индексом массива") << endl;
   cout << "values[5]: " << values[5] << endl;
   //ссылаемся на values[5], используя запись с именем массива как указателем
   cout << rt("Ссылаемся на values[5], используя запись с именем массива как указателем") << endl;
   cout << "values[5]: " << *(values + 5) << endl;
   //ссылаемся на values[5], используя запись с индексом указателя
   cout << rt("Ссылаемся на values[5], используя запись с индексом указателя") << endl;
   cout << "values[5]: " << vPtr[5] << endl;
   //ссылаемся на values[5], используя запись указатель-смещение
   cout << rt("Ссылаемся на values[5], используя запись указатель-смещение") << endl;
   cout << "values[5]: " << *(vPtr + 5) << endl;

   // ПУНКТ "i"
   cout << endl << "vPtr + 3: " << vPtr + 3 << endl << endl;

   // ПУНКТ "j"
   *vPtr = values[4];
   cout << "vPtr -= 4: " << (vPtr -= 4) << endl;
   //вроде по-другому как-то сделать надо, но я только на это додумался =)
   cout << rt("В (vPtr -= 4) хранится значение: ") << values[0] << endl;

   system("pause");
   return 0;
}
fs444 вне форума Ответить с цитированием
Старый 02.09.2010, 23:22   #5
fs444
Форумчанин
 
Регистрация: 18.08.2009
Сообщений: 289
По умолчанию

Выводит следующее:

Цитата:
Печать массива values, используя запись с индексом массива
values[0] = 2
values[1] = 4
values[2] = 6
values[3] = 8
values[4] = 10

Печать массива values, используя запись указатель-смещение
*(vPtr + 0) = 2
*(vPtr + 1) = 4
*(vPtr + 2) = 6
*(vPtr + 3) = 8
*(vPtr + 4) = 10

Печать массива values, используя запись указатель-смещение c именем массива как
указатель
*(values + 0) = 2
*(values + 1) = 4
*(values + 2) = 6
*(values + 3) = 8
*(values + 4) = 10

Печать массива values, используя индексацию указателя на массив
vPtr[0] = 2
vPtr[1] = 4
vPtr[2] = 6
vPtr[3] = 8
vPtr[4] = 10

Ссылаемся на values[5], используя запись с индексом массива
values[5]: 4206644
Ссылаемся на values[5], используя запись с именем массива как указателем
values[5]: 4206644
Ссылаемся на values[5], используя запись с индексом указателя
values[5]: 4206644
Ссылаемся на values[5], используя запись указатель-смещение
values[5]: 4206644

vPtr + 3: 1245036

vPtr -= 4: 1245008
В (vPtr -= 4) хранится значение: 10
Вопрос только один: не понимаю, почему "values[0]" выдает 10? Ведь первый элемент этого массива - "2".
fs444 вне форума Ответить с цитированием
Старый 02.09.2010, 23:51   #6
Indian
Форумчанин
 
Регистрация: 23.02.2010
Сообщений: 107
По умолчанию

Код:
vPtr=&values[4];
...
cout << rt("В (vPtr -= 4) хранится значение: ") << *vPtr << endl;
Indian вне форума Ответить с цитированием
Старый 04.09.2010, 09:33   #7
atenon
Форумчанин
 
Регистрация: 05.12.2009
Сообщений: 253
По умолчанию

Элемент массива values[5] не существует, в результате вместо значения выводится мусор. Для того чтобы
Цитата:
Сошлитесь на элемент 5 массива values
Нужно использовать values[4], так как нумерация массива начинается с нуля, а чтобы сослатся на 5-ый элемент массива применяется values[5] (примерно так я себе это представляю)
Цитата:
d) Укажите два разных оператора, которые присваивают начальный адрес массива
address переменной указателю vPtr.
Может быть нужно использовать new, malloc. Кстати вам повезло с преподом таких "ясных", и "четко поставленных задач" я еще не видел )))

// ПУНКТ "i"
cout<<"Адрес по которому хранится vPtr + 3 = "<< &*(vPtr + 3)<<endl;
cout << endl << "vPtr + 3: " << *(vPtr + 3) << endl << endl;
Приходится бежать со всех ног, чтобы только остаться на том же месте! Если хочешь попасть в другое место, тогда нужно бежать по меньшей мере вдвое быстрее! Льюис Кэрол

Последний раз редактировалось atenon; 04.09.2010 в 10:08.
atenon вне форума Ответить с цитированием
Старый 06.09.2010, 23:18   #8
fs444
Форумчанин
 
Регистрация: 18.08.2009
Сообщений: 289
По умолчанию

Цитата:
Может быть нужно использовать new, malloc
Попробую.

Цитата:
Кстати вам повезло с преподом таких "ясных", и "четко поставленных задач" я еще не видел )))
Всмысле, все объяснено хреново? =))

Цитата:
&*(vPtr + 3)
В чем смысл этой записи? & - символ, позволяющий получить адрес переменной. * - позволяет вытащить из указателя значение переменной на которую он указывает. Получается, мы значком & получаем значение переменной, на которую указывает (vPtr+3), а затем значком * получаем адрес, в котором хранится это значение?
fs444 вне форума Ответить с цитированием
Старый 07.09.2010, 06:34   #9
atenon
Форумчанин
 
Регистрация: 05.12.2009
Сообщений: 253
По умолчанию

Код:
В чем смысл этой записи? & - символ, позволяющий получить адрес переменной. * - позволяет вытащить из указателя значение переменной на которую он указывает. Получается, мы значком & получаем значение переменной, на которую указывает (vPtr+3), а затем значком * получаем адрес, в котором хранится это значение?
Немного напутали. Знак * имеет какбы двойственные функции:
1. С помощью его определяют указатели
2. Это операция разадресации или разыменования -обращение к переменной адрес которой содержится в указателе.
Знак & также может использоваться:
1. Как определение ссылки на переменную
2. Как операция взятия адреса.
Таким образом, этой частью *(vPtr+3) мы обращаемся к элементу массива,
а знак & возвращает нам адрес этого элемента.
Приходится бежать со всех ног, чтобы только остаться на том же месте! Если хочешь попасть в другое место, тогда нужно бежать по меньшей мере вдвое быстрее! Льюис Кэрол

Последний раз редактировалось atenon; 07.09.2010 в 06:37.
atenon вне форума Ответить с цитированием
Старый 07.09.2010, 14:03   #10
f.hump
C/C++, Asm
Участник клуба
 
Аватар для f.hump
 
Регистрация: 02.03.2010
Сообщений: 1,323
По умолчанию

2 fs444

Цитата:
Немного напутали. Знак * имеет какбы двойственные функции:
1. С помощью его определяют указатели
2. Это операция разадресации или разыменования -обращение к переменной адрес которой содержится в указателе.
Знак & также может использоваться:
1. Как определение ссылки на переменную
2. Как операция взятия адреса.
Таким образом, этой частью *(vPtr+3) мы обращаемся к элементу массива,
а знак & возвращает нам адрес этого элемента.
херня это все.

пишите как писали, просто vPtr+3. арифметика указателей одна из самых сильных и полезных тем с/с++.
f.hump вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
задача на с. указатели функции строки(хз как переделать) нонфактор Помощь студентам 1 12.01.2010 16:46
Указатели, задача по структуре Lees27 Общие вопросы C/C++ 2 22.11.2009 21:16
как правильно поставить условие ГОСЕАН Помощь студентам 5 27.04.2009 10:52
Паскаль, простая задача, тупое условие. Кагбе_Прогер Помощь студентам 2 24.11.2008 09:50
[C] Задача на указатели . Нужна помощь shtkuh Помощь студентам 1 26.01.2008 08:47