Суббота, 03 Декабря 2022, 22:23

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 2 из 4
  • «
  • 1
  • 2
  • 3
  • 4
  • »
Форум игроделов » Программирование » C/C++ » Массивы и метки в C++
Массивы и метки в C++
05142Дата: Вторник, 30 Августа 2011, 16:32 | Сообщение # 21
постоянный участник
Сейчас нет на сайте
Quote (Kornival)
Откуда новичкам, не знающим goto, знать что такое указатель?

Зачем новичкам не знающим что такое указатель говорить про массивы?


mecinvader

Сообщение отредактировал 05142 - Вторник, 30 Августа 2011, 16:45
noTformaTДата: Вторник, 30 Августа 2011, 16:33 | Сообщение # 22
Ukrainian independent game developer
Сейчас нет на сайте
Quote (05142)
Зачем новичкам не знающим что такое укащатель говорить про массивы?

а они как то связаны?


@noTformaT
05142Дата: Вторник, 30 Августа 2011, 16:47 | Сообщение # 23
постоянный участник
Сейчас нет на сайте
Quote (noTformaT)
а они как то связаны?

Ну да.
Code

int p[5];
// p - указатель, *p == p[0]


Я несовсем уверен в правильности ситаксиса, но в принципе всё так работает


mecinvader
noTformaTДата: Вторник, 30 Августа 2011, 17:14 | Сообщение # 24
Ukrainian independent game developer
Сейчас нет на сайте
05142, ммм, что то ты напутал.

@noTformaT
KornivalДата: Вторник, 30 Августа 2011, 17:18 | Сообщение # 25
The Witcher
Сейчас нет на сайте
для того, чтобы юзать массивы необязательно знать про указатели.
05142Дата: Вторник, 30 Августа 2011, 17:22 | Сообщение # 26
постоянный участник
Сейчас нет на сайте
noTformaT, ничего я не напутал.
Quote (Kornival)
для того, чтобы юзать массивы необязательно знать про указатели

необязательно, но новичку знать полезно будет


mecinvader
noTformaTДата: Вторник, 30 Августа 2011, 17:25 | Сообщение # 27
Ukrainian independent game developer
Сейчас нет на сайте
Quote (05142)
ничего я не напутал.

05142, цитата:

Чтобы создать в памяти новый массив, используется такая запись:
int m[10];
........массив практически всегда автоматически приводится к указателю на свой первый элемент. Поэтому в функцию, которая требует указатель, вполне законно передавать массив:
void MyFunc( int *arr );
MyFunc(m);

передавать массив, а не первый [0] элемент как у тебя.


@noTformaT


Сообщение отредактировал noTformaT - Вторник, 30 Августа 2011, 17:28
05142Дата: Вторник, 30 Августа 2011, 17:36 | Сообщение # 28
постоянный участник
Сейчас нет на сайте
noTformaT, я ничего не напутал. Почитай учебники по Си, или по плюсам. Я не говорил что первый элемент массива - указатель. Я говорил что имя массива - указатель на первый элемент массиваю Всё правильно.

mecinvader
froexДата: Вторник, 30 Августа 2011, 17:52 | Сообщение # 29
Руководитель Froexilize team
Сейчас нет на сайте
int array[100] - объявление массива на 100 элементов
int *a - объявление указателя на целое
a = array - с указателем "a" теперь можно работать как с массивом (инфа 100%)
a[60] - обращение к 61-му элементу массива (получение его значения)
a+60 - это адрес 61-го элемента массива в памяти

При передаче массива в функцию выгодней передавать указатель на него, либо ссылку, чтобы не прогонять через стек весь массив/не вызывать конструктор копирования/и т.п.
Допустим, заголовок функции:
void get_array(int *src)

Тогда передаём в функцию наш объявленный массив простым вызовом:
get_array(array)

Запись вида
get_array(*array)
означает, что мы сначала разыменовываем указатель array, т.е. мы передадим значение по адресу (array указывает на первый элемент массива. Разыменовав, получив значение первого элемента массива). Это не передача массива явно.

Добавлено (30.08.2011, 17:50)
---------------------------------------------
btw, загонять объявления в цикл с безусловных переходом недопустимо, т.к. оптимизация кода может "проглотит" недочет. Тогда все объявления будут требовать дополнительную память и располагаться по новым адресам. Т.к. цикл с безусловным переходом не имеет фактического тела цикла, а только формальное, то при "случайной" оптимизации компилятором кода будет пропущен вызов деструктора либо его вообще не будет создано до окончания фактического тела конструкции. Другими словами, будет засоряться память и может наступить переполнение.

Добавлено (30.08.2011, 17:52)
---------------------------------------------
И ещё - в моём примере выше указатели "a" и "array" содержат один и тот же адрес - указывают на одну и ту же область памяти.


Не превращайте форум в чат. Пишите более развернуто и понятно - всё равно вас попросят объяснить подробнее.
Алгоритмы, программирование, оптимизация, тестирование, ведение проектов.
Ищу художника, дизайнера, тестера, программистов С и С++
Обучаю процессам разработки и программированию.


Сообщение отредактировал froex - Вторник, 30 Августа 2011, 17:54
noTformaTДата: Вторник, 30 Августа 2011, 18:01 | Сообщение # 30
Ukrainian independent game developer
Сейчас нет на сайте
froex, http://www.gamedev.ru/code/faq/?id=3603

@noTformaT
froexДата: Вторник, 30 Августа 2011, 18:14 | Сообщение # 31
Руководитель Froexilize team
Сейчас нет на сайте
noTformaT, автор сам не знает, что пишет. Честно говорю.
Code
int a[4]  = { 1, 2, 3, 4 };
int *p = a; //неявное преобразование массива к указателю на его первый элемент.
p = p + 2; //с массивом такое не пройдёт.
p[-1] = 10; //этот указатель указывает теперь в середину массива, поэтому можно присваивать в отрицательные индексы.

комментирую по строкам:
1. Хотя бы знает, как инициализировать массив - то радует.
2. Это явное присваивание адресов во время инициализации указателя. Никаких преобразований нет.
3. http://gcup.ru/forum/62-16908-3#278994 - тут см. первую задачку. Там проходит, а у автора нет?
4. По стандарту в "-1"-ом элементе можно откопать размер массива. Автор не говорит, что int занимает 4 байта. Если структуры данных построенны в программе по стандарту (то компилятор решает, а не пользователь), то автор даёт указания смены размера. int занимает 4 байта, т.е. получается 2,5 целых чисел. Именно целых, т.к. указатель тычет на целое. Ладно, что автор не "а[-1]" так меняет, а то хз, куда бы пропали остальные 1,5 элемента массива.

Сохраню ссылку - вечером его дочитаю, на утро хорошо с улыбкой на утро ложиться баиньки.

Добавлено (30.08.2011, 18:14)
---------------------------------------------
btw, два кода идентичны:
Code
int main(int argc, char *argv[])

Code
int main(int argc, char **argv)


Не превращайте форум в чат. Пишите более развернуто и понятно - всё равно вас попросят объяснить подробнее.
Алгоритмы, программирование, оптимизация, тестирование, ведение проектов.
Ищу художника, дизайнера, тестера, программистов С и С++
Обучаю процессам разработки и программированию.


Сообщение отредактировал froex - Вторник, 30 Августа 2011, 18:19
KornivalДата: Вторник, 30 Августа 2011, 18:15 | Сообщение # 32
The Witcher
Сейчас нет на сайте
froex, речь шла не об этом, 05142 конечно прав, речь шла о том, где динамическое выделение памяти?

Добавлено (30.08.2011, 18:15)
---------------------------------------------
froex, речь шла не об этом, 05142 конечно прав, речь шла о том, где динамическое выделение памяти?

froexДата: Вторник, 30 Августа 2011, 18:18 | Сообщение # 33
Руководитель Froexilize team
Сейчас нет на сайте
Ах, да - соглашусь, что массив - это не указатель.

Добавлено (30.08.2011, 18:18)
---------------------------------------------
Kornival, может не так выразился... читай как "используется динамическая память". Опять же - читаем гугл, в чём различие между статической и динамической памятью. Я старался подробней описать ситуацию, когда возникает конфликт.


Не превращайте форум в чат. Пишите более развернуто и понятно - всё равно вас попросят объяснить подробнее.
Алгоритмы, программирование, оптимизация, тестирование, ведение проектов.
Ищу художника, дизайнера, тестера, программистов С и С++
Обучаю процессам разработки и программированию.
noTformaTДата: Вторник, 30 Августа 2011, 18:22 | Сообщение # 34
Ukrainian independent game developer
Сейчас нет на сайте
Quote (froex)
3. http://gcup.ru/forum/62-16908-3#278994 - тут см. первую задачку. Там проходит, а у автора нет?

тоесть по твоему:
int a[4] = {1,2,3,4}
a = a+2;
Проканает?
В твоем примере нет такой конструкции smile
Ты создаешь указатель, и через него уже работаешь с элементами массива smile
total += q++->i;

Про 4 я не понял о чем ты, какие 2.5? Вот именно про 2.5 не понял.


@noTformaT
KornivalДата: Вторник, 30 Августа 2011, 18:31 | Сообщение # 35
The Witcher
Сейчас нет на сайте
froex, я знаю какие различия между динамической и статической памятью. В нашем случае массив находится в стеке. Сейчас нет возможности проверить, но я уверен что память выделяется примерно так:
mov ebp, esp
sub esp, 1c
посмотри дизасемблированный листинг функции main
froexДата: Вторник, 30 Августа 2011, 18:35 | Сообщение # 36
Руководитель Froexilize team
Сейчас нет на сайте
Quote (noTformaT)
Про 4 я не понял о чем ты, какие 2.5? Вот именно про 2.5 не понял.

в массиве 4 элемента. Массив - это неразрывный блок памяти. Все эелменты массива в адресе хранятся друг за другом. Существует 4 элемента целого типа - 4 элемента по 4 байта. Если следовать идеологии, что перед первым элементом в памяти будет храниться размер массива, то автор вручную хочет править миром, если не следовать это идеологии, то автор несет бред. Хотя бред в любом случае.
Если объявлен массив:
int array[10];
то array - это указатель на область памяти, где находится целое число.
Запись array+1 будет возвращать адрес следующего элемента массива.
array - это указатель на целое, следовательно array+1 переводить нас будет на sizeof(int) в области памяти, т.е. на 4 байта. Так мы и получим адрес следующего элемента массива. Для примера, логическое выражение
(array[1] == (array+1)[0]) вернёт истину
(array[1] == *(array+1)) вернёт истину

Чем заниматься такими разборками - приведу код:
http://liveworkspace.org/code/da4eee87ba019af8f42af1d86429d9a0
Code

#include <iostream>

int main()
{
    int *a; // указатель на целое
    int array[5] = {0,1,2,3,4}; // массив из 5 чисел
    a = array;

    for(int i=0;i<5;++i)
       std::cout << array[i];
    std::cout <<std::endl;

    for(int i=0;i<5;++i)
       std::cout << a[i];
    std::cout <<std::endl;

    std::cout << a << ' ' << array << std::endl;
     
    std::cout << (array[1] == (array+1)[0]) << std::endl;
    std::cout << (array[1] == *(array+1)) << std::endl;
     
    return 0;
}

И результат выполнения:
Code
01234
01234
0xbfe011f0 0xbfe011f0
1
1

Добавлено (30.08.2011, 18:35)
---------------------------------------------
Я офф, буду к ночи - если код на вас не произвёл впечатления, я хз, как ещё объяснить. Вроде всё доказывает.


Не превращайте форум в чат. Пишите более развернуто и понятно - всё равно вас попросят объяснить подробнее.
Алгоритмы, программирование, оптимизация, тестирование, ведение проектов.
Ищу художника, дизайнера, тестера, программистов С и С++
Обучаю процессам разработки и программированию.
noTformaTДата: Вторник, 30 Августа 2011, 18:45 | Сообщение # 37
Ukrainian independent game developer
Сейчас нет на сайте
froex,
int a[10];
a = a +1;
проканает?


@noTformaT
KornivalДата: Вторник, 30 Августа 2011, 18:50 | Сообщение # 38
The Witcher
Сейчас нет на сайте
опять тоже самое... То что ты написал выше абсолютно верно, это обычная косвенная адресация и еще раз объяснять е принчипы не нужды. Но вопрос 'где ты увидел использование динамической памяти?' остается открытым.

Добавлено (30.08.2011, 18:50)
---------------------------------------------
нет не проканает, *а = *a+1 проканает

noTformaTДата: Вторник, 30 Августа 2011, 18:59 | Сообщение # 39
Ukrainian independent game developer
Сейчас нет на сайте
Quote (Kornival)
нет не проканает, *а = *a+1 проканает

ммм, чет я запутался, *а + 1 - это же разыменование


@noTformaT
05142Дата: Вторник, 30 Августа 2011, 19:13 | Сообщение # 40
постоянный участник
Сейчас нет на сайте
Quote (Kornival)
*а = *a+1 проканает


Это же совсем другое. Сейчас проверю a = a + 1 на gcc под linux

Добавлено (30.08.2011, 19:13)
---------------------------------------------
работает int *b = a + 1;


mecinvader
Форум игроделов » Программирование » C/C++ » Массивы и метки в C++
  • Страница 2 из 4
  • «
  • 1
  • 2
  • 3
  • 4
  • »
Поиск:

Все права сохранены. GcUp.ru © 2008-2022 Рейтинг