paulo1205
(usa Ubuntu)
Enviado em 04/12/2021 - 07:06h
ApprenticeX escreveu:
Bom dia a Todos!
Fazendo testes com strchr percebi um estranho comportamento!
O valor de Letra é 5
O valor de Text é 12
Não.
O valor de
Letra é um endereço na memória do caráter que fica 7 posições após o caráter que reside no endereço de memória produzido quando
Text é usado numa expressão.
Em outras palavras, se
Text corresponde a um endereço
X (que, a princípio, é desconhecido, pois vai depender de como seu programa foi compilado e como foi carregado na memória no momento de ser executado),
Letra corresponde ao endereço
X+7. Daí,
Letra-Text valerá
X+7-X, que dá
7.
O tipo de dados do valor resultante da subtração de dois ponteiros é
ptrdiff_t (definido em <stddef.h>). A conversão a ser usada com
printf() quando o argumento é do tipo
ptrdiff_t é
"%td", não
"%ld", como você fez. Possivelmente na sua máquina os tipos
ptrdiff_t e
long int têm a mesma representação interna, e por isso o compilador não alarmou incompatibilidade entre a conversão e o tipo do argumento, mas não se acostume a contar com essa coincidência, pois outra implementação pode usar representações diferentes, e o seu programa pode quebrar.
Outro problema com seu programa está na diferença
strlen(Letra)-strlen(Text) e na impressão do resultado. O tipo de retorno de
strlen() é
size_t, que é um inteiro sem sinal (provavelmente, na sua máquina, equivalente a
unsigned long int). Como tanto o minuendo quanto o subtraendo são do mesmo tipo sem sinal (
size_t), o resultado também é do mesmo tipo e, portanto, é
falso concluir que esse resultado é
-7, já porque esse valor não é representável como
size_t. A conversão correta a ser usada com
printf() quando o argumento é do tipo
size_t é
"%zu". O valor impresso como
-7 é resultado da conversão realizada dentro de
printf() porque você disse que o argumento seria de um tipo com sinal quando usou a conversão
"%ld". Possivelmente o compilador não alarmou porque na sua máquina
size_t e
long int têm o mesmo tamanho, e porque C aceita sem reclamar conversões implícitas entre inteiros com sinal e sem sinal quando eles têm o mesmo tamanho.
Se você quiser confirmar que o resultado não é negativo, você pode colocar as seguintes linhas no programa, e ver que a mensagem nunca será impressa.
if(strlen(Letra)-strlen(Text)<0))
puts("negativo");
Se estiver usando o GCC e compilar com a opção
-Wextra, vai ver a explicação para o comportamento dessas linhas, que confirma o que eu afirmei acima.
gcc -Wextra -Werror -O2 -pedantic-errors y.cc
y.cc: In function ‘int main()’:
y.cc:14:36: error: comparison of unsigned expression < 0 is always false [-Werror=type-limits]
if(strlen(Letra) - strlen(Text) < 0L)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
cc1plus: all warnings being treated as errors
Se quiser que essa subtração produza um valor negativo, você deve converter os operandos para um valor inteiro com sinal (ou então converter o resultado, que foi o que você acabou fazendo sem querer quando usou a conversão incorreta com
printf()).
... Então Jesus afirmou de novo: “(...) eu vim para que tenham vida, e a tenham plenamente.” (João 10:7-10)