Контроль типов. Как сделать, чтобы CHAR[xx] и PCHAR были эквивалентны?

Тема в разделе "LANGS.C", создана пользователем int2e, 29 янв 2009.

  1. int2e

    int2e New Member

    Публикаций:
    0
    Регистрация:
    9 янв 2009
    Сообщения:
    169
    Есть массивы CHAR[40], CHAR[100], CHAR[256] и еще несколько...

    В них хранятся строки.... Когда в качестве параметра передается указатель на массив, компилятор ругается, что не может конвертировать CHAR*[xx] в PCHAR и нужно каждый раз в скобках уточнять вручную, т.е. (PCHAR)&array

    Как можно сделать так, чтобы компилятор не ругался на данную ошибку и принимал тип CHAR*[xx] как PCHAR??
     
  2. _basmp_

    _basmp_ New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2005
    Сообщения:
    2.939
    немного загадочно. хотелось бы снисхождения к отсутствию проницательности в виде примера. от объявлений и до использования участников беды
     
  3. int2e

    int2e New Member

    Публикаций:
    0
    Регистрация:
    9 янв 2009
    Сообщения:
    169
    Я действительно наверное неточно выразился....

    Код (Text):
    1. char ayt_name[40];
    2. char oun_name[100];
    3. char sim_name[256];
    4. ....
    5.  
    6. lstrcmpiA(&ayt_name, "autoaim");
    7. /* ошибка.
    8. error C2664: 'lstrcmpiA' : cannot convert parameter 1 from 'CHAR (*)[40]' to 'LPSTR'   
    9. */
    приходится делать так

    Код (Text):
    1. lstrcmpiA((PCHAR)&ayt_name, "autoaim");
    поскольку аналогичных примеров и вызовов много - каждый раз писать скобки - накладно....
    как сделать так, чтобы компилятор не ругался на подобный тип ошибкок??

    вводить дополнительные переменные, например такие

    Код (Text):
    1. PCHAR payt_name = (PCHAR)&ayt_name
    крайне нежелательно
     
  4. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    А почему не так?
    Код (Text):
    1. lstrcmpiA(ayt_name, "autoaim");
    Имя массива разлагается. :)
     
  5. int2e

    int2e New Member

    Публикаций:
    0
    Регистрация:
    9 янв 2009
    Сообщения:
    169
    Booster
    О_О
    без комментариев..... работает.... я в легком шоке...
     
  6. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    int2e
    Ну как бы имя массива разлагается в указатель на первый элемент. То есть
    ayt_name = &ayt_name[0]

    Думаю что и на &ayt_name[0] ругать не должно.
     
  7. int2e

    int2e New Member

    Публикаций:
    0
    Регистрация:
    9 янв 2009
    Сообщения:
    169
    спасибо большое!!!
    Все, тему можно закрывать :)
     
  8. _basmp_

    _basmp_ New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2005
    Сообщения:
    2.939
    Booster
    добавлю
    typeof &ayt_name == char**;
     
  9. s0larian

    s0larian New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2004
    Сообщения:
    489
    Адрес:
    Крыжёпполь
    int2e, дополню, по стандарту ANSI C имя массива и есть указатель:

    char name[20];
    char *p1 = name, *p2 = &name[0];
    p1 == p2;

    То есть, с точки зрения ANSI С, доступ к памяти может быть и через name и p1:
    name[0] = '\0';
    p1[0] = '\0';
    *p1 = '\0';

    и, как и сказал _basmp_, адрес имени, &name, есть указатель-на-указатель.
     
  10. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    s0larian
    Ну, по стандарту C++ - char[] и char* - все же разные типы. В общем случае. Хотя некоторые компиляторы работают с ними одинаково. Просто при вызове функции имя массива неявно приводится к указателю на первый элемент.
    (Это я занудствую, если кто не понял :) )
     
  11. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    Обратное утверждение также верно: адрес на любой тип можно использовать как массив:
    Код (Text):
    1. char* p = <проинициализировано не важно как>;
    2. p [10] = 'A'; // при условии если есть место
    И даже такая конструкция возможна (когда функция возвратит адрес на объект класса):
    Код (Text):
    1. class A; // у этого класса есть метод: Show()
    2.  
    3. ...
    4.  
    5. A* GetClass ();
    6.  
    7. ...
    8.  
    9. (GetClass () [0]).Show ();
     
  12. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    AsmGuru62
    Не "использовать как массив", а применять оператор [].
    (это я опять занудствую :Р)
    а так вы умеете?
    Код (Text):
    1. (0[GetClass ()]).Show ();
    :)
     
  13. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    typeof &ayt_name == char** ложно скорее typeof &ayt_name == char(*)[N] а вот если к нему применить разыменование то тогда получим просто char *
     
  14. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    иначе если бы typeof &ayt_name == char** это было правдой то инкремент &ayt_name увеличивал бы адрес на размер указателя
    а должен на размер массива делать смещения
    из за этого и работает арифметика с двумерными массивами типа
    int mat[4][4];
    *(*(mat + i) + j) если бы было typeof &mat[4] == int** это бы не работало
     
  15. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Взятие адреса у массива - это вообще бессмысленная операция :)
     
  16. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    int2e
    >>спасибо большое!!!
    Все, тему можно закрывать :)
    Вот от тебя этого никак не ожидал! ;)))) Позабавил ;)
     
  17. Aspire

    Aspire New Member

    Публикаций:
    0
    Регистрация:
    19 май 2007
    Сообщения:
    1.028
    археологи..
     
  18. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    Aspire
    гыыы, я так часто сюда захожу, что любая тема мне кажется новой )))
     
  19. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    где еще бывает нужен указатель на массив так это
    чтоб кусок плоской памяти проинтерпретировать как матрицу
    типа так но и то в реальном коде такого не встретиш
    надо явно зашивать указатель на массив какого размера создается
    Код (Text):
    1. int *matrix = malloc(n * m * sizeof(int));
    2. int (*p)[m/*hardcode*/] = (int(*)[m/*hardcode*/])matrix;
    3. p[i][j] //...
    вместо этого обычно делают так тут хоть есть возможность
    динамически создавать матрицы нужного размера
    Код (Text):
    1.    
    2. int *matrix = malloc(n * m * sizeof(int));
    3. matrix[i * m + j] //....
     
  20. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    хотя в с99 это недоразумение исправили теперь этот кусок
    Код (Text):
    1. int (*p)[m/*hardcode*/] = (int(*)[m/*hardcode*/])matrix;
    можно переписать и так
    Код (Text):
    1. int (*p)[m] = (int(*)[m])matrix;
    но на практике студия очень много ошибок выкидывает на такой код интересно они когда нить поддержут с99 полностью