массивы

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Re: массивы

Сообщение vitaly_l » 03.02.2017 19:30:14

enot777 писал(а):Компилятор вас не может обманывать.

Распечатайте, код ассемблера , из примера ТС, в котором компилятор обнуляет массив и приведите, в качестве подтверждения.
Есть в ASM код обнуления массива или вы всё таки заблуждаетесь?


.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: массивы

Сообщение enot777 » 03.02.2017 19:34:46

Ну да, не более чем 2 byte индекс (2^16=65536), иначе ошибка: слишком большой диапазон у массива.
Код: Выделить всё
{$mode objfpc}
type
  TA = array [low(word)..high(word)] of integer;
var
  a: TA;
  i: cardinal;
begin
  for i:=low(a) to high(a) do write(a[i],#32);
  readln;
end.
enot777
новенький
 
Сообщения: 24
Зарегистрирован: 24.11.2016 15:20:58

Re: массивы

Сообщение Лекс Айрин » 03.02.2017 19:35:49

vitaly_l писал(а):такая приблуда ненужного принудительного обнуления - тормознёт в два раза любую программу. Вы явно заблуждаетесь.


Если я правильно помню PE EXE формат, то все инициализированные значения хранятся в отдельном разделе и он целиком загружается в память.. Т. е накладных расходов фактически нет. При этом раздел неинициализированных данных вроде как зачастую пропускается вообще.

При этом, начальную инициализацию переменных (в том числе и программистом) само-собой напрашивается сделать в компиляторе при сборке, а не в самой программе.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: массивы

Сообщение vitaly_l » 03.02.2017 19:42:25

Лекс Айрин писал(а):Если я правильно помню PE EXE формат, то все инициализированные значения хранятся в отдельном разделе и он целиком загружается в память.. Т. е накладных расходов фактически нет.

Это всё должо быть прописано в ASM коде.
Распечатайте, код ассемблера , из примера ТС, в котором компилятор обнуляет массив и приведите, в качестве подтверждения.
Есть в ASM код обнуления массива или вы всё таки заблуждаетесь?

enot777 писал(а):Ну да, не более чем 2 byte индекс (2^16=65536), иначе ошибка: слишком большой диапазон у массива.

Я делаю массивы 1 000 000 и у меня всё прекрасно работает, 1 000 000 явно больше 65 536. Что я делаю не так?
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: массивы

Сообщение Лекс Айрин » 03.02.2017 19:50:58

vitaly_l писал(а):Это всё должо быть прописано в ASM коде.


Оно прописано. Только без кучи справочников, блокнота и океана времени ты его не найдешь. А найдя, с большой долей вероятности не переведешь обратно в паскалевский код. При этом надо еще учитывать настройку сегментов при загрузке программы и пр... и пр... ах да... некоторые команды превращаются в данные. И как раз инициализации они и касаются.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: массивы

Сообщение vitaly_l » 03.02.2017 20:06:10

Лекс Айрин писал(а):Оно прописано. Только без кучи справочников, блокнота и океана времени ты его не найдешь. А найдя, с большой долей вероятности не переведешь обратно в паскалевский код. При этом надо еще учитывать настройку сегментов при загрузке программы и пр... и пр... ах да... некоторые команды превращаются в данные. И как раз инициализации они и касаются.

Компилируем с -Al и смотрим. Обнуляет или нет?

Добавлено спустя 1 час 9 минут 46 секунд:
Я кстати, обманул топик стартера и всех. Всё наоборот, если: isFound=0; то, цикл останавливается и пишется в b, а если isFound не равно 0, то цикл крутится вечно.
Код: Выделить всё
program ex;
const a=10;
type
  arr=array[1..a] of integer;

var
  b : arr;
  element : integer;
  i, j, isFound : integer;
Begin
  for i:=1 to a do
    begin
      repeat
         Write( Utf8ToAnsi('Введите '),i,Utf8ToAnsi('-й элемент: ') );
         ReadLn(element);
         isFound := 0;
         for j:=1 to i do
           if b[j]=element then begin
               isFound:=1;
               Break;
           end;
           if isFound=1 then WriteLn(Utf8ToAnsi('Введённое значение уже есть в массиве. Вводите ещё раз!'),b[j])
      until isFound=0;
      b[i] := element;
      WriteLn(Utf8ToAnsi('Ведено новое значение'),b[i]);
  end;
end.   
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: массивы

Сообщение Nick245 » 03.02.2017 22:02:34

А если написть
Код: Выделить всё
for j:=1 to i-1 do
не будет точнее??
Nick245
новенький
 
Сообщения: 10
Зарегистрирован: 22.01.2017 00:31:07

Re: массивы

Сообщение enot777 » 03.02.2017 22:14:30

Nick245
Это будет слишком просто.
vitaly_l
Как бы ничего не изменилось.
enot777
новенький
 
Сообщения: 24
Зарегистрирован: 24.11.2016 15:20:58

Re: массивы

Сообщение sign » 04.02.2017 07:30:00

Я всегда инициирую данные.
Типа вот так:
Код: Выделить всё
  FillChar(V, SizeOf(V), 0);

Быстро, эффективно, не затратно и голова не болит!
sign
энтузиаст
 
Сообщения: 1131
Зарегистрирован: 30.08.2009 09:20:53

Re: массивы

Сообщение beria » 04.02.2017 08:38:43

enot777 писал(а):Про TP3 не скажу, а такая программа на TP7 выведет на экран нули


Про TP3 и даже про TP5 я скажу )))) Далее уже другим занимался.
А про далее... я тоже попробовал явно не инициализировать кусок своего кода. Вроде все работает...
Код: Выделить всё
function TStack.Get: _T;
var
   Buf: _T;
begin
   if Counter>0 then
      Result := Top^.Data
   else
   begin
      //FillChar(Buf, SizeOf(_T), #0);
      Result := Buf;
   end;
end;
     

Следующий шаг - будет ли оно работать всегда нормально, то есть отдавать нули при нулевом Сountere ежели от функции оставить огрызок вида
Код: Выделить всё
function TStack.Get: _T;
begin
   if Counter>0 then
      Result := Top^.Data;
end;

Или в пределе, ну ежели статические переменные всегда заполняются нулем, ежели не используются... Хотя это уж совсем бред.
Код: Выделить всё
function TStack.Get: _T;
begin
      Result := Top^.Data;
end;

Но все равно вот такие предупреждения компилятора при явных операциях c не инициализированной переменной меня вот напрягают. Я очень привык верить сообщениям и рекомендациям компилятора ибо уже были прецеденты...
Код: Выделить всё
stack.pas(77,11) Warning: Локальная пеpеменная "i" не инициализиpована
Аватара пользователя
beria
постоялец
 
Сообщения: 130
Зарегистрирован: 29.09.2016 08:57:13

Re: массивы

Сообщение vitaly_l » 04.02.2017 09:06:34

beria писал(а):Или в пределе, ну ежели статические переменные всегда заполняются нулем, ежели не используются... Хотя это уж совсем бред.

Она пишет ноль, потому что, на момент создания переменной, в ячейке было пусто. А если-бы в ячейке был бы мусор, то вместо нуля был-бы мусор. Посмотрите уже ассемблерный код и убедитесь, что asm - задаётся только адрес и нет никакого обнуления, потому что, принудительное бесконтрольное обнуление - это слишком затратная процедура, при больших массивах. Сомневаюсь, что разработчики, подкинули такую бяку всем.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: массивы

Сообщение Лекс Айрин » 04.02.2017 09:59:25

vitaly_l писал(а):Компилируем с -Al и смотрим. Обнуляет или нет?


И будет твое обновление выглядеть как
Код: Выделить всё
dim1 db  150 dup (0)

что есть не более чем команда ассемблеру зарезервировать 150 байт и забить их нулями.

vitaly_l писал(а):потому что, принудительное бесконтрольное обнуление - это слишком затратная процедура, при больших массивах.

Угу... если подходить к нему прямо
Код: Выделить всё
xor eax,eax

но есть и более продвинутые методы, типа

Код: Выделить всё
cld ;снять флаг DF
mov di, [адрес_массива]
mov cx, размер_массива
sub al, al ;обнуляем записываемый байт
rep stosb ;обнуляем массив байтов


Но даже этого никто не будет делать просто так... ибо нет смысла.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: массивы

Сообщение vitaly_l » 04.02.2017 10:31:18

Лекс Айрин писал(а):И будет твое обновление выглядеть как

БУДЕТ или УЖЕ ВЫГЛЯДИТ???
Домыслы оставьте телепатам и вангинаторам, а художникам нужны: неопровержимые факты из ассемблера.
Факты есть? В коде ассемблера при создании глобальных переменных принудительно присваивается ноль или нет?
Если ответ "ДА" - значит нужно писать в баг-трекер, т.к. компилятор врёт, что 0 не инициализирован, т.к. 0 - это инициализированная переменная.
Если ответ "НЕТ" - то многим программистам, которые: нагло не инициализируют переменные - имеет смысл пересмотреть свой код.

.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: массивы

Сообщение Лекс Айрин » 04.02.2017 10:57:15

vitaly_l писал(а): В коде ассемблера при создании глобальных переменных принудительно присваивается ноль или нет?

Смотря что под этим подразумевать. Фактически, да. Если только речь идет о конкретной ассемблерной команде, то вряд ли. Если честно, то мне просто пофиг. Это абсолютно ничего не меняет.
vitaly_l писал(а):Если ответ "ДА" - значит нужно писать в баг-трекер, т.к. компилятор врёт, что 0 не инициализирован, т.к. 0 - это инициализированная переменная.


Пиши.... если тебя пошлют пятиэтажным матом, то я предупреждал. Хотя, скорее всего, просто поржут как над нубом... оно тебе надо? Это не баг, а фича созданная из-за привычки некоторых забывать про инициализацию переменных. Так что все правильно компилятор говорит. Другое дело, что иногда есть смысл не заморачиваться с инициализацией так-как переменная инициализируется не так и не там, где ожидается.

vitaly_l писал(а):Если ответ "НЕТ" - то многим программистам, которые: нагло не инициализируют переменные - имеет смысл пересмотреть свой код.


А вот это как раз нужно делать независимо от результатов стандартной инициализации. Программист должен в таких вещах быть параноиком... иначе получится как в сишных программах, которые взламывают все, кому не лень, из-за того, что программисты забывают о стандартных проверках на выход за пределы циклов и прочую "мелочь".

Добавлено спустя 33 минуты 58 секунд:
Для особо упертых художников Вот прога:
Код: Выделить всё
program project1;
var
  arr:array[1..10] of integer;
begin
end.

вот инициализация массива:
Код: Выделить всё
.section .bss
   .balign 4
# [3] arr:array[1..10] of integer;
U_$P$PROJECT1_$$_ARR:
   .zero 40

И вот полный ассемблерный листинг
Код: Выделить всё
   .file "project1.lpr"
# Begin asmlist al_procedures

.section .text.n__main,"x"
   .balign 16,0x90
.globl   PASCALMAIN
PASCALMAIN:
.globl   _main
_main:
# [project1.lpr]
# [4] begin
   pushl   %ebp
   movl   %esp,%ebp
   call   FPC_INITIALIZEUNITS
# [5] end.
   call   FPC_DO_EXIT
   leave
   ret
# End asmlist al_procedures
# Begin asmlist al_globals

.section .bss
   .balign 4
# [3] arr:array[1..10] of integer;
U_$P$PROJECT1_$$_ARR:
   .zero 40

.section .data.n_INITFINAL,"d"
   .balign 4
.globl   INITFINAL
INITFINAL:
   .long   3,0
   .long   INIT$_$SYSTEM
   .long   0
   .long   INIT$_$FPINTRES
   .long   0,0
   .long   FINALIZE$_$OBJPAS

.section .data.n_FPC_THREADVARTABLES,"d"
   .balign 4
.globl   FPC_THREADVARTABLES
FPC_THREADVARTABLES:
   .long   1
   .long   THREADVARLIST_$SYSTEM

.section .data.n_FPC_RESOURCESTRINGTABLES,"d"
   .balign 4
.globl   FPC_RESOURCESTRINGTABLES
FPC_RESOURCESTRINGTABLES:
   .long   0

.section .data.n_FPC_WIDEINITTABLES,"d"
   .balign 4
.globl   FPC_WIDEINITTABLES
FPC_WIDEINITTABLES:
   .long   0

.section .data.n_FPC_RESSTRINITTABLES,"d"
   .balign 4
.globl   FPC_RESSTRINITTABLES
FPC_RESSTRINITTABLES:
   .long   0

.section .fpc.n_version
   .balign 16
   .ascii   "FPC 3.0.0 [2015/11/16] for i386 - Win32"

.section .data.n___heapsize,"d"
   .balign 4
.globl   __heapsize
__heapsize:
   .long   0

.section .data.n___fpc_valgrind,"d"
.globl   __fpc_valgrind
__fpc_valgrind:
   .byte   0
# End asmlist al_globals


Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: массивы

Сообщение zub » 04.02.2017 12:34:48

>>Для особо упертых художников Вот прога:
>>вот инициализация массива:
>>И вот полный ассемблерный листинг
С тебя еще вот такое:
>>И вот выдержка из документации, где написано что это происходит всегда и на всех платформах.
Нет такого - значит то, что ты приводишь - часный случай
и сообщения
Warning: Variable "arr" does not seem to be initialized

Нужно устранять иначе будут проблемы на других платформах.

зы. инициализация - удел глобальных переменных, а их используют только художники (да еще и гиганские массивы...) Людям с техническим образованием должно быть стыдно за глобальные переменные.

зыы.
Код: Выделить всё
program project1;
var
  s:string;
begin
  if s<>'' then
    readln;
end.

project1.lpr(5,6) Warning: Variable "s" of a managed type does not seem to be initialized

да managed переменная обязательно всегда инициализируется. но никто не обещает чем
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

Пред.След.

Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 26

Рейтинг@Mail.ru