Casa
Top.Mail.Ru Yandeks.Metrika
Fórum: "Agarrar";
Arquivo atual: 2002.09.12;
Download: [xml.tar.bz2];

Para baixo

--- | O ramo foi sem título | --- Encontre agências semelhantes


VEG   (2002-08-10 23:18) [0]

Código de segurança: segurança em primeiro lugar! Melhor evitar problemas com antecedência!

Nome interessante? É isso aí! Acontece que existe esse tipo de código! Você não pode imaginar até que ponto pode ser seguro! Acontece que, para remover os três últimos caracteres da string, você precisa escrever:
var
L: Inteiro;
S: string;
começar
L: = comprimento (S);
Inc (L, -3);
Se L <0, então L: = 0;
SetLength (S, L);
end;
Em vez da linha mais familiar: Se Comprimento (S)> 2, em seguida, Excluir (S, Comprimento (S) -2,3) else S: ​​= ""; A primeira opção é segura e a segunda não! Porque Eu mesmo não sei! Parece que esses trechos de código fazem exatamente a mesma coisa! A única diferença entre esses trechos de código que encontrei é o número de variáveis ​​e linhas de código! Na versão segura, são necessárias uma variável extra e linhas de código de programa 4 e, em condições inseguras, não uma única variável extra e uma linha de código de programa!
Eu aprendi sobre tudo isso em uma conversa com Anatoly Podgoretsky.
Por que estou escrevendo tudo isso? A resposta é simples: quero pedir uma explicação de por que o primeiro trecho de código é seguro e o segundo não.
Na verdade tudo!



VEG   (2002-08-10 23:59) [1]

Aqui está outro código seguro:
se Comprimento (s)> 2, então SetLength (s, Comprimento (s) -3) else S: ​​= "";



TTCustomDelphiMaster   (2002-08-11 08:57) [2]

VEG © (10.08.02 23: 18)
Na minha opinião, todos os três códigos são seguros, apenas o código Anatoly Podgoretsky é mais rápido, menos memória e menos compreensível.

PS: Otimização se Comprimento (s)> 3 e SetLength (s, Comprimento (s) -3) else S: ​​= "";



Anatoly Podgoretsky   (2002-08-11 10:02) [3]

VEG © (10.08.02 23: 18)
Ambas as opções são seguras, pois uma verificação de validação é realizada, mas você distorceu os cartões no segundo caso. Afinal, tratava-se do código Delete (S, Length (S) -2,3) sem verificar If Length (S)> 2
Este código não é seguro.

A segunda coisa que você precisa prestar atenção, embora ambas as opções façam o que você deseja, mas Delete foi projetado principalmente para remover caracteres do interior da string, enquanto SetLength especificamente para alterar seu comprimento para cima e para baixo.

Em uma conversa em um bate-papo, além disso, houve conversas sobre L: = Length (S) -3; em vez de duas linhas como a sua.

Agora, se você remover a distorção dos cartões com a segunda opção, talvez possa descobrir por que a segunda opção não é considerada segura. Não sei para que finalidade você fez isso.



Anatoly Podgoretsky   (2002-08-11 10:26) [4]

TTCustomDelphiMaster © (11.08.02 08: 57)
Este não é o meu código!
E com Excluir não é o meu código!
Sim, e não nas linhas que eu costumo pensar, mas nas operações
Duas tarefas, uma comparação e uma chamada de procedimento.
Esse bate-papo não era sobre esse código, mas especificamente sobre o código VEG para trabalhar com o registro, onde, para todo o código, não há uma única verificação de validação, esse código era apenas uma demonstração do princípio de escrever programas seguros, a propósito, com um link para a ramificação de isso também é usado para indicar quem chamou a atenção para um erro potencial em Excluir, este é o Digitalman, se você fizer isso sem verificar se há valores válidos.

A essência da teoria é por que escrever código com erros, para que mais tarde você gaste tempo depurando, é melhor escrever código imediatamente sem erros.
Se houver parâmetros, eles devem ser verificados, se os recursos forem utilizados, eles devem ser protegidos usando try finally / try, exceto blocos. O programa deve ser verificado não apenas em um conjunto de dados limitado, mas também em condições de contorno, em dados inválidos.
Na teoria de escrever código seguro, existem muitos truques diferentes, mesmo que alguns deles aumentem drasticamente a confiabilidade dos programas, há menos chances de que, durante a operação, um truque saia de algum lugar.



Юрий Зотов   (2002-08-11 10:32) [5]

> Acontece que existe esse tipo de código!

É isso mesmo, existe esse tipo de código. Mais precisamente, não um tipo de código, mas um estilo de programação. Aqui está um exemplo simples, mas ilustrativo:

1 opção:
com TMyObject.Create fazer
começar
...
Grátis
end;

2 opção:
com TMyObject.Create fazer
tentar
...
finalmente
Grátis
end;

Comentários, eu acho, não são obrigatórios. O mesmo se aplica a outras operações "emparelhadas" (GetMem-FreeMem, BeginUpdate-EndUpdate, GetDC-ReleaseDC, SelectObject, OnChange: = nil - OnChange: = OnChangeHandler, etc.).

Outro exemplo

1 opção:
se CreateProcess (..., PI), então
começar
WaitForSingleObject (PI.hProcess, INFINITE);
GetExitCodeProcess (PI.hProcess, ...);
... // faça alguma coisa
CloseHandle (PI.hThread);
CloseHandle (PI.hProcess);
end;

2 opção:
se CreateProcess (..., PI), então
começar
CloseHandle (PI.hThread);
WaitForSingleObject (PI.hProcess, INFINITE);
GetExitCodeProcess (PI.hProcess, ...);
CloseHandle (PI.hProcess);
... // faça alguma coisa
end;

Na primeira modalidade, os recursos do sistema permanecem apreendidos mesmo quando não são realmente necessários e, na segunda, são liberados imediatamente assim que se tornam desnecessários. Parece - pense em um par de alças, um pouco. De fato, um pouco. Mas somente até chegarmos a algo como usar código não seguro (não esse, mas semelhante a ele) dentro de um loop. E então há uma chance real de encontrar uma escassez de recursos e, em seguida, escrever nos fóruns, que tipo de Win9x é o mesmo.

Outro exemplo, sobre um tópico diferente (infelizmente, da minha própria prática).

1 opção:
N: = 0;
para i: = 1 em Comprimento (StringList.Text) faça
se StringList.Text [i] = "A", então N: = N + 1;

2 opção:
S: = StringList.Text;
N: = 0;
para i: = 1 para Length (S)
se S [i] = "A" então Inc (N);

A segunda opção armazena em cache a propriedade Text e usa Inc e, portanto, é executada muitas vezes mais rapidamente que a primeira (principalmente devido ao armazenamento em cache, é claro). A propósito, um truque semelhante no módulo VBA (propriedades do objeto de cache - Pasta de trabalho etc.) tornou possível acelerar as macros deste módulo várias dezenas (!!!) vezes (também um caso real da prática).

Outro exemplo, aparentemente completamente inocente.

procedimento TMyCollection.Update (Item: TCollectionItem);
começar
... // faça alguma coisa
end;

Não há chamada para herdar aqui. Parece que ele não é necessário - na classe ancestral, o método Update está vazio, existe apenas o começo. No entanto, imagine que as mudanças apareceram em alguma versão do Delphi e esse método se tornou não vazio. Isso é tudo, grande olá - a partir deste momento, nosso código cuidadosamente depurado e impecavelmente funcionando pode começar a falhar. E, durante muito tempo, vamos entender a causa de um fenômeno tão estranho. E se eles escrevessem imediatamente herdado - eles não teriam nenhum problema.

Outro exemplo é a supressão de um erro em potencial (com a ajuda de try-except, ou se ou de alguma outra maneira - isso não importa). Como resultado, o programa parece funcionar, mas não funciona corretamente (a propósito, isso ainda precisa ser percebido, e quanto antes melhor, porque as consequências podem ser desastrosas). E tudo porque o programador estava com preguiça de lidar com o erro e deveria mascará-lo. E ela, é claro, não desapareceu em lugar nenhum, ela simplesmente não é visível.

===== ver continuação =====



Юрий Зотов   (2002-08-11 10:46) [6]

===== continuação =====

Outro exemplo, com sua permissão.

1 opção:
se <condição 1> e <condição 2> então ...

2 opção:
se <condição 1> então
se <condição2> então ...

Parece ser a mesma coisa? Mas não - o resultado da primeira opção pode depender de qual opção é compilada (esquema curto ou completo para calcular expressões booleanas). E o segundo - não depende. Aqui está outra fonte oculta de erros na primeira versão (especialmente durante o trabalho em grupo em um projeto, quando as opções do compilador para diferentes programadores podem variar).

E há muitos exemplos semelhantes de gargalos. Essas são quase todas as operações que estão explícita ou implicitamente relacionadas à alocação de memória e outros recursos. Essa é a velocidade das operações. Essa é uma otimização de loops (remoção de invariantes etc.), e não apenas dos loops (mesmo a ordem das ramificações na instrução de caso também é importante - é aconselhável ordená-las em ordem crescente, de forma mais rápida). Essa negligência dos recursos da aritmética da máquina (especialmente o ponto flutuante). Isso é para desativar verificações fora do intervalo (pelo menos durante a fase de depuração do programa). É o uso de recursos não documentados ou detalhes de implementação interna. Este é um marcador nas opções padrão do compilador. Este também é um indicador da ordem dos módulos em uso (um tipo de erro raro, mas muito difícil de localizar). Essa negligência das dicas e avisos do compilador (eu pessoalmente vi como uma pessoa se esqueceu de escrever sobrepor na declaração do destruidor e não deu a mínima para a mensagem do compilador - um vazamento de memória é quase garantido).

Isso ... bem, em geral, esse é praticamente todo o nosso programa.

Obviamente, o código absolutamente seguro não existe em princípio, mas está ao nosso alcance torná-lo mais seguro. E MUITO mais. Outra coisa é que você não deve se tornar paranóico e aplicar verificações sempre que necessário e não necessário.

Portanto, conselhos a todos os programadores iniciantes - desde o início, tente desenvolver um estilo competente e seguro para si mesmo. Ele deve se tornar um hábito, tornar-se apenas um estereótipo. E você nunca escreverá o começo em vez de tentar (veja o primeiro exemplo) - o piloto automático não permitirá.

E como desenvolvê-lo? Muito simples - atenção e precisão. Por mais estranho que pareça, um estilo seguro começa com as coisas mais simples - formatação de texto, nomes semânticos, manutenção de casos etc. Bem, é claro, você precisa pensar literalmente em cada colchete.

Em geral, você só precisa se acostumar com a precisão. Sem isso, com certeza, nada funcionará, e o resto virá com experiência.

Desculpe pela postagem longa. Sua única justificativa pode ser que ele possa ser útil a alguém. : o)



Anatoly Podgoretsky   (2002-08-11 11:15) [7]

Obrigado Yuri Zotov, como sempre implantado.
No bate-papo, conversamos sobre código específico, linhas de trabalho do 10 com o registro, o argumento foi tão sim que tudo funciona!
E, por exemplo, com herdado, está conectado com essa discussão recente, sobre a exclusão (truncando uma linha) por três caracteres no final, houve um argumento sobre diferentes versões do compilador que você não deve estar vinculado à implementação interna de uma ou outra versão do compilador, problemas são inevitáveis. Indo para uma reunião de programadores sem escrúpulos, Borland mudou a implementação da função Excluir, agora funciona da seguinte maneira

Se o índice for maior que o comprimento do S ou menos que 1, nenhum caractere é excluído.

Nas versões do 5 e abaixo

Se o Índice for maior que o comprimento de S, nenhum caractere será excluído.

Existe uma grande diferença, mas, de acordo com Digman, isso não funciona como deveria, não há exclusão de caracteres se o comprimento da string for menor que Index, mas ainda era necessário excluir, aqui eles faziam apenas proteção contra o índice que ia além. A opção com SetLength ou a mesma para Excluir, com verificação e ajuste do índice, funciona bem e demonstra os princípios de escrever um código seguro.



VEG   (2002-08-11 12:52) [8]

Isso é tudo! Eu descobri!
É tudo sobre velocidade !!!
Para verificação, usei os seguintes trechos de código:
Para o primeiro cofre:
var L: Inteiro; S: String; Tempo: Inteiro; FTD: Inteiro; começar Hora: = GetTickCount; Para FTD: = 1 para 1000000, faça começar S: = "ABC"; L: = comprimento (S); Inc (L, -3); Se L <0, então L: = 0; SetLength (S, L); fim; Hora: = GetTickCount-Time; Label1.Caption: = IntToStr (Tempo);

Para o segundo cofre:
var S: String; Tempo: Inteiro; FTD: Inteiro; começar Hora: = GetTickCount; Para FTD: = 1 a 1000000, faça começar S: = "ABC"; Se Comprimento (S)> 2, então SetLength (S, Comprimento (S) -3) else S: ​​= ""; fim; Hora: = GetTickCount-Time; Label1.Caption: = IntToStr (Tempo);

Para inseguros:
var S: String; Tempo: Inteiro; FTD: Inteiro; começar Hora: = GetTickCount; Para FTD: = 1 a 1000000, faça começar S: = "ABC"; Se Length (S)> 2, em seguida, Delete (S, Length (S) -2,3) else S: ​​= ""; fim; Hora: = GetTickCount-Time; Label1.Caption: = IntToStr (Tempo);
Ambas as opções seguras apresentaram excelentes resultados! O primeiro seguro lidou em média com o 110 ms., E o segundo - 124 ms. !!! A opção insegura está MUITO atrás dos seus concorrentes. Seu resultado médio é 890 !!!
Para referência: todos os testes foram realizados em um processador Pentium III - 550Mhz.
PS: Neste momento vou ler o que você escreveu :-)



VEG   (2002-08-11 13:08) [9]

> Anatoly Podgoretsky
> Ambas as opções são seguras, porque uma verificação de validação é realizada, mas você distorceu os cartões no segundo caso. Afinal, tratava-se do código Delete (S, Length (S) -2,3) sem verificar If Length (S)> 2
Este código não é seguro.
Você se lembra de como eu lhe disse para adicionar a este código uma verificação da falta de caracteres? Foi isso que eu quis dizer!
> A segunda coisa em que você precisa prestar atenção, embora ambas as opções façam o que você deseja, mas Delete foi projetado principalmente para remover caracteres do interior da string, enquanto SetLength foi projetado para alterar seu comprimento para cima e para baixo.
Eu concordo!
> Em uma conversa em um bate-papo, além disso, houve conversas sobre L: = Length (S) -3; em vez de duas linhas como a sua.
Me desculpe Conversamos de manhã e escrevi o texto à noite. Não guardei cópias da conversa. Errado!
> A conversa no bate-papo não estava falando sobre esse código, mas especificamente sobre o código VEG para trabalhar com o registro, onde não há uma única verificação de validação em todo o código, esse código era apenas uma demonstração do princípio de escrever programas seguros, a propósito, com um link para uma filial de onde vem e uma indicação de quem chamou a atenção para um possível erro em Excluir, este é o Digitalman, se você fizer isso sem verificar se há valores válidos.
Sim Foi um acordo! Mas! Em primeiro lugar, este não é todo o código, e esse código não demonstra meu estilo de programação. Você disse que há mais erros nesse código do que linhas! Isso não é verdade! A única coisa que precisa ser feita é colocar todo o código em teste ... exceto !!! Mas pode haver um erro nas opções 1 / 1000000. Aqui está a pergunta original: http://delphi.mastak.ru/cgi-bin/forum.pl?look=1&id=1025549197&n=2
> A essência da teoria é por que escrever código com erros, para que mais tarde você gaste tempo depurando, é melhor escrever código imediatamente sem erros.
Expressei essa idéia de uma forma diferente: "É melhor se proteger antecipadamente dos problemas!" :-)

PS: Agora vou ler o texto de "Yuri Zotov"



VEG   (2002-08-11 13:43) [10]

> Yuri Zotov
Obrigado por uma explicação tão detalhada! Algo semelhante não faria mal para publicar na seção do artigo.
> Outra coisa é que você não deve se tornar paranóico e aplicar verificações sempre que necessário e não necessário.
E isso é o principal!

> Anatoly Podgoretsky
No jogo eu uso um monte de manipulação de erros. Somente erros 4 podem realmente ocorrer:
1. A placa de vídeo não suporta o modo de vídeo necessário.
2. Questionário danificado.
3. A ausência de todos os arquivos do jogo (exceto o EXE-shnik, naturalmente).
4. A falta de uma placa de som ou decodificador MPEG-3.
No primeiro caso, uma mensagem de não conformidade é exibida e, EMBUTIDO, SOLUÇÃO DE PROBLEMAS.
No segundo e terceiro casos, o programa INICIARÁ sem problemas e erros! O host explicará cuidadosamente o problema ao usuário e informará como corrigi-lo!
No quarto caso, o programa bloqueará o som. Se houver uma placa de som, ela será enviada ao meu site para um decodificador.
Eu amo escrever código ordenadamente. O que você vê nos fóruns são aqueles recados que ainda são pouco estudados por mim. Eles não ilustram o código que está escrito no jogo.
Não sei o que você tem com o IE, apenas você tem essas fontes. Meu site não é tão assustador. Outra coisa é o programa. Além do Windows, ela não precisa de nada, tudo será exibido lá, como deveria! E o jogo é muito bonito! É seguro, e o risco que você me disse é reduzido a zero!
Em geral, para ser sincero, a maioria dos programas na Internet é escrita com código não seguro.



VEG   (2002-08-11 17:06) [11]

Curiosamente, mas meu código sugerido aqui (http://delphi.mastak.com/cgi-bin/forum.pl?look=1&id=1027684797&n=7) é seguro?



Anatoly Podgoretsky   (2002-08-11 17:10) [12]

VEG © (11.08.02 17: 06)
Não, leia acima sobre comandos emparelhados, tente / finalmente



Юрий Зотов   (2002-08-11 18:40) [13]

> VEG © (11.08.02 17: 06)

Bem, vamos tentar comentar. Naturalmente, apenas desse ponto de vista, como eu o entendo, nada mais. E chur, não se ofenda, ok? Considere isso como uma crítica amigável - o que é.

1. O design do texto ainda deixa muito a desejar (case, recuos, espaços). Um estilo seguro começa com ele.

2. TBitmap.Create - onde está finalmente tentando? Imagine que, no momento de chamar esse procedimento, o Panel1 ou o Image1 já esteja destruído (por exemplo, devido a um erro em um local completamente diferente) - e olá, vazamento de memória.

3. GetDC (0) - onde está finalmente tentando? Concordo que um erro é muito improvável nesta seção do código. Mas se você seguir rigorosamente os cânones da segurança, tente-finalmente não fará mal.

4. GetDC (0) - GetDC mais confiável (GetDesktopWindow). Onde está a garantia de que, na versão Win2005, um identificador nulo ainda significa uma área de trabalho, e não alguns sinos e assobios comuns do tio Billy?

5. PanelPoint: = ClientToScreen (Point (panel1.BoundsRect.Left, panel1.BoundsRect.Top));

Amanhã, seu colega do projeto transferirá o Panel1 do formulário para qualquer outro pai (outro painel, TabSheet etc.) - e o código falhará. Você precisa encaixar no painel em si e não no formulário - por exemplo, você pode usar o MapWindowPoints e um ponto (0,0).

6. ReleaseDC (0, ScreenDC) - consulte o parágrafo 4.

7. Por último - o código está longe de ser o ideal (operações extras, variáveis ​​extras, memória extra).

Eu trago minha opção. Eu acredito que é mais simples, mais curto, mais claro e mais econômico (e todos esses também são componentes de segurança). Observe que, se houver um erro em algum outro lugar do programa, aqui ele não será mascarado, mas, pelo contrário, aparecerá. Se não estava lá, o código funcionará quando qualquer painel se mover ou inovar nosso amado tio Billy.

procedimento TForm1.Button1Click (Sender: TObject); var PanelRect: TRect; ScreenWnd: HWND; ScreenDC: HDC; começar se GetWindowRect (Panel1.Handle, PanelRect), // Verificação implícita Panel1 com Image1.Picture.Bitmap do // Verificação implícita de Image1 começar Largura: = Panel1.Width; Altura: = Panel1.Height; ScreenWnd: = GetDesktopWindow; // Para não ligar duas vezes ScreenDC: = GetDC (ScreenWnd); // Aqui try-finalmente já é supérfluo - se houver um erro, // então ele aparecerá mais cedo. BitBlt (Canvas.Handle, 0, 0, Largura, Altura, ScreenDC, PanelRect.Left, PanelRect.Top, SRCCOPY) ReleaseDC (ScreenWnd, ScreenDC) fim fim;



VEG   (2002-08-11 20:36) [14]

> Anatoly Podgoretsky
> Yuri Zotov
Eu escrevi esse código há muito tempo. Você pode verificar você mesmo olhando a data. Antes, eu não ouvia o conceito de "código seguro" nirazu

> Yuri Zotov
Durante a programação, adquiri o estilo de programação OWN. Aqui está um exemplo:
(******************************** Nome do cabeçalho do código ***************** **************)
Nome da Função (S: String): String; // O que este procedimento faz; Descrição de variáveis, etc.
var
// Nome: Type; // Comentário
FTD: Inteiro; // Exemplo
STR: String; // outro exemplo
const
XXX = 0; // E outro exemplo :-)
começar
(* Nome do sub-bloco *)
STR: = "abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc"
+ "abcabcabcabcabc";
Se ... então
começar
Para FTD: = 1 para 100, faça
começar
...
...
end;
fim mais ...;
Se ... então ... mais
começar
...
...
end;
Se ... então
tentar
...
...
exceto
...
...
final
outro
tentar
...
...
finalmente
...
...
end;
Com ... fazer
começar
...
...
end;
Para ... fazer ...;
end; // Copyright sobre o procedimento, data, hora
Você não deve se importar que este exemplo não esteja funcionando! Esta é uma demonstração do meu estilo. Entenda! É muito mais conveniente para mim! O código parece uma imagem!

Aqui, por exemplo, parece um fragmento com variáveis ​​no meu jogo:

(************************* Parâmetros básicos da pergunta (Tags) ******************* *****) BasePass: String; // Senha para acessar o questionário BaseName: String; // Nome do questionário BaseNumAllQA: Inteiro; // Total de perguntas no questionário BaseAutor: String; // Autor do questionário BaseTopic: String; // Assunto geral do questionário BaseLoads: Inteiro; // Total de bancos de dados iniciados (**************************** Trabalhe com bancos de dados de perguntas ********************** *******) BaseFName: String; // nome do arquivo do questionário BaseFile: TextFile; // Arquivo base da pergunta QA: matriz [1..15] de Inteiro; // Número de perguntas QABaseAll: array [1..15] de QABaseNum; // Todas as perguntas (************************************** Opções Opções ************ **************************) OnMusic: Booleano = Verdadeiro; // Music OnTimer: Booleano = True; // Timer OnAnime: Booleano = Falso; // Animação MenuTimerSpeed: Inteiro = 20; // Velocidade do temporizador para o menu
Não é um código, mas uma imagem!
Aqui está um dos procedimentos:
(******************************** Procedimentos do sistema ****************** *************) procedure Delay (msegs: Longint); // Aguarde msegs segundos, sem congelar o programa var FirstTick: longint; // TEMP para verificar a hora comece FirstTick: = GetTickCount; repita Application.ProcessMessages; {para não "travar" o Windows} até (GetTickCount-FirstTick> = msegs) ou (GetKeyState (VK_SPACE) <0); fim;

> Anatoly Podgoretsky



Oleg_Gashev   (2002-08-11 20:39) [15]

procedure Delay (msegs: Longint); // Aguarde msegs segundos, sem congelar o programa
var
FirstTick: longint; // TEMP para verificar a hora
comece FirstTick: = GetTickCount;
repita Application.ProcessMessages; {para não "travar" o Windows}
até (GetTickCount-FirstTick> = msegs) ou (GetKeyState (VK_SPACE) <0);
end;

E porque



Oleg_Gashev   (2002-08-11 20:42) [16]

> Esta é uma demonstração do meu estilo.
> QA: matriz [1..15] de número inteiro; // Número de perguntas
> QABaseAll: array [1..15] de QABaseNum; // Todas as perguntas

Estilo ruim. Haverá problemas se você precisar aumentar o número de perguntas.



Oleg_Gashev   (2002-08-11 20:51) [17]

> BaseFName: String; // nome do arquivo do questionário
E se o nome do arquivo contiver mais de caracteres 255?



app   (2002-08-11 20:52) [18]

Sem mencionar que é simplesmente errado, ele só funciona sob certas condições.
1. o valor de retorno não está assinado! DWord, não o icônico LongInt
2. como resultado, ocorrerá um erro com o valor GetTickCount + msecs ~ = 2 ^ 31, ocorrerá um loop ou um atraso no 24 do dia; isso se refere à verificação de operabilidade mencionada anteriormente nos valores-limite.


Se você deseja que um procedimento aqueça o processador, veja como isso é feito no RxLib



VEG   (2002-08-11 22:21) [19]

> Oleg_Gashev
Número de perguntas por CATEGORY. Você não conhece as regras do jogo ??? O jogo tem perguntas do 15. Eu não vou mudar as regras do jogo! E no QABaseAll é armazenada uma matriz dinâmica, definida automaticamente pelo número de perguntas. O número de perguntas é limitado pelo tipo Inteiro * 15 !!!
> E se o nome do arquivo contiver mais de caracteres 255?
O arquivo é armazenado no pai do controle de qualidade junto com o jogo. Esta variável armazena apenas o nome do arquivo, sem extensão e caminho de acesso !!! E o nome do arquivo, como você sabe, é limitado! O erro acabou!
> app
Em primeiro lugar, o valor máximo usado no meu jogo é 10000!
Em segundo lugar, há uma capacidade interna de cancelar todo o processo: GetKeyState (VK_SPACE) <0!!!
Em terceiro lugar, POR QUE PASSO UM TEMPO EXTRA DE VERIFICAÇÃO E BYTES EXTRA DO MEU PROGRAMA, se eu sei exatamente quais valores eu uso? Afinal, o usuário não tem o direito de alterar os valores dessas variáveis!

PS Para ver todo o charme do meu estilo de escrever código, escreva-o no editor de código Delphi !!!
Visualização de amostra:
(******************************** Nome do cabeçalho do código ***************** **************) Nome da Função (S: String): String; // O que este procedimento faz; Descrição de variáveis, etc. var // Nome: Type; // Comentário FTD: Inteiro; // Exemplo STR: String; // outro exemplo const XXX = 0; // E outro exemplo :-) começar (* Nome do sub-bloco *) STR: = "abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc" + "abcabcabcabcabc"; Se ... então começar Para FTD: = 1 para 100, faça começar ... ... fim; fim mais ...; Se ... então ... mais começar ... ... fim; Se ... então tentar ... ... exceto ... ... fim mais tentar ... ... finalmente ... ... fim; Com ... fazer começar ... ... fim; Para ... fazer ...; end; // Copyright sobre o procedimento, data, hora



Anatoly Podgoretsky   (2002-08-11 22:48) [20]

VEG © (11.08.02 22: 21)
Escute, se você quiser falar sobre o seu jogo, isso é uma coisa, e sobre o estilo, outra. Oleg observou com razão que esse estilo é ruim.
Nesses casos, eles declaram constantes de limite ou, melhor ainda, um sub-intervalo, por exemplo:

tipo
QuestionsRange = 1..15; // Número de perguntas


QA: array [QuestionsRange] of Inteiro; // Número de perguntas
QABaseAll: array [QuestionsRange] de QABaseNum; // Todas as perguntas

Essa é outra questão, uma série de perguntas é apresentada imediatamente aqui e a capacidade de ser automaticamente verificada pelo compilador, se necessário, aumenta a capacidade de leitura do programa.
Durante esses meses, tive a impressão de que você não se importa com todas as dicas.



Юрий Зотов   (2002-08-11 22:52) [21]

> VEG © (11.08.02 20: 36)

Parece bonito e lê muito bem, sem dúvida. Mas o estilo começa apenas com a beleza, mas não termina com isso. Não vou repetir sobre a matriz [1..15] e MSecs não assinados, mas quanto ao "aquecimento do processador", acrescentarei o que foi dito - esses ciclos de atraso são muito melhores com base no MsgWaitForMultipleObjects. Esse realmente será um estilo competente - com a carga mínima do processador, tudo o que for necessário será feito. Eu recomendo fortemente que você escreva esse procedimento, ele será útil mais de uma vez.

Embora o que já é bom. Alguns programadores profissionais escrevem pior. Infelizmente ...

PS Informações para consideração.
A expressão msecs + FirstTick no seu loop de repetição é invariável. Alguma idéia sobre isso? Também é um estilo ...



Anatoly Podgoretsky   (2002-08-11 23:03) [22]

Bem, eu não sei sobre beleza, mas o código em que começa e a frase em uma linha, a mesma repetição



Юрий Зотов   (2002-08-11 23:11) [23]

> Anatoly Podgoretsky © (11.08.02 23: 03)

Uma questão de hábito, não mais. Não esqueça que o cara tem apenas 15 anos de idade. Ele mudará o estilo do design mais de uma vez e no final ainda chegará ao estilo Borland, ele não é o primeiro nem o último. Esta não é a coisa principal - o estilo PROGRAMAÇÃO é muito mais importante.



Oleg_Gashev   (2002-08-11 23:39) [24]

> Esta não é a principal coisa - o estilo de PROGRAMAÇÃO é muito mais importante.

Me desculpe Isso não é mais importante do que o pensamento de um programador, sua atitude em relação à programação em si. Eu toquei neste tópico várias vezes no fórum e mais uma vez se resume ao mesmo. Somos ensinados a programar, mas não somos ensinados a pensar. Nós estamos escrevendo
QA: matriz [1..15] de Inteiro;
e não entendemos o que isso pode levar. Portanto, posso aconselhar o VEG a mudar antes de tudo o pensamento, e o estilo de programação já será desenvolvido por si só.



Юрий Зотов   (2002-08-11 23:59) [25]

> Oleg_Gashev © (11.08.02 23: 39)

> principalmente pensamento e estilo de programação
> já elaborou sozinho.

O estilo de programação é um reflexo "visual" do pensamento, do conhecimento e da experiência do programador. Essas coisas são inextricáveis, elas sempre se desenvolvem juntas. De fato, este é o mesmo.



Torry   (2002-08-12 00:08) [26]

Yuri e Anatólia, antes de tudo:

Agora, estou pronto para fazer algo como uma seção em que vocês analisariam exemplos de código no Torrik. Anteriormente, havia uma série de livros de um autor, o sobrenome começou com "K" - eu esqueci onde foi feito. É uma pena que essa já seja uma maneira esquecida de fornecer informações ...

Vamos falar sobre esse tópico em particular?



VEG   (2002-08-12 00:32) [27]

> Anatoly Podgoretsky
> Ouça, se você quiser falar sobre o seu jogo, isso é uma coisa, mas o estilo é outra, Oleg observou com razão que esse estilo é ruim.
Eu trouxe o meu estilo de escrever código! O erro aqui é excluído, pois em um caso específico, um novo tipo não deve ser criado melhor!
> Tenho a impressão de que você não se importa com todas essas dicas.
Hehe ... Que meses? Começamos a falar sobre escrever código apenas ontem!
> Bem, eu não sei sobre beleza, mas o código em que começa e a frase em uma linha, a mesma repetição
No começo, estudei Delphi sem livros e sem a Internet, porque nem um nem o outro era! Eu criei meu próprio estilo e realmente gosto!
> Yuri Zotov
Este procedimento foi criado no ano passado! E não sei que tipo de MsgWaitForMultipleObjects você quer dizer.
> ... que o cara tem apenas 15 anos de idade.
Quando todos vocês aprenderão a contar! Eu sou 14 !!!
> Oleg_Gashev
> e não entendo o que isso pode levar.
E o que isso pode levar?



Anatoly Podgoretsky   (2002-08-12 00:32) [28]

É difícil fazer isso de forma contínua, para qualquer código, a tarefa é mais adequada para fóruns, como exemplo do código fornecido ou como uma série de artigos, lembro-me do Borland toli no D2 toli no D3 na documentação com a Delphi, havia vários capítulos do Robust Application.

O ponto não está no código, mas na psicologia da pessoa, ou ele está pronto para escrever o código sem erros ou não, a comunicação direta é tudo favorável a isso.

Geralmente, os comentários sobre o código raramente são dados, poucos estão prontos para isso, apenas neste caso, um tópico especial surgiu e surgiu de uma discussão no chat.

O assunto completamente diferente de Yuri está em sua natureza e ele o faz profissionalmente.



Anatoly Podgoretsky   (2002-08-12 00:35) [29]

Especificamente para D5
Guia do desenvolvedor
Capitulo 3
Tarefas comuns de programação



MrBeer   (2002-08-12 01:49) [30]

Yuri Zotov © (11.08.02 22: 52)
Alguns programadores profissionais escrevem pior. Infelizmente ...


Profissional oznachaet tolko chto chelovek etim zarabativet, como hleb, te eto neochem ne govorit ...



FLIZ   (2002-08-12 01:55) [31]

Eu até nas noites do 2 TUDO li o que você escreveu.
quão bom é que você ensina tão bem!
obrigada



Юрий Зотов   (2002-08-12 01:56) [32]

> MrBeer © (12.08.02 01: 49)

Isto é o que quis dizer. Infelizmente.



VEG   (2002-08-12 02:05) [33]

Obrigado a Yuri Zotov por tudo!
Tchau pessoal! O ramo está fechado!
VEG está morto. Por este agradecimento especial, antes de tudo, a Anatoly Podgoretsky, e depois a MrBeer e Oleg_Gashev!

> Anatoly Podgoretsky, MrBeer, Oleg_Gashev
Mas, infelizmente, senhores, infelizmente ...



Юрий Зотов   (2002-08-12 02:19) [34]

> VEG © (12.08.02 02: 05)

Em vão. Por que reagir tão dolorosamente? Pense com calma. Só não agora, amanhã. Releia com calma e calmamente, ok?



Anatoly Podgoretsky   (2002-08-12 09:24) [35]

VEG © (12.08.02 02: 05)
Por mais doloroso que seja não reagir, posso aconselhar, além do conselho de Yuri sobre descanso, que não traga seu código para análise, com uma indicação explícita disso, pois será mais fácil avaliar.



VEG   (2002-08-12 12:14) [36]

E daí? Tudo já foi repetido várias vezes ... Os últimos três dias são o limite? Não, claro! Haverá outros ...



FLIZ_   (2002-08-12 12:18) [37]

2 VEG © (12.08.02 02: 05)

hmm, mas você quer que todos aqui aceitem seu estilo "bonito"
para programação padrão? talvez você ainda tenha
Os borlandianos deveriam comprar? Eu não entendo alguma coisa - e por que diabos
Você ainda brilha aqui? pioneiro, caramba ...

"VEG está morto"

talvez com esse pathos índios conversem sobre si mesmos
(como "guaxinim morto deixa você" :-))
e .... mulheres! :)

2 all
mas eu li que pessoas inteligentes escrevem em casa
encontrou falhas no estilo, e mais uma vez digo a essas pessoas -
obrigado por aprender! informação é a coisa mais valiosa ...



DenKop   (2002-08-12 15:52) [38]

IMHO:
Penso que, para tipos de dados, não vale a pena a falha, se esses valores não estiverem acessíveis ao usuário. Se o programador souber que, sob nenhuma circunstância, seu programa poderá acessar um elemento da matriz cujo índice> 15, ele terá todo o direito de declarar sua matriz como [1..15]. Mas se você ainda tiver dúvidas, precisará usar apenas os tipos Estendido ou Cardinal, provavelmente não sentirá falta. Nesse caso, surge a questão de economizar memória, e isso também será criticado. Acontece que, independentemente do código que você fornecer, ele ainda não estará correto, porque é o mesmo: não é econômico ou não está correto (porque pode haver mais do que perguntas do 15, embora essa seja uma das principais perguntas para o desenvolvedor idéias que as perguntas não podem ter mais que 15).
Nesse caso e para isso, é necessário prever que a pergunta possa ser geralmente negativa (por exemplo, -12). Senhores PARADOX! E em vão você atacou com esses críticos rudes Prana. Afinal, esse é um estilo de programação, e não uma regra obrigatória, por exemplo, como um ponto e vírgula após cada linha.



VEG   (2002-08-12 15:59) [39]

> FLIZ_
Não é sobre estilo. Sobre conversas de bate-papo nos últimos três dias.



Anatoly Podgoretsky   (2002-08-12 16:02) [40]

Um ponto-e-vírgula após cada linha não é uma regra obrigatória; em alguns casos, pode ser omitido e, em alguns casos, não pode ser usado. É claro que isso não é sobre o programa dele, não se importa, não é sobre estilo, embora isso faça parte do conceito, seja sobre o método de escrever os programas certos, é disso que se trata. E nada a ser reduzido a motivos pessoais, eles simplesmente não existem.



VEG   (2002-08-12 16:08) [41]

> DenKop
Eu concordo!
Obrigado pelo apoio!



DenKop   (2002-08-12 16:45) [42]

Anatoly Podgoretsky >>
Eu acho que não é necessário encontrar falhas em ninharias (quero dizer;), eu me expressei exageradamente. Mas ainda quero ouvir algo interessante sobre o assunto do paradoxo apresentado. Eu não acho que TODOS OS QUERIDOS Anatoly Podgoretsky, sabendo que seu array não pode conter mais do que 15 els, o declarem como [1..1000] (não especificarei nada, o exemplo é novamente abstrato!), Porque pode ser responsabilizado pela irracionalidade do código.
Mas se você tentar descrevê-lo como [1..15], será exibida uma pergunta com o seguinte conteúdo: "E se houver mais de perguntas sobre o 15, o que fazer, Voz de acesso ou Índice fora dos limites, ou talvez o que mais? !!" É aqui que o principal paradoxo está nas mensagens apresentadas por você (e não apenas por você), e eu ia reduzir as críticas a motivos pessoais.


> Claro, isso não é sobre o programa dele, não importa, fala
> não é sobre estilo, embora isso faça parte do conceito, é sobre técnica de escrita
> os programas certos, é disso que se trata.

Isso é exatamente o que eu tinha em mente, porque Uma explicação teórica levaria muito tempo; portanto, para não ir muito longe, peguei um exemplo do ramo atual.

Digamos que o código seja QA: array [1..15] of Inteiro; não racional não faz sentido sem ver o restante do código em que essa matriz é usada. Afinal, talvez seja usado assim:

...... QA [3]: = 23; ...... ShowMessage (IntToStr (QA)); ......

Se isso for verdade, esse encadeamento poderá ser considerado uma chama geralmente sem sentido. É isso mesmo? Ou estou errado em alguma coisa?



DenKop   (2002-08-12 16:48) [43]

Pequena alteração ShowMessage (IntToStr (QA [3]);



Alx2   (2002-08-12 16:58) [44]

DenKop © (12.08.02 16: 48)
Foi você quem escreveu o controle de qualidade [3] em vão. E onde está o cheque
if 3 em [1..15] // e se sob o símbolo "3" outro valor foi mascarado?
Controle de qualidade [3]: = Variante (23) // E se alguém alterar o tipo de controle de qualidade?
8)

PS
Concordo que extremos podem ser ainda mais prejudiciais do que descuido, pois você pode obter um monstro que, além de verificar a correção de suas estruturas internas de dados, quase não faz nada.



Anatoly Podgoretsky   (2002-08-12 17:01) [45]

DenKop © (12.08.02 16: 45)
Por que o ramo é muito útil.
É uma pena que eles constantemente tentem desviá-lo do tópico para programas e relacionamentos pessoais.



DenKop   (2002-08-12 17:08) [46]

Para Alx2 >>

> de repente, sob o símbolo "3", um significado diferente foi disfarçado?


É a primeira vez que ouço isso, mas o que realmente pode ser disfarçado como uma constante inteira?


> E se alguém alterar o tipo de controle de qualidade?

Não entendo direito quem pode alterar o tipo e em que estágio (usuário, desenvolvedor)? "E se alguém que usa o IDA transformar o jogo em algum tipo de sistema de programação, por exemplo, em algum tipo de Bear Pro ou Elefant Pro (analogia com a Fox Pro)."



Юрий Зотов   (2002-08-12 17:48) [47]

No entanto, eu gostaria de interromper nossos desmantelamentos em andamento (é estranho por que, bem, é apenas que nunca é possível sem eles?) E voltar ao tópico. E não com referência a um código ou programador específico, mas ainda mais amplo.

Acima, Torry expressou a idéia de criar uma seção na qual se pudesse ler sobre o estilo de programação, técnicas e princípios para escrever códigos seguros (profissionais, se você preferir), examinar e analisar exemplos específicos, talvez sugerir seu próprio código para revisão e obter comentários específicos sobre ele - etc. (se, é claro, eu entendi corretamente a ideia dele).

A esse respeito, gostaria de saber a opinião de todos os programadores sobre aproximadamente essas questões.

1. Você precisa pessoalmente dessa seção?

Se sim, então:

2. Como você o imagina?
3. O que eu gostaria de ver nele (quais subseções etc.)
4. Organização do diálogo com seus líderes (ou nenhum diálogo é necessário - apenas artigos e é isso).
5. Etc. - quaisquer pensamentos sobre este assunto.



Игорь Шевченко   (2002-08-12 17:58) [48]

Yuri Zotov © (12.08.02 17: 48)

Teixeira e Pacheco têm um capítulo inteiro sobre o estilo de programação, mais ou menos ...

Atenciosamente,



RV   (2002-08-12 18:01) [49]

Eu preciso
também um fórum, mas com pré-moderação como no Reino de Delfos
Sim, o principal é começar - ainda mais a critério do host



DenKop   (2002-08-12 18:18) [50]


> Eu ainda gostaria de parar nossa desmontagem em andamento (estranho,
> por que, bem, nunca é sem eles?) e retornar
> para o tópico.

Concordo, com muita frequência, que nossos mestres estimados tentam mostrar seu profissionalismo (ou o oposto). É preciso mal e ressentimento, porque o tratamento de nossos profissionais com os visitantes deixa muito a desejar (um exemplo de VEG e não apenas, na minha memória já havia três ramos desse tipo). Bem, tudo bem, não vamos falar sobre o mal.


> 1. Você precisa pessoalmente dessa seção?

Eu acho que seria muito interessante ler qualquer coisa sobre esse tópico, porque Não vi nada parecido na rede.


> 3. O que eu gostaria de ver nele (quais subseções etc.)

Eu acho que não vale a pena dividir em um grande número de subseções. Eu acho que isso é suficiente:
1. Princípios gerais.
2. Regras para um belo código de API.
3. Esqueletos de estruturas seguras. (Eu acho que nenhuma explicação é necessária)


> 4. Organização do diálogo com seus líderes (ou de forma alguma
> nenhum diálogo - apenas artigos e é isso).

Para mim, pessoalmente, um conjunto de artigos seria suficiente.

Há outra questão: onde obter tanta informação e quem a fará?



Romkin   (2002-08-12 18:20) [51]

2 Yuri Zotov: Eu gostaria de ... E depois de todas as conversas já estou pensando: e se eu escrever abaixo do ideal?
2. Algo como FAQ neste site, talvez como um cruzamento entre artigos (notícias da seção na entrada)
3. Eu acho que as subseções são visíveis: Object Pascal, trabalhando com WINAPI ...
4. Não há necessidade de diálogo, existem fóruns para isso. Mas o formulário para postar seu código para verificação deve ser. E depois de verificar o IMHO, é desejável poder fazer perguntas esclarecedoras ao inspetor (do autor da postagem), etc.
5. E tp ...



FLIZ_   (2002-08-12 18:24) [52]

Eu preciso.
Eu quero:
1. veja exemplos do código de segurança "referência" de diferentes maneiras
assuntos - trabalhe com bases, com objetos, com padrões
funções ...
2. ser capaz de obter uma explicação do porquê
É considerado seguro.
3. envie seu código "para verificação", ou seja, tire isso
em público para discussão.

4. E PARAR NO FIM DO POUCO COMO COMPLETO ...
vamos nos lembrar por que estamos aqui no fórum.
Pessoalmente, estou aprendendo aqui!



Malder   (2002-08-12 18:46) [53]

Outro exemplo, com sua permissão.

1 opção:
se <condição 1> e <condição 2> então ...

2 opção:
se <condição 1> então
se <condição2> então ...

Parece ser a mesma coisa? Ah não


Você poderia dar um exemplo de quando esses dois códigos executarão as mesmas ações.



Anatoly Podgoretsky   (2002-08-12 19:21) [54]

Nas configurações, há o item Avaliação Booleana Completa e a diretiva correspondente ($ BOOLEVAL), o comportamento do primeiro código dependerá do estado deles; no segundo caso, não, a segunda expressão será executada apenas se o primeiro for executado e sempre para a primeira opção. Naturalmente, os resultados podem ser diferentes.
Um erro tão sutil e furtivo.



MrBeer   (2002-08-12 19:23) [55]

Para Malder:
skazali para zavisit ot kompilyatora / opcii, tk ne yasno kotoraya chastj iz "se <condição 1> e <condição 2> então ..." budet proveryatsja pervoi condition2 ili condition1. Uma variante kogda naprimer iz serii if (Something <> nil) e (Something.Size <> 0) então ... violação de acesso mozhet vizivatj




vuk   (2002-08-12 19:28) [56]

para Malder:
> Você pode, por exemplo, um exemplo em que esses dois códigos serão executados
> Ações desiguais.
Então, tudo está escrito lá. Tudo depende de que tipo de esquema de computação de expressão booleana é usado.
Parimer.

procedimento SomeProc (DataSet: TDataSet);
começar
if (DataSet <> nil) e DataSet.Active, então
começar
...
end;
end;

Suponha que nada seja passado para este procedimento.
1. Um esquema de cálculo curto é usado. A primeira condição é calculada. Não é executado, portanto, você pode prever o resultado de toda a expressão lógica com antecedência - isso é falso. Portanto, a segunda condição não é verificada.

2. Avaliação de expressão completa é usada. Nesse caso, as expressões são totalmente avaliadas; portanto, ao contrário do primeiro caso, será feita uma tentativa de obter o valor da propriedade DataSet.Active. Mas, como DataSet = nil, obtemos Violação de Acesso.

Se o código for reescrito assim
if (DataSet <> nil) então
se DataSet.Active, então
...
Então ele funcionará corretamente de qualquer maneira.

Quanto às dificuldades no desenvolvimento do grupo e nas diferentes configurações do compilador em diferentes máquinas mencionadas por Yuri Zotov, isso pode ser facilmente resolvido de várias maneiras:

1. Administrativamente. É necessário concordar com certas configurações do compilador ou aprová-las como um padrão interno.

2. O arquivo de configurações de parâmetro do compilador deve fazer parte do código geral.

3. As configurações do compilador são gravadas diretamente no código fonte. Como opção - inclua. Nesse caso, a compilação correta é sempre garantida. As opções especificadas nas fontes têm precedência sobre as configurações do compilador no IDE.



Anatoly Podgoretsky   (2002-08-12 19:34) [57]

Além disso, como MrBeer chamou a atenção, a sequência de verificação pode ser diferente, uma vez que ambas as condições devem ser verificadas, não é necessário nessa sequência.



Malder   (2002-08-12 19:39) [58]

Exatamente exatamente. Eu travo ...



vuk   (2002-08-12 19:44) [59]

Eu dei o caso mais simples ... Naturalmente, em expressões complexas tudo será ainda mais lançado. : o) Será ainda pior se funções que fizerem algo irreversível e cujo trabalho depende do resultado de verificações anteriores forem usadas na expressão.



Anatoly Podgoretsky   (2002-08-12 19:49) [60]

É melhor usar o termo funcional - uma função com efeitos colaterais, aqui apenas aguarde



Юрий Зотов   (2002-08-12 23:43) [61]

Caros dons (como costumava dizer o Don Rumata), desculpe-me pela importunidade, mas ainda assim peço que você fale sobre minha última postagem (sem contar isso): o)

Peço especialmente aos jovens programadores que se manifestem - nesse caso, sua opinião é muito mais importante.



Oleg_Gashev   (2002-08-12 23:54) [62]

> Yuri Zotov
Mãos e pés atrás. Está na hora.



Torry   (2002-08-13 00:08) [63]

Estou sujeito a tudo e sinceramente peço desculpas a Alexei Vukolov - também convido você a participar ...




Anatoly Podgoretsky   (2002-08-13 00:24) [64]

O caso da organização, para o formulário



vuk   (2002-08-13 01:36) [65]

para Yuri Zotov:
Ponto por ponto.
> 1. Você precisa pessoalmente dessa seção?
Aparentemente sim. É preciso sempre aprender. E existe a oportunidade de aprender com os erros dos outros, e até (se de repente) com um interrogatório. : o)

> 2. Como você o imagina?
Isso é pior. Isso deve ser pensado ... Tudo, na maior parte, depende de quem fará isso.

> 3. O que eu gostaria de ver nele (quais subseções etc.)
Padrões e estilos de design de código (falamos muito sobre isso neste tópico). Técnicas de codificação segura / ideal. Talvez métodos para localizar erros.

> 4. Organização do diálogo com seus líderes (ou de forma alguma
> nenhum diálogo - apenas artigos e é isso).
Depende, novamente, de quem o organizará e de sua abordagem para organizar o recurso. Eu prefiro a abordagem quando a base da construção são materiais e as discussões já estão anexadas a elas. Algo como o Reino de Delfos.

torry:
> e sinceramente peço desculpas a Alexei Vukolov
Não vale o pedido de desculpas.



blackweber   (2002-08-13 01:45) [66]

seria muito bom



Виктор Щербаков   (2002-08-13 10:33) [67]

Yuri Zotov © (12.08.02 23: 43)

1. Mãos e pés atrás. Essa seção é sem dúvida necessária.

2. A seção deve complementar o fórum e não substituí-lo. Ao mesmo tempo, não deve ser estático. Caso contrário, ele se tornará inútil para qualquer um. A esse respeito, proponho as seguintes seções:

3. a) artigos de vários autores.
b) perguntas regulares (felizmente, existem muitos materiais para isso no fórum) que os apresentadores fariam. Seções sobre tópicos (Win API, OP, BD, ...), IMHO, não são necessárias.
c) como complemento: o padrão de codificação Borland em russo (como em Teixeira e Pacheco).
d) ... nada mais vem à mente.

4. Quanto à revisão do meu código, eu nem sei. O fórum faz um bom trabalho nisso. É preciso apenas fazer tal solicitação na seção apropriada do fórum. Outra coisa é quando um código curvo aparece durante a discussão e é ignorado. É precisamente isso que precisa ser analisado nesta seção (nem todos, é claro, apenas os exemplos mais impressionantes).



Сатир   (2002-08-15 14:44) [68]

2Yury Zotov © (12.08.02 17: 48)
não seria muito ruim se sua idéia fosse concretizada, já que são os comentários IMHO que dão ao compilador e seus recursos muito mais insight do que um exemplo simples de código para uma pergunta trivial.
Além disso, essa abordagem é mais produtiva, pois representará o potencial de obter informações sobre os meandros da própria programação, o que, por sua vez, possibilitará resolver com mais precisão os problemas colocados.
Atenciosamente, Programador Iniciante



kull   (2002-08-15 18:29) [69]

2 VEG

var L: Inteiro; S: String; começar L: = comprimento (S); Inc (L, -3); Se L <0, então L: = 0; SetLength (S, L); fim;
Eu odeio se.
A mesma coisa em uma linha e sem instruções condicionais:

SetLength (S, Inteiro (Comprimento (S)> 2) * (Comprimento (S) -3));

E não menos confiável ...
(Para mim, eu já escrevi a mesma coisa sobre esse código, mas não me lembro onde ...)



DiamondShark   (2002-08-15 18:45) [70]


> kull © (15.08.02 18: 29)


No depurador, observe o código da máquina e decida de uma vez por todas: faz sentido quebrar o cérebro e depois de dois dias até os olhos desse código.

A propósito, isso também pode ser aconselhado aos apoiadores da "concisão" de C ++



Юрий Зотов   (2002-08-15 19:14) [71]

> kull © (15.08.02 18: 29)

> E não menos confiável ...

Absolutamente não confiável. Um ótimo exemplo de uma violação grave dos princípios de programação segura é vinculativo para uma implementação interna.

Na versão existente do compilador, False = 0, True = 1, e seu código funciona. No entanto, de acordo com a documentação oficial, False = 0 e True <> 0. Portanto, vale a pena que a Borland "amanhã decida qual é mais conveniente, por exemplo, True = -1 - e seu código imediatamente deixa de funcionar. Mas a Borland não será a culpada - permaneceu estritamente dentro de sua documentação.



^Sanya   (2002-08-15 19:50) [72]


> 1. Você precisa pessoalmente dessa seção?
Sim, eu preciso disso. Estou procurando por algo assim há muito tempo. Infelizmente, capítulos dos clássicos (Teixeyer & Pacheco), na minha opinião, não são suficientes.
> Se sim, então:
>
> 2. Como você o imagina?
Depende de quanto tempo livre é gasto por Yuri Zotov e outros mestres respeitados: se houver muito, gostaria de ver a possibilidade de criar + discussões sua código
> 3. O que eu gostaria de ver nele (quais subseções e
> etc.)
primeiro, uma seção (como "perguntas gerais") e, em seguida, se necessário, selecione subseções, ou seja, de Geral para Particular, conforme necessário ... gradualmente. Se, por exemplo, houver muitas perguntas sobre o WinAPI, crie uma subseção para o WinAPI.
> 4. Organização do diálogo com seus líderes (ou de forma alguma
> nenhum diálogo - apenas artigos e é isso).
Sim, eu gostaria.
> 5. Etc. - quaisquer pensamentos sobre este assunto.
Se for real, mostre às pessoas o seu programa com uma discussão subsequente (algo como um "aterro sanitário" no Reino)




evgeg   (2002-08-15 20:17) [73]

Na versão existente do compilador, False = 0, True = 1, e seu código funciona. No entanto, de acordo com a documentação oficial, False = 0 e True <> 0.

O uso mais comum de uma expressão booleana é com operadores relacionais e instruções condicionais. Como os tipos booleanos são tipos enumerados, os seguintes relacionamentos se aplicam:

Falso <verdadeiro
Ord (Falso) = 0
Ord (Verdadeiro) = 1
Succ (Falso) = Verdadeiro
Pred (Verdadeiro) = Falso

Diferentemente das variáveis ​​booleanas, que podem assumir apenas os valores 0 (False) ou 1 (True), ByteBool, WordBool e LongBool podem assumir outros valores ordinais em que 0 é False e qualquer valor diferente de zero é True.

Coloque Ord (..) em vez de inteiro (..) - e tudo estará absolutamente correto. Embora o julgamento pela segunda passagem destacada e número inteiro (..) esteja correto.



evgeg   (2002-08-15 20:41) [74]

Em geral, se o log. Como a expressão pode usar um tipo booleano não-booleano, é melhor não usar um número inteiro. Ord sempre funcionará corretamente.



Anatoly Podgoretsky   (2002-08-15 20:49) [75]

Este é um truque típico.



Jeer   (2002-08-15 21:16) [76]

> kull © (15.08.02 18: 29)
Eu odeio se.
> A mesma coisa em uma linha e sem declarações condicionais:
> SetLength (S, Inteiro (Comprimento (S)> 2) * (Comprimento (S) -3));

Isso é alguma coisa.
Um exemplo de como não escrever, pelo menos em Pascal.
E por que não lembrar de momentos inesquecíveis:
Assim:
char far * (far * getint) (int far *);
expressar?



Игорь Шевченко   (2002-08-16 11:13) [77]

Jeer © (15.08.02 21: 16)

> char far * (far * getint) (int far *);

E o que, de fato, é incompreensível? E, o mais importante, como isso pode ser declarado de maneira diferente? :-)))



Виктор Щербаков   (2002-08-16 11:18) [78]


> char far * (far * getint) (int far *);

Quando tento dizer em palavras, acontece com interjeições e sem casos :)))



Игорь Шевченко   (2002-08-16 11:28) [79]

© Victor Shcherbakov (16.08.02 11: 18)

Um ponteiro para uma função que retorna um ponteiro para uma sequência de caracteres e leva um ponteiro para um número inteiro como parâmetro.

Também posso dizer muitas coisas interessantes sobre Pascal, mas é necessário?



Jeer   (2002-08-16 11:29) [80]

Eu não disse que esse é um design ruim ou incorreto ou que há um registro mais curto ou mais compreensível.
A observação foi que não transferimos cegamente técnicas silábicas para Pascal.



kull   (2002-08-16 11:30) [81]


> Yuri Zotov © (15.08.02 19: 14)

Antes de consultar a documentação, você deve lê-la.
À minha frente, há uma caixa com Delphi licenciado e, no folheto em anexo, diz que True corresponde a 1 e False corresponde a 0.

Aqui Mlyn, muitas pessoas ficaram presas aqui com essa realização interna.
Eu não tenho o mau hábito de procurar nas fontes e investigar o código asm. Tento proceder apenas da documentação e aconselho.



kull   (2002-08-16 11:33) [82]


> Jeer

E eu não aguentei as técnicas de recepção em Pascal ...
Em C ++, ainda sou um lamer completo. E, se possível, deve haver menos código.
Um design mais simples é um código mais confiável.



Anatoly Podgoretsky   (2002-08-16 11:40) [83]

Com base no tópico, basta confiar na implementação interna de um compilador específico, embora documentado.
Embora tenha sido mais de uma vez, ao longo do caminho, esses ou outros tipos foram alterados.



Jeer   (2002-08-16 12:22) [84]

kull © (16.08.02 11: 33)
> Um código deve ser menor, se possível.

Bem, sim, claro.
Mas o YaVU é para leitura e gravação em seres humanos, e a segurança da codificação está diretamente relacionada à boa capacidade de reconhecimento e compreensibilidade do código. Mas aqui, alguns métodos para aumentá-los não podem ser dispensados.

Por exemplo, existe um otimizador de código HTML que elimina redundância de código desnecessária (formatação) não necessária ao intérprete do navegador, mas tão necessária para uma pessoa entender.
O resultado dessa formatação é simplesmente ilegível.



kull   (2002-08-16 12:23) [85]


> Anatoly Podgoretsky

Não, eu não confio na implementação interna.

Você pode confundir os conceitos ...

Para mim, há uma entrada True e uma saída 1;
Para mim, há uma entrada False e uma saída 0;
Tudo o que acontece dentro desta caixa preta não me incomoda. Então, o que está acontecendo lá dentro é realização interna. E quando abro a Ajuda e leio o que deve estar na entrada da função e o que deve estar na saída, isso não se aplica à implementação interna - essa é a interface, se você preferir.

By the way, sobre a implementação interna e escavação na fonte .-

Abrir qualquer versão do Delphi e procure o texto - "Inteiro (" no diretório Delphi \ Source.
Você encontrará muitas conversões interessantes como Boolean-> Inteiro nos resultados da pesquisa. Ou a Borland não segue sua documentação?



kull   (2002-08-16 12:26) [86]


> Jeer © (16.08.02 12: 22)

Eu concordo com isso. Obviamente, escrever é mais fácil e mais curto, se possível, mas não em detrimento da legibilidade e confiabilidade.



Виктор Щербаков   (2002-08-16 12:28) [87]


> Abra qualquer versão do Delphi e procure no diretório Delphi \ Source
> texto - "Inteiro (".
> Você encontrará muitas transformações interessantes nos resultados da pesquisa
> digite Boolean-> Inteiro. Ou a Borland não segue sua documentação?

Nesse caso, não há ligação à implementação atual. A conversão será realizada pelo compilador. Em vez disso, ele irá gerar código para essa conversão.



Anatoly Podgoretsky   (2002-08-16 12:32) [88]

kull © (16.08.02 12: 23)
Concordo com você, se falamos sobre implementações específicas do Pascal da Borland, mas se falamos de um espectro mais amplo ou, de maneira mais geral, sobre métodos para escrever código seguro, não posso concordar.

O link para o código de outros programadores da Source, apesar de bom, não é prova, escreveram pessoas lá, o número de erros é conhecido.

Ao mesmo tempo, está escrito em qualquer cartilha de código seguro, evite a conversão ou a conversão de código desnecessariamente.



VEG   (2002-08-16 12:41) [89]

Programa de teste: var L: Inteiro; S: String; Tempo: Inteiro; FTD: Inteiro; começar Hora: = GetTickCount; Para FTD: = 1 para 1000000, faça começar S: = "ABC"; (* Código para resolver o problema *) fim; Hora: = GetTickCount-Time; fim; Resultados dos testes de todas as opções propostas: 1. L: = comprimento (S); Inc (L, -3); Se L <0, então L: = 0; SetLength (S, L); Resultado: 110 ms. 2. Se Comprimento (S)> 2, então SetLength (S, Comprimento (S) -3) else S: ​​= ""; Resultado: 124 ms. 3. SetLength (S, Inteiro (Comprimento (S)> 2) * (Comprimento (S) -3)); Resultado: 149 ms. 4. Se Length (S)> 2, em seguida, Delete (S, Length (S) -2,3) else S: ​​= ""; Resultado: 890 ms. Para referência: todos os testes foram realizados em um processador Pentium III - 550Mhz.



kull   (2002-08-16 12:50) [90]


> Viktor Shcherbakov
> Nesse caso, não há vinculação à implementação atual.

O que foi necessário para provar.
(Ou talvez Boolean-> Inteiro, será compilado de maneira diferente dependendo do diretório em que está?)


> mas se falamos de um espectro mais amplo ou mais
> que, em geral, sobre métodos de escrever código seguro

A função SetLength pode não aparecer em um espectro mais amplo ...
Além disso, o modem não parece ser longas filas ...


> O link para o código de outros programadores da Source, apesar de bom,
> mas não é prova ...

E a documentação também não é prova? Então, quais "primers" você usa?




kull   (2002-08-16 13:12) [91]


> VEG © (16.08.02 12: 41)

Naturalmente. No caso do 1, o comprimento é chamado apenas vezes 1 e em outros tempos 2.

Mas tente tornar a linha (S = "ABC") mais autêntica, a diferença não é tão grande.

Além disso, na maioria dos casos, a otimização da velocidade resulta em menor flexibilidade do código, baixa legibilidade e manutenção difícil. Concorde que o mesmo algoritmo pode ser implementado no assembler e ele funcionará ainda mais rápido.

A otimização é necessária apenas quando a velocidade do trabalho é crítica.



DiamondShark   (2002-08-16 14:07) [92]

2 kull

Por que uma defesa tão surda? Fora de princípio?

Todos entendem que esse código não se justifica nem pela legibilidade nem pelo tamanho do código da máquina, nem pela velocidade, nem pela confiabilidade.



kull   (2002-08-16 17:25) [93]


> Todo mundo entende que esse código não se justifica por nenhuma legibilidade,
> nem o tamanho do código da máquina, nem a velocidade, nem a confiabilidade.

Você está certo em estimar a velocidade (e isso pode ser).


Se você não gosta de Boolean-> Integer, aqui está outro código:

SetLength (S, Max (0, Comprimento (S) -3));

Não menos confiável, legível e em velocidade, está em conformidade com a versão 1.
E acho que isso é mais legível do que:
L: = comprimento (S); Inc (L, -3); Se L <0, então L: = 0; SetLength (S, L);

Então, eu acho que lutar por esse código é mais justificado.

Bem, agora e a implementação interna?



VEG   (2002-08-16 20:25) [94]

A classificação mudou!
Para o caractere 1:
1. Se Comprimento (S)> 2, então SetLength (S, Comprimento (S) -3) else S: ​​= ""; Resultado: 89 ms., 910 ms. 2. Se Length (S)> 2, em seguida, Delete (S, Length (S) -2,3) else S: ​​= ""; Resultado: 90 ms., 910 ms. 3. L: = comprimento (S); Inc (L, -3); Se L <0, então L: = 0; SetLength (S, L); Resultado: 111 ms., 1140 ms. 4. SetLength (S, Max (0, Comprimento (S) -3)); Resultado: 116 ms., 1275 ms. 5. SetLength (S, Inteiro (Comprimento (S)> 2) * (Comprimento (S) -3)); Resultado: 145 ms., 1533 ms.

Para caracteres 3:
1. L: = comprimento (S); Inc (L, -3); Se L <0, então L: = 0; SetLength (S, L); Resultado: 110 ms., 1119 ms. 2. Se Comprimento (S)> 2, então SetLength (S, Comprimento (S) -3) else S: ​​= ""; Resultado: 124 ms., 1260 ms. 3. SetLength (S, Max (0, Comprimento (S) -3)); Resultado: 125 ms., 1274 ms. 4. SetLength (S, Inteiro (Comprimento (S)> 2) * (Comprimento (S) -3)); Resultado: 149 ms., 1516 ms. 5. Se Length (S)> 2, em seguida, Delete (S, Length (S) -2,3) else S: ​​= ""; Resultado: 890 ms., 8842 ms.

Para caracteres 6:
1. L: = comprimento (S); Inc (L, -3); Se L <0, então L: = 0; SetLength (S, L); Resultado: 736 ms., 7413 ms. 2. Se Comprimento (S)> 2, então SetLength (S, Comprimento (S) -3) else S: ​​= ""; Resultado: 737 ms., 7442 ms. 3. SetLength (S, Max (0, Comprimento (S) -3)); Resultado: 739 ms., 7473 ms. 4. SetLength (S, Inteiro (Comprimento (S)> 2) * (Comprimento (S) -3)); Resultado: 758 ms., 7694 ms. 5. Se Length (S)> 2, em seguida, Delete (S, Length (S) -2,3) else S: ​​= ""; Resultado: 1172 ms., 11790 ms.

Tempo gasto na atribuição de linha: 71 ms., 749 ms.

Nota: O primeiro dígito é o loop 1000000; O segundo dígito é o ciclo 10000000.

Para perguntas: Todos os testes foram realizados no processador Pentium III - 550Mhz.

Nota do testador: No primeiro teste, os dois primeiros vencedores jogaram, por assim dizer, não muito honestamente, porque use atribuição simples. No segundo teste, os três primeiros códigos funcionaram quase na mesma velocidade. De todos os testes, obtive o seguinte código, na minha opinião, o mais ideal:
L: = comprimento (S); Se L> 2, então SetLength (S, L-3), mais S: = "";
Aqui está o que os testes mostraram:
Para caracteres 6: 730 ms., 7407 ms.;
Para caracteres 3: 108 ms., 1126 ms.;
Para o caractere 1: 92 ms., 975 ms .;



kull   (2002-08-16 23:54) [95]

Sim, a primeira opção é a mais ótima, em velocidade.

A diferença entre 7473 e 7413 é 0.8%, ou seja, por uma hora no 3. opção, temos 59 min. 30 segundos no 1. opção Otimização poderosa!

Mas com um comprimento de string S igual a, por exemplo, 100, a diferença de velocidade é bastante insignificante.



Anatoly Podgoretsky   (2002-08-17 00:06) [96]

kull © (16.08.02 17: 25)
Não há nenhuma reclamação sobre esse código.



kull   (2002-08-17 00:16) [97]

Muitas vezes, quando ouço o raciocínio e os cálculos dos fãs de velocidade, fica engraçado.
De fato, você precisa cuidar da velocidade quando houver uma necessidade urgente.

Tenho muita experiência amarga, com base no desejo de nosso ex-gerente de projetos de várias otimizações:

Ele economizava em cada milissegundo, em cada byte no tráfego. Mesmo quando você abre os campos do Query, ele disse que é melhor chamar não FieldByName (FieldName), mas Fields [Index]. Como se fosse mais rápido. Byte preferido de número inteiro - como ocupa menos espaço no 4! E outros caprichos estranhos ...

Portanto, nossa equipe ainda está transando com o código quando você precisa alterar a ordem dos campos na solicitação, quando o byte já está ausente ou quando você precisa adicionar novas funcionalidades. E esse gerente ainda não está no projeto para o 2 do ano, mas conseguiu "otimizar" muito, até o momento vamos dissolvê-lo. O projeto, por sua graça, acabou sendo tão inflexível, não expansível e difícil de manter, que para nós entendemos firmemente - "Não há necessidade de otimização prematura!"

Falando em códigos seguros, ele diz o mesmo sobre otimização.

Portanto, pense dez vezes antes de pensar no tamanho do código e na velocidade da máquina.



Страницы: 1 2 3 filial inteira

Fórum: "Agarrar";
Arquivo atual: 2002.09.12;
Download: [xml.tar.bz2];

em cima





Memória: 1.09 MB
Hora: 0.097 c
8-35818
darha
2002-05-06 23:52
2002.09.12
Programa


14-35864
sudiv
2002-08-17 13:36
2002.09.12
Esse é o problema ...


1-35715
$ HiC0
2002-09-02 18:48
2002.09.12
Passando uma matriz bidimensional para um método de objeto ...


6-35828
delphi32.execod
2002-07-04 12:19
2002.09.12
Ajuda por favor


1-35716
$ hiC0
2002-09-02 19:26
2002.09.12
Novamente StringGrid





afrikaans albanês Arabic armênio azerbaijano basco belarusian Bulgarian catalão Chinês simplificado) Chinês tradicional) croata checo dinamarquês Dutch Inglês estoniano filipino Finnish French
Galego georgiano German grego crioulo haitiano hebraico hindi húngaro islandês Indonesian irlandês Italian Japanese Korean letão lituano macedónio Malay maltês Norwegian
persa polonês Portuguese Romeno Russa sérvio Slovak esloveno Espanhol swahili sueco tailandês turco ucraniano urdu vietnamita galês ídiche bengali bósnio
cebuano esperanto gujarati hausa hmong igbo javanês kannada khmer lao latino maori marata mongol Nepali punjabi somali tâmil telugu yoruba
zulu
Английский francês Alemão Italiano Португальский russo Espanhol