реклама на сайте
подробности

 
 
5 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> Можно ли в typedef struct описать массив переменной длины, IAR, C, AVR
west329_
сообщение Feb 20 2009, 09:52
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 378
Регистрация: 10-09-07
Из: UKR/Voz
Пользователь №: 30 423



Есть некий протокол который пытаюсь описать структурой типа

Код
typedef struct TMainS
  {
    unsigned char   Start;
    unsigned long   Adata;
    unsigned int      Bdata;
    unsigned char   Cdata[var];
    unsigned int      Ddata;
    unsigned int      Edata;

  } T_MainS_Header;


Подскажите как в таких случаях поступат если, Cdata имеет переменную длину.

Перед присваиваем типов можно легко найти значение var.
Интересует доступ к полям Ddata и Edata, после присваивания типа MainS->Ddata или MainS->Edata.

Возможно ли такое решение, в книге по С такого ненашол, компилятор упорно ругается на Cdata, говорит что надо константа для var, и я с ним согласен, но есть ли другие решения ?

Сообщение отредактировал west329_ - Feb 20 2009, 09:57
Go to the top of the page
 
+Quote Post
ARV
сообщение Feb 20 2009, 09:58
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



Cdata делайте указателем, не забывая выделять память под вашу "переменную" длину и освобождать, когда станет не нужно... либо переместите массив в конец структуры и объявите его Cdata[] - т.е. без явного указания длины...


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Feb 20 2009, 10:04
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(west329_ @ Feb 20 2009, 13:52) *
Подскажите как в таких случаях поступат если, Cdata имеет переменную длину.


Стандартами языка С С89 и С99 массивы переменной длины не предусмотрены. 2 варианта для тебя навскидку:
1. Объвить Cdata фиксированного размера, заведомо большим, чем может быть по протоколу.
2. Объвить поле unsigned char *Cdata, а затем, когда var будет известно - динамически выделять/освобождать через malloc/free.
Причина редактирования: Удаление излишнего цитирования.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 20 2009, 11:01
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(west329_ @ Feb 20 2009, 11:52) *
Подскажите как в таких случаях поступат если, Cdata имеет переменную длину.
В С массив неизвестной длины (фактически - нулевой) может располагаться только в конце структуры. В плюсах массивы переменной длины средствами языка невозможны. На С вы можете разбить вашу структуру на две - Header и Footer. В первой Start, Adata, Bdata, Cdata, во второй - Ddata, Edata. К Footer обращаетесь через указатель, который ставите на нужное место памяти, когда уже знаете значение var. При передаче можно разбить процедуру на три части - передача заголовка, передача Cdata, передача заключительной части.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
west329_
сообщение Feb 20 2009, 11:54
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 378
Регистрация: 10-09-07
Из: UKR/Voz
Пользователь №: 30 423



Благодар за подсказку.
Понятно как действовать дальше, впринципе изначально планировал разбить на 2 части, но засомневался, так как опыта маловато.
Go to the top of the page
 
+Quote Post
rezident
сообщение Feb 20 2009, 14:06
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Сергей Борщ @ Feb 20 2009, 16:01) *
В С массив неизвестной длины (фактически - нулевой) может располагаться только в конце структуры.
Дополню слова Сергея.
В таком случае (объявление без явного указания размера) массив будет incompete array, а в структуре под него будет выделена лишь переменная под указатель. Так что, если вы попытаетесь определить размер такой структуры с помощью sizeof, то результат может отличаться от ожидаемого. Это следует помнить и учитывать заранее.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 20 2009, 19:12
Сообщение #7


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(rezident @ Feb 20 2009, 16:06) *
а в структуре под него будет выделена лишь переменная под указатель.
Нет. Не будет там указателя. Размер структуры будет равен размеру без массива. При обращении к массиву будет обращение в адреса сразу за структурой. Это можно представить, как будто в структуре последним идет массив int Array[0]; а обращение идет как бы за границы этого массива.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Rst7
сообщение Feb 20 2009, 19:32
Сообщение #8


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Чисто с прагматической точки зрения я бы положил в конце структуры массив с длинной, соответствующей максимально возможной. Меньше способов наступить на грабли. Сугубо ИМХО.


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
west329_
сообщение Feb 21 2009, 08:25
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 378
Регистрация: 10-09-07
Из: UKR/Voz
Пользователь №: 30 423



Если забирать данные с Cdata через указатель, какой размерности должен быть указатель ?.

Предпологаю, что INT, но не утверждаю, исхожу из того, что массив имеет размерность до 400 байт, и если забирать вручную через инкремент в переменную, указатель будет возвращать по 1 байту масива или по 2 ?.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 21 2009, 10:01
Сообщение #10


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(west329_ @ Feb 21 2009, 11:25) *
Если забирать данные с Cdata через указатель, какой размерности должен быть указатель ?.
Вопрос неверен в корне.
В Вашем случае указатель имеет размерность 2 байта в любом случае, т.к. размер ОЗУ врядли более 64КБ.
Тип указателя определяется типом данных на которые он ссылается и всё. Более нет никаких характеристик у указателей.
Если он указывает на байты, то unsigned char*, если на слова то unsigned short*
Если на константные данные ссылается: const unsigned char*.
Если сам указатель должен быть константным: unsigned char* const
Если указатель константный и ссылается на сонстанту: const unsigned char* const
Ну и ещё надо не забывать о volatile, если Ваш указатель ссылается на аппаратный регистр контроллера или область памяти, которая может использоваться (изменяться) в прерываниях то надо писать так: volatile unsigned char* p = &PIND;


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Feb 21 2009, 16:59
Сообщение #11


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(west329_ @ Feb 21 2009, 12:25) *
Если забирать данные с Cdata через указатель, какой размерности должен быть указатель ?.

Предпологаю, что INT, но не утверждаю, исхожу из того, что массив имеет размерность до 400 байт, и если забирать вручную через инкремент в переменную, указатель будет возвращать по 1 байту масива или по 2 ?.


Указатель должен быть такого размера, чтобы однозначно адресовать память и зависит от процессора.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 21 2009, 17:35
Сообщение #12


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(sergeeff @ Feb 21 2009, 19:59) *
Указатель должен быть такого размера, чтобы однозначно адресовать память и зависит от процессора.
По стандарту на язык СИ "размерность" указателя равна "размерности" типа int для данной архитектуры. Если я ничего не напутал.
Для 8 и наверное для 16 битного контроллера int = short = 2 байта.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Rst7
сообщение Feb 21 2009, 17:57
Сообщение #13


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата
По стандарту на язык СИ "размерность" указателя равна "размерности" типа int для данной архитектуры. Если я ничего не напутал.


Да, такое заблуждение было. До появления 64хбитных архитектур. Там int - 32 бита, указатель 64. Соответственно, size_t (разность между двумя указателями) не int, а long long.


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
zltigo
сообщение Feb 22 2009, 06:52
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Rst7 @ Feb 21 2009, 20:57) *
До появления 64хбитных архитектур....

Да и "до" указетели совершенно разной размерности в пределах одной платфрмы обыденное явление - в том-же реалмоде x86 самые разнообразные по размеру, и даже два варианта 32bit, один из которых реально вовсе и не 32bit smile.gif.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Rst7
сообщение Feb 22 2009, 07:26
Сообщение #15


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата
в том-же реалмоде x86


Ну да. Правда, самый мелкий указатель (в пределах сегмента) все-же соответствовал int'у. Но вообще, про платформы с сегментацией надо забывать, как о страшном сне smile.gif


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 22 2009, 08:32
Сообщение #16


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Да и на x51 была возможность косвенной адресации через восьмибитные регистры. Разговор не о "возможных" вариантах адресации на той или иной платформе. Разговор о языке программирования СИ и о том какова в нём разрядность указателя. Я запомнил, что aesok говорил о том, что она по стандарту равна разрядности типа int - я ретранслировал. Надо глянуть в стандарт.
Цитата
5 An integer may be converted to any pointer type. Except as previously specified, the
result is implementation-defined, might not be correctly aligned, might not point to an
entity of the referenced type, and might be a trap representation.
(The mapping functions for converting a pointer to an integer or an integer to a pointer
are intended to be consistent with the addressing structure of the execution environment.)

6 Any pointer type may be converted to an integer type. Except as previously specified, the
result is implementation-defined. If the result cannot be represented in the integer type,
the behavior is undefined. The result need not be in the range of values of any integer
type.
Вот так. преобразование INT<->PTR должно обеспечиваться с легкостью необычайной (на момент принятия стандарта 1999г)smile.gif
Цитата
A pointer to void shall have the same representation and alignment requirements as a
pointer to a character type.39) Similarly, pointers to qualified or unqualified versions of
compatible types shall have the same representation and alignment requirements. All
pointers to structure types shall have the same representation and alignment requirements
as each other. All pointers to union types shall have the same representation and
alignment requirements as each other. Pointers to other types need not have the same
representation or alignment requirements.
Интересно какие остальные?


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Feb 22 2009, 11:55
Сообщение #17


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(Rst7 @ Feb 21 2009, 21:57) *
Да, такое заблуждение было. До появления 64хбитных архитектур. Там int - 32 бита, указатель 64. Соответственно, size_t (разность между двумя указателями) не int, а long long.


Разность между двумя указателями - ptrdiff_t.

size_t - стандартный псевдоним для типа, возвращающегося при запросе размера объекта языка (sizeof). Всегда беззнаковый.
Go to the top of the page
 
+Quote Post
Rst7
сообщение Feb 22 2009, 12:04
Сообщение #18


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата
Разность между двумя указателями - ptrdiff_t.


Да-да. Пардон, ошибся. Правда, сути дела это не меняет. ptrdiff_t не лезет в int.


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
ReAl
сообщение Feb 22 2009, 20:51
Сообщение #19


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(demiurg_spb @ Feb 22 2009, 10:32) *
Вот так. преобразование INT<->PTR должно обеспечиваться с легкостью необычайной (на момент принятия стандарта 1999г)smile.gif
Ну. Всё правильно.
Просто "int" не тождественно "integer type" ("Платон человек, но не все люди Платоны").
Даже в процитированном Вами написано
Цитата
The result need not be in the range of values of any integer type.
Смотрим тот же стандарт 99-го года.
Цитата
6.2.5 Types
...
4 There are five standard signed integer types, designated as signed char, short int, int, long int, and long long int. (These and other types may be designated in several additional ways, as described in 6.7.2.) There may also be implementation-defined extended signed integer types.28) The standard and extended signed integer types are collectively called signed integer types.29)

long long int есть integer-type и в него 64-битный указатель влезет и назад вылезет.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 22 2009, 21:22
Сообщение #20


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(ReAl @ Feb 22 2009, 23:51) *
Просто "int" не тождественно "integer type" ("Платон человек, но не все люди Платоны").
Согласен. Я тоже об этом задумывался.
Цитата
long long int есть integer-type и в него 64-битный указатель влезет и назад вылезет.
Это я понял. НО вопрос был задан примерно так "какого размера указатель мне выбрать для адресации массива длиной 333?". И что Вы ответите человеку? Как ему выбрать указатель подходящей размерности?smile.gif


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
ReAl
сообщение Feb 22 2009, 21:39
Сообщение #21


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(demiurg_spb @ Feb 22 2009, 23:22) *
Это всё понятно. Вот вопрос был задан примерно так "какого размера указатель мне выбрать для адресации массива длиной 333?". И что Вы ответите человеку? Как ему выбрать указатель подходящей размерности?smile.gif
Не понял вопроса.
T*
где T - тип элемента массива.

Если речь идёт о выборе типа достаточной разрядности для индекса массива, то size_t хватит гарантированно всегда, если минимально-возможной разрядности, то для 333 - int16_t/uint16_t (второе в зависимости от процессора может быть выгоднее по генерируемому коду, хуже врядли будет). В общем случае - пробежаться #if-ами по константам из limits.h и соорудить нужный typedef.

Если вопрос звучит "какой не-указательный тип выбрать для хранения этого указателя?", то сначала я спрошу "а какого его не хранить в переменной типа T* или в крайнем случае void*?"
Если "действительно надо", то вариантом ответа может быть аналогичный предыдущему, только сравнивать по очереди не размер массива с UCHAR_MAX/UINT_MAX, а sizeof(T*) с sizeof() целых типов.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
west329_
сообщение Feb 23 2009, 06:39
Сообщение #22


Местный
***

Группа: Свой
Сообщений: 378
Регистрация: 10-09-07
Из: UKR/Voz
Пользователь №: 30 423



CODE
/* - LIMITS.H -

Integral ANSI element sizes.

$Revision: 1.4 $

Copyright 1986 - 1999 IAR Systems. All rights reserved.
*/

#ifndef _LIMITS_INCLUDED
#define _LIMITS_INCLUDED

#ifndef _SYSTEM_BUILD
#pragma system_include
#endif

#include "sysmac.h"

#define CHAR_BIT 8 /* Number of bits in any "char" */

#if defined(__CHAR_MAX__)

#define CHAR_MAX __CHAR_MAX__
#define CHAR_MIN __CHAR_MIN__

#define MB_LEN_MAX 1 /* No of bytes in multibyte char */

#define SCHAR_MAX __SIGNED_CHAR_MAX__
#define SCHAR_MIN __SIGNED_CHAR_MIN__
#define UCHAR_MAX __UNSIGNED_CHAR_MAX__

#define SHRT_MAX __SIGNED_SHORT_MAX__
#define SHRT_MIN __SIGNED_SHORT_MIN__
#define USHRT_MAX __UNSIGNED_SHORT_MAX__

#define INT_MAX __SIGNED_INT_MAX__
#define INT_MIN __SIGNED_INT_MIN__
#define UINT_MAX __UNSIGNED_INT_MAX__

#define LONG_MAX __SIGNED_LONG_MAX__
#define LONG_MIN __SIGNED_LONG_MIN__
#define ULONG_MAX __UNSIGNED_LONG_MAX__

#else /* !defined(__CHAR_MAX__) */

#if _argt$(char)==1 /* "char" = "unsigned" "char" */
#define CHAR_MAX 255
#define CHAR_MIN 0
#else
#define CHAR_MAX 127 /* Maximum "char" value */
#define CHAR_MIN (-128) /* Mimimum "char" value */
#endif

#define MB_LEN_MAX 1 /* No of bytes in multibyte char */

#define SCHAR_MAX 127 /* Maximum "signed" "char" value */
#define SCHAR_MIN (-128) /* Minimum "signed" "char" value */

#define UCHAR_MAX 255 /* Maximum "unsigned" "char" value */

#define SHRT_MAX 32767 /* Maximum ("signed") "short" value */
#define SHRT_MIN (-32767-1) /* Minimum ("signed") "short" value */
#define USHRT_MAX 0xFFFFU /* Maximum "unsigned" "short" value */

#if __INT_SIZE__ == 2 /* For 32-bit CPU's usually not */
#define INT_MAX 32767 /* Maximum ("signed") "int" value */
#define INT_MIN (-32767-1) /* Minimum ("signed") "int" value */
#define UINT_MAX 0xFFFFU /* Maximum "unsigned" "int" value */
#else
#define INT_MAX 2147483647
#define INT_MIN (-2147483647-1)
#define UINT_MAX 0xFFFFFFFFU
#endif

#define LONG_MAX 2147483647 /* Maximum ("signed") "long" value */
#define LONG_MIN (-2147483647-1) /* Minimum ("signed") "long" value */
#define ULONG_MAX 0xFFFFFFFFU /* Maximum "unsigned" "long" value */

#endif /* defined(__CHAR_MAX__) */

#endif


Выходит, что unsigned chort, что unsigned int одинаково в данном случае.
Причина редактирования: Уменьшение видимого размера цитаты исходника.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 23 2009, 08:19
Сообщение #23


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(ReAl @ Feb 23 2009, 00:39) *
Не понял вопроса.
Вот и я не понял вопроса. Поэтому и углубился в "теорию си указателей"B) )
Цитата(west329_ @ Feb 23 2009, 09:39) *
Код
- LIMITS.H - .....
- вот этого всего писать не надо было. Разговор не о том и не между первоклассниками. krapula.gif
Цитата
Выходит, что unsigned chort....
unsigned Чёрт побериsmile.gif
Пора закрывать тему. Уже один флэйм идёт.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
west329_
сообщение Feb 23 2009, 11:36
Сообщение #24


Местный
***

Группа: Свой
Сообщений: 378
Регистрация: 10-09-07
Из: UKR/Voz
Пользователь №: 30 423



Цитата(demiurg_spb @ Feb 23 2009, 11:19) *
Вот и я не понял вопроса. Поэтому и углубился в "теорию си указателей"B) )
- вот этого всего писать не надо было. Разговор не о том и не между первоклассниками. krapula.gif
unsigned Чёрт побериsmile.gif
Пора закрывать тему. Уже один флэйм идёт.

а указатель может быть signed, обьясните мне ?
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Feb 23 2009, 11:48
Сообщение #25


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(west329_ @ Feb 23 2009, 14:36) *
а указатель может быть signed, обьясните мне ?


А адрес ячейки памяти бывает отрицательный?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 23 2009, 12:01
Сообщение #26


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(west329_ @ Feb 23 2009, 13:36) *
а указатель может быть signed, обьясните мне ?
Мне кажется вы не понимаете. unsigned char * означает "указатель на unsigned char". Каким образом будет представлен сам указатель - внутреннее дело компилятора. Программиста интересует тот тип данных, на который этот указатель указывает.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
west329_
сообщение Feb 23 2009, 12:21
Сообщение #27


Местный
***

Группа: Свой
Сообщений: 378
Регистрация: 10-09-07
Из: UKR/Voz
Пользователь №: 30 423



Незнал, чесно признаюсь думал, что это описывается тип указателя, соотвецтвенно меня ввело в заблуждение (Сообщение #23) который предложил закрыть топик, но данные которые будут лежать в массиве действительно беззнаковые, выходит что я был прав u_i, а за сам указатель, его тип и хранение позаботится как я понял сам ИАР. Или я ошибаюсь
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Feb 23 2009, 12:33
Сообщение #28


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(west329_ @ Feb 23 2009, 15:21) *
Незнал, чесно признаюсь думал, что это описывается тип указателя, соотвецтвенно меня ввело в заблуждение (Сообщение #23) который предложил закрыть топик, но данные которые будут лежать в массиве действительно беззнаковые, выходит что я был прав u_i, а за сам указатель, его тип и хранение позаботится как я понял сам ИАР. Или я ошибаюсь


У вас в голове полная путаница в понимании того, что такое массив, а что такое указатель. Вы бы не ленились, а почитали что-нибудь от отцов-основателей. Полно толковых книг по С. И в inet'e куча ресурсов.
Go to the top of the page
 
+Quote Post
west329_
сообщение Feb 23 2009, 13:40
Сообщение #29


Местный
***

Группа: Свой
Сообщений: 378
Регистрация: 10-09-07
Из: UKR/Voz
Пользователь №: 30 423



..Указатель — это переменная, значением которой является адрес некоторого объекта (обычно другой переменной) в памяти компьютера...
..Базовый тип указателя определяет тип объекта, на который указатель будет ссылаться. Фактически указатель любого типа может ссылаться на любое место в памяти...

Сообщение отредактировал west329_ - Feb 23 2009, 13:42
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Feb 23 2009, 15:05
Сообщение #30


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(west329_ @ Feb 23 2009, 16:40) *
..Указатель — это переменная, значением которой является адрес некоторого объекта (обычно другой переменной) в памяти компьютера...
..Базовый тип указателя определяет тип объекта, на который указатель будет ссылаться. Фактически указатель любого типа может ссылаться на любое место в памяти...


Это вы к чему нам это радостно сообщаете?
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 23 2009, 20:34
Сообщение #31


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(sergeeff @ Feb 23 2009, 14:48) *
А адрес ячейки памяти бывает отрицательный?
Относительно чего либо бывает. Вы когда-либо видели код типа:
Код
    char* p = (char*)123;
    p[0] = '/0';
    p[-1] = 'а';
    p[-2] = 'п';
    p[-3] = 'о';
    p[-4] = 'Ж';
Я не говорю, что так надо писать, я говорю что так можно и это технически грамотно.
Индексы массива тоже являются "одним из способов адресации". ИМХО.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Feb 24 2009, 07:33
Сообщение #32


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Очень жаль, если у вас до сих пор нет понимания разницы между адресом в памяти и индексом в массиве.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 24 2009, 07:42
Сообщение #33


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(sergeeff @ Feb 24 2009, 10:33) *
Очень жаль, если у вас до сих пор нет понимания разницы между адресом в памяти и индексом в массиве.
У меня есть прекрасное понимание и того и другого - верьте мне. Но я пойду на принцип.
Давайте объясните мне принципиальную разницу между адресацией просто ячек памяти и индексацией (синоним-адресация) ячеек памяти массива из байт. На asm будет что-то типа ldi R16,Z+ в обоих случаях.
Читая, некоторые не ловят смысл написанного. Часть фразы написана в кавычках...
Вышесказанное мной приведено лишь с одной целью - показать, что если физически нет адресов ячеек с отрицательными номерами, то гипотетически ничего не мешает указателю быть знаковым. И что нельзя быть категоричным в своих суждениях.
А до этого я пошутил над опечаткой - словом chort - чёрт (short в оригинале),
а west329_ принял во внимание зачем-то выдранное из контекста слово unsigned и понеслось, а изначально об этом речи вообще не велось!
У меня не возникало даже мысли о знаковости указателей.
Такое тоже возможно - и это тоже нормально (но я так никогда не делал на практике).
Код
char* p = (char*)-1;
for (int i=0; i<10; i++)  *++p = 0;
ЗЫ: высказывать свои сожаления уместнее в некрологе.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Feb 24 2009, 09:21
Сообщение #34


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Типун вам на язык и долгих лет жизни.

В двоичной системе отрицательное или положительное число - вопрос интерпретации этого представления.

Индексация в массиве - это всегда адрес + смещение. Смещение может быть каким угодно, +/- , но итоговый адрес - всегда положительный. При попытке записать/прочитать чего-нибудь по char* p = (char*)-1, куда будет писаться *p = 0? Можо сказать, по адресу -1 (при этом на вас посмотрят коллеги с некоторым недоумением), можно - по 0хFFFF..FF. Я понимаю, что мы живем в мире условностей, но зачем на ровном месте придумывать новые...
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 24 2009, 09:38
Сообщение #35


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(sergeeff @ Feb 24 2009, 12:21) *
Типун вам на язык и долгих лет жизни.
smile.gif
На мой взгляд именно -1 в данном случае абсолютно уместно (предыдущий перед нулём - всё однозначно).
А вот что записать 0xffff или ещё чего-нибуть типа 0xffff..ff - это уже надо задуматься, да и переносимость пропадёт в свете недавно выясненных обстоятельств о "размерности" указателей. Я считаю это не условность, а единственно верное решение (ну не совсем единственное, но точно верное). Я забыл к сожалению в какой книжке я это прочитал, но возможные проблемы при смене разрядности процессора - это не миф, и лучше соломку подстелить заранее (писать надежный код должно стать привычкой)... А косые взгляды коллег - это уже другая история и другая причина и кроется она в коллегахsmile.gif


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Feb 24 2009, 09:53
Сообщение #36


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата
это уже надо задуматься


Задумываться - полезно.

Адрес перед нулем - это сильно. Наш ответ Чемберлену.
А давайте начнем размещать объекты по адресам -123456 или -987654. Обеспечим себе место в зале программистской славы!
Go to the top of the page
 
+Quote Post
west329_
сообщение Feb 24 2009, 10:04
Сообщение #37


Местный
***

Группа: Свой
Сообщений: 378
Регистрация: 10-09-07
Из: UKR/Voz
Пользователь №: 30 423



Подскажите как правильно поступить, хочу использовать стандартную процедуру С strstr описанную в string.h

Цитата
char *strstr(const char *s1, const char *s2);


Обьясните с чем связано, то что все передаётся через const, масив содержит необязательно символы, можно и числовую последовательность искать, и значения хранятся во временных буферах.

собственно выжимка
Код
...
#include <string.h>
...
#define BUFFER_SIZE_P 350
unsigned char buf_phone[BUFFER_SIZE_P];
..
void test (void)
{
  unsigned char *p1, *p2, *p3;

  p1 = & test1[0];
  p2 = & test2[0];
  p3 = strstr( test2, test1);
}  
...

В принципе всё работает и правильно, но компилятор ругается на несовпадение типов, хотя и компилирует.

Успокоить компилятор удалось только таким способом
Код
p3 = (unsigned char*)strstr( (char const*)test2, (char const*)test1);

ответ правильный предупреждений нету, скажите такое решение правильное ?
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 24 2009, 10:38
Сообщение #38


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(west329_ @ Feb 24 2009, 13:04) *
Обьясните с чем связано, то что все передаётся через const, масив содержит необязательно символы, можно и числовую последовательность искать, и значения хранятся во временных буферах.
Это дополнительное документирование функции. Сразу становится ясно, что функция не модифицирует строки.
Цитата
скажите такое решение правильное ?
Нет. Компилятор ругается на то, что Вы передаете unsigned char* вместо char*.
ошибка тут: unsigned char *p1, *p2, *p3;
А передавать в качестве аргумента не константу вместо констаны - это нормально и естественно. Плохо когда наоборот.

Цитата(sergeeff @ Feb 24 2009, 12:53) *
Задумываться - полезно.
Я так не думаю. Грубо: думать надо над идеологией, алгоритмом и надёжностью, а не над написанием цифр и букв.
Цитата
Адрес перед нулем - это сильно. Наш ответ Чемберлену.
А давайте начнем размещать объекты по адресам -123456 или -987654. Обеспечим себе место в зале программистской славы!
Мне Вас не переубедить. Жизнь Вас научит. Зачем Вы ёрничаете? Любому грамотному программисту всё будет прекрасно понятно. У меня в конторе работают 5 программистов и (-1) не вызывает ни у кого сомнений - это общепринятая (не побоюсь этого слова) практика с которой Вы просто не сталкивались ранее.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
west329_
сообщение Feb 24 2009, 10:48
Сообщение #39


Местный
***

Группа: Свой
Сообщений: 378
Регистрация: 10-09-07
Из: UKR/Voz
Пользователь №: 30 423



В чем тогда отличие unsigned char от char

сори, понял ошибу

Код
unsigned char test1[] = "hello";
unsigned char test2[] = "test1 hello test2";


void test (void)
{
  char *p1, *p2, *p3;

  p1 = (char*) & test1[0];
  p2 = (char*) & test2[0];
  p3 = strstr( p2, p1);
}


а такой вариант правильный ?

Сообщение отредактировал west329_ - Feb 24 2009, 10:54
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Feb 24 2009, 10:55
Сообщение #40


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(west329_ @ Feb 24 2009, 13:48) *
В чем тогда отличие unsigned char от char

один тип кодирует числа от 0 до 255,
другой - от -128 до 127
Вот и вся разница.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 24 2009, 11:09
Сообщение #41


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(west329_ @ Feb 24 2009, 13:48) *
...а такой вариант правильный ?
Не то чтобы неправильный. Лишние приведения типов, лишние переменные, лишняя писанина - нагромождение...
Чем Вас это не привлекает?
Код
char test1[] = "hello";
char test2[] = "test1 hello test2";

char*  p = strstr(test2, test1);
...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Feb 24 2009, 11:12
Сообщение #42


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(west329_ @ Feb 24 2009, 13:48) *
а такой вариант правильный ?

Не плодите сущности:
Код
char test1[] = "hello";
char test2[] = "test1 hello test2";
  p3 = strstr( test1, test2);

и все. Точнее почти все - еще для некоторых платформ/компиляторов следует подумать о ценных указаниях по месту размещения этих строк. Ну и моему взгдляду приятнее
Код
char *test1 = "hello";
char *test2 = "test1 hello test2";

нежели []


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
xemul
сообщение Feb 24 2009, 11:21
Сообщение #43



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Цитата(west329_ @ Feb 24 2009, 13:48) *
Код
unsigned char test1[] = "hello";
unsigned char test2[] = "test1 hello test2";

void test (void)
{
  char *p1, *p2, *p3;

  p1 = (char*) & test1[0];
  p2 = (char*) & test2[0];
  p3 = strstr( p2, p1);
}


а такой вариант правильный ?

Одноцветно, пока работаете с символами только из диапазона 0x00..0x7f или только из диапазона 0x80..0xff. Вот только не могу понять, почему unsigned char Вам нравится больше просто char в случае testХ[], и зачем вообще эти пляски с бубнами?
Цитата
сори, понял ошибу

не похожеsad.gif

ЗЫЖ
p1 = (char*) test1; // test1 - уже указатель. Вы доказываете, что (a+1)-1 тождественно равно a?
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 24 2009, 11:24
Сообщение #44


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(zltigo @ Feb 24 2009, 14:12) *
Ну и моему взгдляду приятнее
Код
char *test1 = "hello";
char *test2 = "test1 hello test2";

нежели []
Так вроде как создаются ещё и лишние переменные типа указатель на строку, а в случае с [] нет.
И ещё у Вас в примере опечатка: не та последовательность аргументов - надо (test2, test1)....


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
west329_
сообщение Feb 24 2009, 11:38
Сообщение #45


Местный
***

Группа: Свой
Сообщений: 378
Регистрация: 10-09-07
Из: UKR/Voz
Пользователь №: 30 423



Код
__flash  char *test_   = "hello";
__flash  char *test_1 = "test1 hello test2";

void test (void)
{
  char *p1, *p2, *p3;

  p3 = strstr( test_1, test_);
}


если так писать то у меня происходит дублирование данных, в SRAM и FLASH
если через --string_literals_in_flash, то нет ,
но код неработает.

Цель сделать поиск в буфере строки которая сидит во флеш памяти. Хочется использовать готовую процедуру.
похожее на это :
Код
__flash  char *test_   = "hello";
char test_1[350] = "test1 hello test2";

void test (void)
{
  char  *p3;

  p3 = strstr( test_1, test_);
}

тако реально сделать ?

Сообщение отредактировал west329_ - Feb 24 2009, 12:02
Go to the top of the page
 
+Quote Post
msalov
сообщение Feb 24 2009, 11:41
Сообщение #46


Знающий
****

Группа: Свой
Сообщений: 526
Регистрация: 24-08-07
Из: Беларусь, Минск
Пользователь №: 30 045



Цитата(west329_ @ Feb 24 2009, 13:38) *
Код
__flash  char *test_   = "hello";
__flash  char *test_1 = "test1 hello test2";

void test (void)
{
  char *p1, *p2, *p3;

  p3 = strstr( test_1, test_);
}


если так писать то у меня происходит дублирование данных, в SRAM и FLASH

Откуда дублирование? Во FLASH строки, а в SRAMе - указатели, правда не для всех платформ sad.gif
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 24 2009, 11:42
Сообщение #47


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(west329_ @ Feb 24 2009, 14:38) *
[code]__flash char *test_ = "hello";
__flash char *test_1 = "test1 hello test2";

Надо:
char __flash test2[] = "test1 hello test2";
И ещё. Задумайтесь: функция strstr знает что Вы решили использовать flash для хранения строк вместо ОЗУ?
Или IAR (или что Вы там используете) шибко умный. В GCC надо другую (заточенную flash строки) функцию вызывать.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
msalov
сообщение Feb 24 2009, 11:47
Сообщение #48


Знающий
****

Группа: Свой
Сообщений: 526
Регистрация: 24-08-07
Из: Беларусь, Минск
Пользователь №: 30 045



Цитата(demiurg_spb @ Feb 24 2009, 13:42) *
char* __flash test2 = "test1 hello test2";

Такая конструкция вообще мало имеет смысла :/ Зачем нужен указатель хранящийся во флеш, который ссылается на строку, которая скорее всего тоже пойдёт во флеш?
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 24 2009, 11:49
Сообщение #49


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Я через минуту раздумий удалил этот пример. Вы опередилиsmile.gif
Это ещё раз показывает, что [] лаконичнее.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
west329_
сообщение Feb 24 2009, 12:05
Сообщение #50


Местный
***

Группа: Свой
Сообщений: 378
Регистрация: 10-09-07
Из: UKR/Voz
Пользователь №: 30 423



Цель сделать поиск в буфере строки которая сидит во флеш памяти. Хочется использовать готовую процедуру.

Пиблизительно похожее на это :

Код
__flash  char *test_   = "hello";
char test_1[350] = "test1 hello test2";

void test (void)
{
  char  *p3;

  p3 = strstr( test_1, test_);
}


Это реально сделать с помощью strstr? или надо свою процедуру писать, чтоб понимала строку с озу и с пзу ?

Сообщение отредактировал west329_ - Feb 24 2009, 12:07
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 24 2009, 12:07
Сообщение #51


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(west329_ @ Feb 24 2009, 15:05) *
Цель сделать поиск в буфере строки которая сидит во флеш памяти. Хочется использовать готовую процедуру.
тако реально сделать ? или надо свою процедуру писать
Для начала изучите библиотеку прежде чем сыпать вопросами, если не найдёте подходящей функции то тогда и поговорим.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Feb 24 2009, 12:08
Сообщение #52


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(demiurg_spb @ Feb 24 2009, 14:24) *
Так вроде как создаются ещё и лишние переменные типа указатель на строку, а в случае с [] нет.

Вроде! Вы просили создавать переменую с указателем? Нет? Так от какой сырости "создаются". Зачем фантазировать?


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 24 2009, 12:24
Сообщение #53


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(zltigo @ Feb 24 2009, 13:12) *
Ну и моему взгдляду приятнее
Код
char *test1 = "hello";
char *test2 = "test1 hello test2";

нежели []
Приятнее - возможно. Но есть маленькая разница: sizeof(test1) даст в случае [] размер памяти, выделенной под строку, а в случае * - размер указателя.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 24 2009, 12:34
Сообщение #54


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(zltigo @ Feb 24 2009, 15:08) *
Вроде! Вы просили создавать переменую с указателем? Нет? Так от какой сырости "создаются". Зачем фантазировать?

Конечно просил.
Ведь код
char* name = "Вася";
означает создать переменную типа char* с именем name и проинициализировать ее.
Где я ошибаюсь? Об этом я даже в мануале на avr-gcc читал.

Я не поленился и прогнал такой тест в gcc 4.3.2
и получил разницу в объёме использования ОЗУ на 2 байта в пользу [] естественно.
Зато флеши больше съело на 8 байт с какого-то перепугу - этого я не понялsad.gif
Код
char* name = "Вася";
//char name[] = "Вася";
volatile int i;

int main(void)
{
    i = strlen(name);
    return (0);
}


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
msalov
сообщение Feb 24 2009, 12:50
Сообщение #55


Знающий
****

Группа: Свой
Сообщений: 526
Регистрация: 24-08-07
Из: Беларусь, Минск
Пользователь №: 30 045



Цитата(demiurg_spb @ Feb 24 2009, 14:34) *
Я не поленился и прогнал такой тест в gcc 4.3.2
и получил разницу не в пользу char*.

Тут отличия гораздо глубже.
Код
char name[] = "Вася";
- создать массив длинны 5 байт и инициализировать его значением.
Код
char *name = "Вася";
- создать указатель на const char, то есть правильнее было бы
Код
const char *name = "Вася";
, причём при использовании не забываем что даже если объявим без const - "Вася" останется константным.
Прошу обратить внимание что это два объявления не эквивалентны что бы их сравнивать на лучше/хуже без учёта конкретного применения.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Feb 24 2009, 13:20
Сообщение #56


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(gotty @ Feb 24 2009, 15:50) *
Тут отличия гораздо глубже.

Разумеется. Речь идет о более-менее частном случае.
Цитата
то есть правильнее было бы
Код
const char *name = "Вася";
,

Вообще для полного целеуказания:
Код
char const * const name = "Вася";

Ну или соответственно специализированные квалификаторы для гарвардообразных


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 24 2009, 13:38
Сообщение #57


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(gotty @ Feb 24 2009, 15:50) *
Тут отличия гораздо глубже.
Глубже-мельче...
В чистом виде (без static const) разница конкретная: в одном случае созаётся лишь массив, а в другом ещё и указатель на него. Вот и всё. Кому что нужно тот то и выбирает для себя. С константным указателем на константную строку наверняка могут быть варианты - будет зависеть от IQ компилятора.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
west329_
сообщение Feb 24 2009, 14:14
Сообщение #58


Местный
***

Группа: Свой
Сообщений: 378
Регистрация: 10-09-07
Из: UKR/Voz
Пользователь №: 30 423



Код
__flash  char test_[] = "hello";
char test_1[] = "test1 hello test2";


void test (void)
{
  char *p1, *p2, *p3;

  p1 = (char*)& test_[0];
  p2 =        & test_1[0];
  
  p3 = strstr( p2, p1);
}


Это бред ?
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 24 2009, 14:22
Сообщение #59


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(west329_ @ Feb 24 2009, 17:14) *
Это бред ?
Вы на кофейной гуще гадаете что-ли? Документацию читали? Какие функции нашли? В отладчике (можно AVR-Studio) прогоняли? Какой компилятор? Делов на 20 минут. А вы... Ложку дай...
Файлик <pgmspace.h> смотрели - там все функции для работы с falsh.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
west329_
сообщение Feb 25 2009, 06:12
Сообщение #60


Местный
***

Группа: Свой
Сообщений: 378
Регистрация: 10-09-07
Из: UKR/Voz
Пользователь №: 30 423



Код
__x_z int strcatstrncmpstrncmp(const void *, PGM_VOID_P, size_t);
__x_z void *memcpy_P(void *, PGM_VOID_P, size_t);
__x_z char *strcat_P(char *, PGM_P);
__x_z int strcmp_P(const char *, PGM_P);
__x_z char *strcpy_P(char *, PGM_P);
__x_z char *strncat_P(char *, PGM_P, size_t);
__x_z int strncmp_P(const char *, PGM_P, size_t);
__x_z char *strncpy_P(char *, PGM_P, size_t)


Аналогично функции strstr, ненашол.
Копилятор IAR AVR CLIB
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 25 2009, 08:05
Сообщение #61


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(west329_ @ Feb 25 2009, 09:12) *
Аналогично функции strstr, ненашол.
Копилятор IAR AVR CLIB
Вы Молодец. Теперь делаем вывод, что без дополнительных усилий Вашу задачу не решить.
Но есть очень простой способ (с использованием временного буфера - будет отъедать ОЗУ).
Пишите свою функцию, которая ищет в строке s1 (из ОЗУ) подстроку s2 (из flash)
Код
char* strstr_P(const char* s1, flash char* s2)
{
    #define MAX_STR_LEN    50            // допустим 50
    char buf[MAX_STR_LEN];
    strncpy_P(buf, s2, MAX_STR_LEN);     // копируем flash в buf
    buf[MAX_STR_LEN-1] = '\0';           // null в любом случае должен быть
    return  strstr(s1, buf);             // вызываем библиотечную функцию.
}

Вариант 2: пишите полностью с нуля функцию char* strstr_P(const char* s1, flash char* s2) без буферизации.
Вариант 3: отказываетесь от использования flash.
Всё в Ваших руках...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
west329_
сообщение Feb 25 2009, 10:20
Сообщение #62


Местный
***

Группа: Свой
Сообщений: 378
Регистрация: 10-09-07
Из: UKR/Voz
Пользователь №: 30 423



Всё работает как надо, благодарю за помощь. За ради интереса, собрал несколько аналогичных функций.
Код
char* strstr_P(const char* s1, flash char* s2)
{
    size_t len;
    len = strlen_P(s2);
    char *buf;  
    buf = malloc(len);
    strncpy_P(buf, s2, len);
    return  strstr(s1, buf);
}

самый прожорлевый вариант. прибавил сразу ~240kb
Код
char* strstr_P(const char* s1, flash char* s2)
{
    #define MAX_STR_LEN    30            // äîïóñòèì 30    
    char buf[MAX_STR_LEN];
    char len = strlen_P(s2);
    strncpy_P(buf, s2, len);     // êîïèðóåì flash â buf
    buf[len] = '\0';
   return  strstr(s1, buf)
}

немного меньше, но всёравно порядка 150кб
ваш код самый маленьки оказался, порядка 100кб
Go to the top of the page
 
+Quote Post
msalov
сообщение Feb 25 2009, 10:53
Сообщение #63


Знающий
****

Группа: Свой
Сообщений: 526
Регистрация: 24-08-07
Из: Беларусь, Минск
Пользователь №: 30 045



Цитата(west329_ @ Feb 25 2009, 12:20) *
Код
char* strstr_P(const char* s1, flash char* s2)
{
    #define MAX_STR_LEN    30
    char buf[MAX_STR_LEN];
    char len = strlen_P(s2);
    strncpy_P(buf, s2, len);
    buf[len] = '\0';
   return  strstr(s1, buf)
}

Советую не использовать этот вариант. Так как у вас тут потенциальное переполнение буфера. Безопасный вариант
Код
char* strstr_P(const char* s1, flash char* s2)
{
    #define MAX_STR_LEN    30
    char buf[MAX_STR_LEN];
    strncpy_P(buf, s2, MAX_STR_LEN);
    buf[MAX_STR_LEN - 1] = '\0';
   return  strstr(s1, buf);
}
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 25 2009, 11:06
Сообщение #64


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(west329_ @ Feb 25 2009, 13:20) *
Всё работает как надо, благодарю за помощь. За ради интереса, собрал несколько аналогичных функций.
Эксперементировать надо с умом (простите, но гляда на то что Вы пишите у меня сердце кровью обливается).
Купите книжку по СИ и перечитайте её несколько раз - эти трудозатраты с лихвой окупятся.
Для общего развития:
1. На каждый malloc() должен быть свой free().
2. strncpy(s1,s2,n) копирует строку s2 в s1, но не более n символов, поэтому нас не интересует длина s2,
т.к. любая строка заканчивается '\0', а приёмный буфер (строка s1) имеет максимальную длину не меньше n.
И ещё, прикинте сколько машинных циклов добавят вызовы этих процедур: malloc() и free().
Да, можно еще немного оптимизировать:
Код
char* strstr_P(const char* s1, flash char* s2)
{
    #define MAX_STR_LEN    30
    char buf[MAX_STR_LEN];
    buf[MAX_STR_LEN - 1] = '\0';
    return  strstr(s1, strncpy_P(buf, s2, MAX_STR_LEN-1));
}


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
A. Fig Lee
сообщение Feb 26 2009, 02:10
Сообщение #65


Знающий
****

Группа: Участник
Сообщений: 974
Регистрация: 4-04-08
Из: далека
Пользователь №: 36 467



то, что возвращает malloc() правильные пацаны проверяют на NULL.


--------------------
Верить нельзя никому, даже себе. Мне - можно.
Go to the top of the page
 
+Quote Post

5 страниц V   1 2 3 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 31st July 2025 - 19:07
Рейтинг@Mail.ru


Страница сгенерированна за 0.02267 секунд с 7
ELECTRONIX ©2004-2016