deve contar os elementos de uma lista, mas diz "*** - +: NIL não é um número"
(setq A '(2 3 4 3 2 6 7 8 4 3 5 6))
(defun big (A)
(if (not (null (car A))) (+ 1 (big (cdr A))) ) ;if the first element is not null, add 1 to the count of the elements to the rest of the list
)
(print (big A))
Uma IF
expressão tem 2 ou 3 argumentos:
(if test something)
(if test something something-else)
Quando tem apenas 2 argumentos, é como se o terceiro argumento something-else
,, fosse NIL. Isso significa que a IF
expressão é avaliada como NIL quando a test
expressão é falsa. No seu caso, você tem 2 argumentos:
(defun big (A)
(if (not (null (car A)))
;; "then" branch (when condition is true)
(+ 1 (big (cdr A)))
;; no "else" branch (when condition is false)
))
Então você sabe que às vezes uma ligação para big
pode retornar NIL
.
Mas, você também escreve:
(+ 1 (big (cdr A)))
Esta expressão parece com (+ 1 x)
com x
sendo uma chamada para big
, o que significa que x
pode avaliar a zero em alguns casos. Esse é o caso que você bate com o depurador.
Se você garantir que a if
expressão sempre retorne um número, retornando, por exemplo, zero no ramo else, você não terá o mesmo erro ao tentar adicionar um número a NIL
.
Mas então, você ainda teria outros bugs, já que diz que a função big
"deve contar os elementos de uma lista" . Se você quiser contar o elemento de uma lista, você nunca precisa olhar para os elementos armazenados na lista, você só precisa saber que eles existem.
Ao escrever (car a)
, você está acessando o primeiro elemento da lista. Você então verifica se esse valor não é nulo, mas é perfeitamente válido ter uma lista preenchida com valores NIL:
'(NIL NIL NIL)
Essa lista tem 3 elementos, e em nenhum momento o fato de serem NIL deve importar ao contá-los.
Uma função recursiva trabalhando em uma lista normalmente precisa cobrir dois casos, a saber, se a lista está vazia ou não. Você verifica se a lista atual está vazia chamando (null list)
ou (endp list)
(fazer isso (if list ... ...)
também funciona, pois NIL é o único valor falso).
Este artigo é coletado da Internet.
Se houver alguma infração, entre em [email protected] Delete.
deixe-me dizer algumas palavras