[Ayuda] Programa en C

Iniciado por GatitoCai93, 24 Julio 2014, 16:04 PM

0 Miembros y 1 Visitante están viendo este tema.

GatitoCai93

Hola estaba programando en C unas cosas que tengo que presentar y como soy nuevo en C no se usar bien el dev c++. Acabo de hacer este algoritmo y me salta un error de "se ha producido una violacion de acceso a memoria" usando arreglos. Hace un tiempo el profesor me dijo algo sobre los arreglos diciendo que hay que usarlos de otra manera, porque de la manera que estaba en el teorico que dio habia que usarlo con puntero, y en C a puntero no lo vimos, si alguien me puede decir cual es el error de este codigo, le estaria muy agradecido! muchas gracias!

P/D: creo que el error esta en la funcion carga!

Código (c++) [Seleccionar]
#include <cstdlib>
#include <iostream>
#include <stdio.h>
#include <math.h>

/* Problema : Corazón = Cáscara: Dada una Matriz de [n x m] de enteros, con n >= 3 y m >=3, determinar si la
sumatoria de las celdas límites (cáscara) es igual que la sumatoria las celdas del interior (todas menos las
límites). Por ejemplo, para la siguiente matriz de (4x4) */

using namespace std;

const int N = 3;
const int M = 3;
int carga (int x);
int carga (int x) /* Funcion que permite cargar toda la matriz*/
{
 int register k,l;
 for (k=0;k<N;k++)
 {
   for (l=0;l<M;l++)
   {
     printf ("Ingrese un numero ");
     scanf ("%f",x);
   }
 }
}


int main(int argc, char *argv[])
{
   bool b;
   int arr[N][M];
   int cascara, corazon;
   int num;
   int c,d;
   int register i,j ;
   cascara = 0;
   corazon = 0;
   carga (num);
   for (i=0; i<N; i+1)
   {
     for (j=0; j<M; j+1)
     {
       cascara = (cascara + arr[i][j]);
       if ((i>0 && i<N-1)&&(j>0)&&(j<M-1))
       {
         corazon = (corazon + arr[i][j]);
       }
     }
   }
   cascara = (cascara - corazon);
   if (cascara == corazon)
   {
     b = 1;
   }
   else
   {
     b = 0;
   }
     
   system("PAUSE");
   return EXIT_SUCCESS;
}


Eternal Idol

Compilandolo con VC++ tenes estas advertencias y/o errores:

(40) : warning C4552: '+' : operator has no effect; expected operator with side-effect
(42) : warning C4552: '+' : operator has no effect; expected operator with side-effect
(26) : error C4716: 'carga' : must return a value
(39) : warning C4700: uninitialized local variable 'num' used
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

eferion

#2
Nota inicial: Para el código, usa las etiquetas GeSHi, gracias.

Código (cpp) [Seleccionar]

#include <cstdlib>
#include <iostream>
#include <stdio.h>
#include <math.h>


Si estás cargando las librerías cstdlib e iostream, estás programando en C++, no en C. Los includes de la librería estándar de C tienen TODOS el ".h"... en el caso de la librería de C++, NO hay includes con ".h". Te lo comento para que luego no te lleves sustos.

Código (cpp) [Seleccionar]
using namespace std;

Los espacios de nombre son también un elemento propio de C++... deberías quitarlo y, si te aparecen errores por ello, es porque estás haciendo uso de utilidades propias de C++.


int carga (int x);
int carga (int x) /* Funcion que permite cargar toda la matriz*/
{
}


Las declaraciones de funciones ( en tu caso la primera línea del código que te he puesto ) sólo son necesarias cuando aparecen llamadas a la función antes que su implementación. Un ejemplo:



void func3( void );

void func1( void )
{  puts( "Hola\n" ); }

int main( void )
{
 func1( ); // Ok, su uso es posterior a su implementacion
 func2( ); // Error, esta funcion no esta definida todavia
 func3( ); // Ok, no esta implementada pero si definida
}

void func2( void )
{ puts( "---\n" ); }

void func3( void )
{ puts( "Adios\n" ); }


Más cosas...


int carga (int x) /* Funcion que permite cargar toda la matriz*/
{
 int register k,l;
 for (k=0;k<N;k++)
 {
   for (l=0;l<M;l++)
   {
     printf ("Ingrese un numero ");
     scanf ("%f",x);
   }
 }
}


La llamada a "scanf" esta mal por tres razones:

1. %f se usa para números con decimales (float, double)... x es de tipo entero (int)
2. scanf necesita un puntero a la variable donde debe almacenar los valores que introduzca el usuario... 'x' se está pasando por valor
3. 'carga' está recibiendo 'x' por valor, es decir, todos los cambios que se hagan en 'x' se van a perder una vez el código sale de la función 'carga'.

Ah si... segun la firma actual, 'carga' debería tener un return y devolver un entero... si una función no ha de devolver nada debe ir precedida de 'void'.

La función debería estar más bien así:


void carga (int* x) /* Funcion que permite cargar toda la matriz*/
{
 int register k,l;
 for (k=0;k<N;k++)
 {
   for (l=0;l<M;l++)
   {
     printf ("Ingrese un numero ");
     scanf ("%d",x);
   }
 }
}


Ahora, 'x' es un puntero, por lo que, por un lado, scanf podrá almacenar el valor en la variable apuntada por 'x' sin problemas y, por otro, los cambios en 'x' se reflejarán fuera de la función.

Debido al cambio de la firma de "carga", también hay que cambiar ahora sus llamadas. "carga" ahora necesita un puntero:


int main(int argc, char *argv[])
{
   int num;
   carga (&num);
}


Más cosas...


int arr[N][M];
int cascara;
int i, j;
for (i=0; i<N; i+1)
{
 for (j=0; j<M; j+1)
 {
   cascara = (cascara + arr[j]);
 }
}


'arr' es un arreglo bidimensional, luego para acceder a sus valores necesitas pasarle dos índices... tu estás pasando sólamente uno. Esto tendría que quedar más o menos así:


int arr[N][M];
int cascara;
int i, j;
for (i=0; i<N; i+1)
{
 for (j=0; j<M; j+1)
 {
   cascara = (cascara + arr[i][j]);
 }
}


Además, 'arr' está definda tal que 'arr[N][M]'... no tiene sentido que le pases como primer índice 'j', que está definida en el rango '0..M'; necesitas un índice definido en el rango '0..N' y ese índice es 'i'... no 'j'.

Por otro lado, no has asignado valores a los elementos contenidos en 'arr', así como tampoco has asignado valores a 'cascara' (ni a otras tantas variables)... los resultados finales de las operaciones que tienes puestas ahí van a ser totalmente incoherentes, ya que estás leyendo basura:


int main( )
{
 int numero;
 printf( "%d\n", numero );
}


¿Qué imprime el código anterior? ¿tu lo sabes? yo lo único que se es que la salida del programa puede cambiar en diferentes ejecuciones. Sin embargo:


int main( )
{
 int numero = 10;
 printf( "%d\n", numero );
}


Estoy totalmente seguro que la salida de esta segunda versión será siempre '10'.

Más cosas... podría seguir pero creo que ya es bastante ayuda.

Moraleja: Estudia unos cuantos tutoriales o manuales de C antes de meterte en estos jardines... aprenderá más, será más satisfactorio para tí y aprenderás más ( lo pongo dos veces para darle énfasis... es importante).

dato000

#3
bueno aquí va el mio que hace tiempo no venia, si quieres puedes revisar estos links para consulta sobre paso de matrices como referencia a funciones.

http://www.zator.com/Cpp/E4_3_8.htm
http://cryptomex.org/Tutorial-LengC/arreglos-parametros.html
http://casicodigo.blogspot.com/2012/09/como-pasar-una-matriz-o-arreglo-como.html



EI: Codigo borrado, no se hacen tareas.



no es el mejor código, pero funciona bien o eso creo, de todas maneras una cosa más: DEV-C++ APESTA



leosansan

Cita de: dato000 en 24 Julio 2014, 17:35 PM
bueno aquí va el mio que hace tiempo no venia................



EI: Codigo borrado, no se hacen tareas.



no es el mejor código, pero funciona bien o eso creo, de todas maneras una cosa más: DEV-C++ APESTA

Creo que te sobra, y a GatitoCai93 también:

Código (cpp) [Seleccionar]
cascara = cascara - corazon;

¡¡¡¡ Saluditos! ..... !!!!