Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Работа с указателями (С/С++)  (Прочитано 18025 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« : 28-06-2011 09:55 » 

Мужики, чет запутался маленько... помогите осознать)
первая проблема:
определить так нельзя:
Код: (C++)
typedef struct _TYPE_A
{
   LPSTRUCT_B b;
} STRUCT_A, *LPSTRUCT_A;

typedef struct _TYPE_B
{
     LPSTRUCT_A a;
} STRUCT_B, *LPSTRUCT_B;

так:
Код: (C++)
typedef struct _TYPE_A
{
    struct _TYPE_B   *b;
} STRUCT_A;

typedef struct _TYPE_B
{
    struct _TYPE_A   *a;
} STRUCT_B;
- будет правильно? или есть другие способы


и вторая проблема.
выделена область памяти:
Код: (C++)
PVOID  buff;

мне надо сформировать указатель(PVOID) на некоторые ее элементы с шагом size_of_block = 1кб.
Код: (C++)
PVOID buff_i =  buff + i*size_of_block;
есествено, компилятор ругается (хотя что тут непонятного?Не понял сложить два числа)
напрашивается написать:

Код: (C++)
PVOID buff_i =  (PVOID) ( (DWORD)buff + i*size_of_block);
или
Код: (C++)
PVOID buff_i =  (PCHAR)buff + i*size_of_block;

но вот насколько это корректно? первая запись мне не нравится. вторая почему то тоже.
как вообще принято делать? и возможные проблемы на x64? (за выравниванием на границу 4к я слежу при выделении памяти)

и чем последнее будет отличатся от
Код: (C++)
PVOID buff_i =  (PWORD)buff + i*size_of_block;
Код: (C++)
PVOID buff_i =  (PDWORD)buff + i*size_of_block;
?
« Последнее редактирование: 28-06-2011 13:30 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 28-06-2011 10:16 » 

Код:
typedef struct _TYPE_A
{
    struct _TYPE_B   *b;
} STRUCT_A;

typedef struct _TYPE_B
{
    struct _TYPE_A   *a;
} STRUCT_B;
- будет правильно? или есть другие способы
Ну, можно ещё
Код: (C++)
struct _TYPE_B;
typedef struct _TYPE_A
{
    _TYPE_B   *b;
} STRUCT_A;

typedef struct _TYPE_B
{
    _TYPE_A   *a;
} STRUCT_B;

хотя, насколько я понимаю, это почти эквивалентно. По крайней мере, следующий код у меня в VS2008 компилируется:
Код: (C++)
typedef struct _TYPE_A
{
    struct _TYPE_B   *b;
} STRUCT_A;

typedef struct _TYPE_C
{
    _TYPE_B *b; // Внимание сюда: _TYPE_B мы ещё не описали окончательно
} STRUCT_C;

typedef struct _TYPE_B
{
    _TYPE_A   *a;
} STRUCT_B;



Добавлено через 5 минут и 20 секунд:
Во втором случае я бы просто указатель к char* приводил - у него известный размер, арифметика будет работать. (или, тогда уж, приводить PVOID к ULONG_PTR)
« Последнее редактирование: 28-06-2011 10:21 от Вад » Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 28-06-2011 12:01 » 

Код: (C++)
struct _TYPE_A;
struct _TYPE_B;

typedef _TYPE_A STRUCT_A;
typedef _TYPE_B STRUCT_B;

struct _TYPE_A
{
    STRUCT_B *b;
};

struct _TYPE_B
{
    STRUCT_A *a;
};

Не знаю как VC, а gcc скушал.


Насколько помню, арифметика void* имеет байтовую дискретность. Т.е. просто:

Код: (C++)
int i, size_of_block;
void *buff, *ptr;

ptr = buff + i * size_of_block;

PVOID, надеюсь, является "void*".
« Последнее редактирование: 28-06-2011 12:06 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 28-06-2011 13:26 » 

RXL,  void он  и в африке void: typedef void *PVOID;
а СL это не ест(
выдает error C2036: 'PVOID' : unknown size
я так понимаю он пытается толковать указатель как массив. а то что я к нему прибавляю - как индекс...
свинство с его стороны)

Код: (C++)
typedef struct _TYPE_A
{
    struct _TYPE_B   *b;
} STRUCT_A;

typedef struct _TYPE_C
{
    _TYPE_B *b; // Внимание сюда: _TYPE_B мы ещё не описали окончательно
} STRUCT_C;

typedef struct _TYPE_B
{
    _TYPE_A   *a;
} STRUCT_B;



Добавлено через 5 минут и 20 секунд:
Во втором случае я бы просто указатель к char* приводил - у него известный размер, арифметика будет работать. (или, тогда уж, приводить PVOID к ULONG_PTR)

хм. забавно. значит у меня не прошло именно потому что я...(ЩА ОБРАТНО ПРВЫЙ ПОСТ ИСПРАВЛЮ КАК БЫЛО НА САМОМ ДЕЛЕ) вот я дудл)

эээ... со структурой наконец въехал...
« Последнее редактирование: 28-06-2011 13:34 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 28-06-2011 14:20 » 

Цитата: Ochkarik
я так понимаю он пытается толковать указатель как массив. а то что я к нему прибавляю - как индекс...
На самом деле всё наоборот. Он массив трактует как указатель, а прибавление к указателю - как сдвиг по массиву. Т.е. буквально
Код: (C)
a[i] == *(a + i)

С void это, естественно, не работает, поскольку размер элемента массива неизвестен. Если размер байтовый, нужно привести тип к указателю на unsigned char или просто char.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #5 : 28-06-2011 18:02 » 

RXL, а зачем это вроде и без этого работает
Код: (C++)
typedef _TYPE_A STRUCT_A;

Ochkarik, а что так сложно структурку объявляешь и используешь?
Код: (C++)
typedef struct _TYPE_A
{
    struct _TYPE_B   *b; // зачем тут struct?
} STRUCT_A;
Записан

Странно всё это....
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #6 : 28-06-2011 18:08 » 

>>а что так сложно структурку объявляешь и используешь
повадки сишника без плюсов Улыбаюсь
Записан

RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #7 : 28-06-2011 18:33 » 

Антон, typedef чисто для удобочитаемости, а в случае Си не потребуется слово struct.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 28-06-2011 19:25 » 

>>а что так сложно структурку объявляешь и используешь
повадки сишника без плюсов Улыбаюсь
))))))))))))))
дык дрова опять пишу - чистый Си и есть) там не сама структура нужна, там нужен указатель на нее.
вообще говоря, это указатель на основную пользовательскую структуру "объекта" драйвера. кто-ж мне еще скажет, где все мои переменные лежат, когда я в чужом потоке работаю?))  
хотя....действительно.... в данном случае... можно было вытащить ее через другое место) только сейчас в голову пришло... подумаю))) спасибо за мысль)

PS что значит зачем struct? а как? там перекрестные указатели в двух структурах... а вообще я си как таковой не учил никогда... нюансы не постигал) так что может и...
PPS но в любом случае, некоторые заголовочные файлы драйвера потом используются в юзерсокм C++... так что...
« Последнее редактирование: 28-06-2011 19:29 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #9 : 28-06-2011 20:04 » 

Сишный вариант:

Код: (C)
struct _TYPE_A;
struct _TYPE_B;

typedef struct _TYPE_A STRUCT_A;
typedef struct _TYPE_B STRUCT_B;


struct _TYPE_A
{
    STRUCT_B *b;
};

struct _TYPE_B
{
    STRUCT_A *a;
};

Опять же, gcc не ругнулся: прошло как Си и как C++.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #10 : 28-06-2011 20:36 » 

спасибо... буду знать) а вообще подучить надо бы...
хотя длинновато)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #11 : 29-06-2011 03:18 » 

Собственно вопросы возникли от того, что явно не сказано, что код для Plain C
но typedef я бы прибил Улыбаюсь имхо код попроще и очевидней будет, хотя неуверне, что в Plain C прокатит, а на нём не пишу и стандартов не читал Улыбаюсь
Код: (C++)
struct _TYPE_A;
struct _TYPE_B;

struct _TYPE_A
{
    _TYPE_B *b;
};

struct _TYPE_B
{
    _TYPE_A *a;
};
Записан

Странно всё это....
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #12 : 29-06-2011 05:41 » new

Антон, не прокатит: struct в Си - неотъемлемая часть типа.

Код: (C)
struct _TYPE_A *a;

либо использовать typedef
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #13 : 30-06-2011 21:45 » 

блин, сутки разбирался, десять бсодов) нельзя там через другое место указатель передавать)
и во всех примерах от майкрософта по первому варианту сделано)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines