Mi programa de paseo aleatorio se compila pero no se ejecuta. ¿Porqué es eso?

Su programa se ejecuta, simplemente no ve salida. Está haciendo exactamente lo que le dijiste que hiciera, que no es en absoluto lo que crees que le dijiste que hiciera. Aquí se explica cómo depurarlo, sin puntos de interrupción:

  • El hecho de que no vea ningún resultado significa que su bucle printf nunca se está ejecutando. Para que eso sea posible, ¿qué tendría que ser cierto? Respuesta: Tendría que ser cierto que el ciclo está dentro de otro bloque que nunca se está ejecutando. Si revisa su código, verá que ese es el caso. Arregla ese error primero.
  • OK, pero ahora, cuando ejecuta su código, imprime un montón de números en lugar de sus puntos y letras. Para que eso sea posible, ¿qué tendría que ser cierto? Respuesta: tendrías que estar usando el tipo incorrecto de argumento printf . Si revisa su código, verá que ese es el caso. Arregla ese error a continuación.
  • Bien, pero ahora, todo lo que obtenemos son un montón de puntos, sin letras. Para que eso sea posible, ¿qué tendría que ser cierto? Respuesta: su ciclo de paseo aleatorio nunca se ejecuta, o r nunca tiene un valor en el rango 0..3, o su prueba de si los cuatro movimientos posibles están bloqueados está interrumpida. Para que el ciclo nunca se ejecute, while () tendría que ser falso la primera vez; puede verificar esto agregando un printf () justo después de un tiempo . Pruebe esto y verá que el ciclo nunca se está ejecutando. Para que eso sea cierto, la verificación debe tener un valor cero; puede verificar esto agregando un printf para verificar antes de tiempo. Haga esto y verá que el cheque es inicialmente cero, ¡malo! Sin embargo, aquí hay algo interesante: si compila su aplicación en modo de lanzamiento, puede encontrar que el valor inicial de la comprobación no es cero. Debería poder ver fácilmente por qué es así y solucionar el problema para obtener un valor inicial de verificación adecuado. Arregla ese error a continuación.
  • Bueno, claro, pero ahora cuando ejecutas el programa se cuelga y finalmente se bloquea con un “Error de bus” o “Error de acceso ilegal” o algo similar. Para que eso suceda, ¿qué tendría que ser verdad? Respuesta: tendría que generar subíndices de matriz no válidos y luego usarlos para leer o escribir su matriz B. Por ejemplo, ¿qué pasaría si comienza la caminata en [0,0] y el valor inicial de r es 0? Esta solución requerirá un replanteamiento importante de su código. Hay dos formas principales de solucionarlo: agregue un borde de 1 celda alrededor y configúrelo inicialmente como, por ejemplo, “*”; o haga su prueba de celdas a las que no puede moverse y sus reglas para modificar el modo iyj son complejas. Arregle ese error, para los cuatro valores de r , a continuación.
  • Oh querido … ahora se cuelga y funciona para siempre, ¡nunca imprime nada! Para que eso suceda, ¿qué tendría que ser verdad? Respuesta: la condición de salida del while () nunca se cumple. Para que eso sea cierto, o nunca cambiaremos el valor de check , o nunca llegaremos a una condición en la que check sea la suma de a , b , c y d . Mirando el código, los valores de a, b, c y d nunca son nada más que cero, por lo tanto, agregarlos a check nunca cambia el valor de check . Para solucionar esto, debemos darles valores distintos de cero. ¿Pero qué valores? ¿Y cuál es el valor del cheque que queremos que eventualmente alcancen? Esta solución también requerirá un replanteamiento importante de su código. Básicamente, lo que quiere es un “conjunto” de direcciones bloqueadas, y cuando las cuatro direcciones están bloqueadas, desea salir del bucle while. Hay varias formas de implementar esto en C, pero hacer referencia al nombre de una variable de valor cero no es una de ellas. La forma profesional de implementar esto es con algunas funciones que crean las primitivas que necesita: borrar el conjunto, agregar dirección al conjunto, probar si las cuatro direcciones están configuradas. La forma de hacerlo es con algo así como máscaras de bits. De cualquier manera, es probable que te encuentres con los mismos errores, así que fingiré que usas máscaras de bits y te mostraré los errores que encontrarás. Aquí está la pista: a = 1, b = 2, c = 4, d = 8; el valor inicial de check es 0. Arregle este error a continuación.
  • Bien, entonces, después de hacer ese cambio, el comportamiento de la aplicación es impredecible. A veces se cuelga para siempre, y a veces imprime una cuadrícula de todos los puntos de inmediato. Para que eso suceda, ¿qué tendría que ser verdad? Respuesta: nuevamente, algo tiene que estar mal con el cálculo del cheque ; a veces, nunca llega al valor que queremos. Podemos depurar esto agregando un printf para verificar dentro del ciclo. Aquí hay una muestra de la salida de mi ejecución: 27623874 27623876 27623878 27623880 27623882 27623884 27623886. Así que la comprobación es obtener estos valores escandalosos, aunque solo le agreguemos 1, 2, 4 u 8 a la vez. El problema aquí es que agregar no es el operador correcto cuando se trabaja con máscaras de bits. Solucione este error a continuación.
  • ¿Ahora que? El programa finalmente se detiene e imprime la matriz con algunas o todas las letras AZ, pero la caminata realmente no parece aleatoria. Parece que el código sigue yendo en una dirección hasta que se agota la matriz, y luego elige otra dirección y va en esa dirección hasta que se agota la matriz. Además, después de ir en una dirección y llegar al final de la matriz, nunca vuelve a ir en esa dirección. Para que eso suceda, ¿qué tendría que ser verdad? Respuesta: el valor de check tendría que estar operando de forma acumulativa, para toda la ejecución del programa en lugar de restablecerse cada vez que nos mudemos a una nueva celda. Verifique el código y verá que este es el caso. Solucione este error a continuación.
  • Aún no está arreglado. Los resultados son casi los mismos que cuando no reiniciamos la verificación . Profundizando en el código un poco más, hay al menos dos problemas con la forma en que verificamos los límites de la matriz para i y j. Uno de ellos podría hacernos acceder a ubicaciones de matriz no válidas usando i o j, y el otro podría hacernos acceder a ubicaciones de matriz no válidas usando j. A pesar de que estos no explican el resultado, sin duda deberían ser reparados. Arregla estos a continuación.
  • Ahora, cada ejecución se ve igual: en mi máquina, comenzamos a descender por la columna del extremo izquierdo, luego a través de la parte inferior, luego retrocedemos por la columna del extremo derecho. Para que eso suceda, ¿qué tendría que ser verdad? Respuesta: algo podría estar mal con el código de número aleatorio. Al inspeccionar el código, vemos que srand () se llama cada vez a través del ciclo; esa no es la forma correcta de usar srand () . Solucione este error a continuación.
  • ¡Guauu! ¡Casi funciona ahora! Sin embargo, algunas ejecuciones tienen resultados corruptos, faltan algunos puntos al final de una fila o faltan filas completas. Para que eso suceda, ¿qué tendría que ser verdad? Respuesta: de alguna manera estamos almacenando un personaje inusual, como un NULL, en algunas de las ubicaciones de la matriz; tal vez esto significa que estamos usando caracteres distintos de AZ de alguna manera. ¿No era una de las reglas que se supone que debemos parar en Z? Solucione este error a continuación.
  • Éxito.

Christopher-Burkes-MacBook-Pro: ~ cburke $ ./a.out
BA. . . . . . . .
C . . . . . . . . .
D. . . . . . . . .
E . . . . . . . .
FGZYX. . . . .
IHOPWV. . . .
J. NQRU. . . .
KLM. S T . . . .
. . . . . . . . . .
. . . . . . . . . .
Christopher-Burkes-MacBook-Pro: ~ cburke $ ./a.out
HA. . . . . . . .
GBC . . . . . .
ALIMENTADO . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
Christopher-Burkes-MacBook-Pro: ~ cburke $ ./a.out
JABC . . . . .
YO . ED. . . . . .
HGF . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
Christopher-Burkes-MacBook-Pro: ~ cburke $ ./a.out
BCDQR. . . . .
AFEPS . . . .
. GNOTU. . . .
. HMXWV. . . .
. ILY. . . . . .
. JKZ . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
Christopher-Burkes-MacBook-Pro: ~ cburke $

Unas pocas cosas…

int a = 0;
int b = 0;
int c = 0;
int d = 0;
cheque int;

while (check! = a + b + c + d)
.
.
.
cheque = a + cheque;

check no está inicializado y puede contener cualquier valor (aleatorio) hasta que se establezca explícitamente. Algunos compiladores pueden inicializarlo automáticamente a 0, lo que hace que su declaración while sea falsa (0! = 0),

Nunca establece a, b, c o d en otra cosa que no sea 0 (en la inicialización), lo que efectivamente hace que todo su cheque = n + cheque ; declaraciones “check = 0 + {algún valor aleatorio en check desde el inicio}” Eso no cambiará el valor de check, y si se inicializa automáticamente a 0 siempre sería 0.

Tienes al menos dos errores que se destacan:
En sus comprobaciones: “if (((0 <= i) && (i <= 10)) && ((0 <= i) && (i <= 10)))" está comprobando i dos veces, cuando supongo que debería verificar tanto i como j (también i <10, j <10 ya que un valor de 10 está fuera de los límites).

Como sus cheques tienen un error, su programa “saldrá” de su matriz y probablemente obtendrá una excepción de acceso a la memoria.

El segundo problema es que: check! = A + b + c + d siempre será cierto y tienes un bucle infinito. Dado que a, b, c, d son todos cero, ¿cuál es el propósito de sumarlos? Reconsidere su condición de parada.

Examina las funciones que pueden simplificar tu vida dramáticamente.

Todo eso ONE_, TEN_, .. _DOTS puede ser reemplazado por:

memset(B,'.',100);

Entonces tenga en cuenta que puede reducir el espacio del problema. Se presenta como un problema bidimensional, que conduce a una gran locura B [i] [j]. Si te equivocas en alguna parte del código, tienes muchos dolores de cabeza garantizados.

Al reducir el espacio del problema, me refiero a considerarlo como un problema unidimensional. Después de todo, una matriz bidimensional en C se presenta en la memoria como una matriz unidimensional. Eso es lo que me permite simplificar su inicialización al memset anterior.

En el espacio bidimensional, la caminata aleatoria se define como [por ejemplo]:

B [i = 10] [j = 10]
Arriba = i–
Abajo = i ++
Izquierda = j–
Derecha = j ++

Eso es genial. Pero sería más fácil de varias maneras considerar el problema de esta manera:

B [i = 100]
Arriba = i-10
Abajo = i + 10
Izquierda = i–
Derecha = i ++

Así que hemos simplificado bastante el problema. A partir de aquí, la solución debería ser milagrosamente obvia. Incluso la verificación de límites es muy obvia:

// ¿podemos subir?
si ((i-10)> = 0)

// ¿podemos bajar?
si ((i + 10) <100)

// ¿podemos movernos a la izquierda?
if (((i-1) / 10) == (i / 10))

// ¿podemos movernos a la derecha?
if (((i + 1) / 10) == (i / 10))

La izquierda derecha puede parecer un poco extraña, pero todo lo que están haciendo es verificar el ajuste, ya que las reglas no nos permiten ajustar el borde de izquierda a derecha o de derecha a izquierda.

Debe verificar I y j antes de probar el elemento de matriz. Y el cheque no está establecido. ¿Y qué se supone que significan a, b, c, d? Mejores nombres de variables ayudarían.