[Duda]Usar variables en system (c)

Bueno, es en c, la cosa es, que intento abrir una url, pero el problema es que no se como poner la variable, para abrirlo, uso start, que creo que usa el navegador establecido como principal.

system("start ¿?¿?");

Ahi nose que poner, he probado con ' < variable ', con ' \"variable\" ', a ver si me echais un cable ^^

Saludos y feliz navidad
Dejando claro que no tengo ni idea (nunca he usado eso)

Si a system tienes que pasarle un string, porque no creas el string y se lo pasas?
es decir, un string que sea start+variable y se lo pasas a system
Exactamente, simplemente tienes que hacer un string con el comando que quieras ejecutar. Necesitaras crear un string suficientemente grande para meter el comando y los parametros, copiar todo allí y pasarselo a system para que ejecute el comando. No tiene mayor misterio que cualquier otro parametro de cualquier otra función que sea una cadena de caracteres.
Bueno, no se si lo he mencionado, pero soy novato, asique el amigo google me ayudara un poco, a ver, tengo esto:

scanf("%s",&url);//Introducimos url y la guarda en el char url
char url[37];
char start[7]="start ";//start, para abrir el link
system(strcat(start,url));//y bueno, la union


Esto funciona perfectamente (creo), algun cambio mas pro o asi es correcto?

Un saludo y gracias

EDIT: duda, todo el code.

#include <stdio.h>
#include <stdlib.h>

void end(){
     printf("\nPulsa para salir");
     }

int main(int argc, char *argv[])
{
  printf("------------------------------------\n");
  printf("|       Loader MV by FroX          |\n");
  printf("------------------------------------\n\n");
  printf("Escribe el final del link de MegaVideo\n");
  char url[37];
  scanf("%s",&url);
  char urlorig[255]="start http://wwwstatic.megavideo.com/mv_player.swf?v= ";
  system(strcat(urlorig,url));
 
  end();
  system("PAUSE>nul");   
  return 0;
}


Que falla? (no critiqueis el porque de MV xD)

EDIT2: ya fufa, era el espacio final en el char urlorig, muchas gracias
  scanf("%s",&url);


Creo que debe ir sin el &.
GameZelda escribió:
  scanf("%s",&url);


Creo que debe ir sin el &.


Eso esta bien, como segundo parametro necesita la direccion de la variable, aun asi ya lo tiene solucionado segun su EDIT.
kYp escribió:
GameZelda escribió:
  scanf("%s",&url);


Creo que debe ir sin el &.


Eso esta bien, como segundo parametro necesita la direccion de la variable, aun asi ya lo tiene solucionado segun su EDIT.


Bueno, pues resulta que ambas maneras son validas, con el & y sin él, porque tanto "a" como "&a" devuelven el mismo puntero para un array.

De todos modos, yo recomiendo sin el &, porque si usas memoria dinámica, debe ir sin el &.
Voy a ser un poco "pedante".

Como parametro tiene que ir lo que tiene que ir, no es que con una forma vaya con & y dinamica sin &, el caso es que malloc ya te da un puntero a la memoria reservada no hace falta obtenerla con &.

En ese caso es lo mismo por que en vectores es lo mismo "&Vector[0]" que "Vector".


Bueno ya respondimos los dos a que no era causa del & como decias :)
kYp escribió:Voy a ser un poco "pedante".

Como parametro tiene que ir lo que tiene que ir, no es que con una forma vaya con & y dinamica sin &, el caso es que malloc ya te da un puntero a la memoria reservada no hace falta obtenerla con &.

En ese caso es lo mismo por que en vectores es lo mismo "&Vector[0]" que "Vector".


Bueno ya respondimos los dos a que no era causa del & como decias :)


Mi error viene de que no conocía que "&x" diese el mismo resultado que "x" para un array (nunca me había encontrado con un ningún caso de este tipo, y (creo que) no tiene ningún uso práctico).

El caso es raro, porque mientras &a, en el caso de un puntero (T *) devuelve un puntero a un puntero (T **), en el caso de un array (T[n]) devuelve un puntero (T *), pero el mismo array ya se puede utilizar como si fuera un puntero directamente. No se si me explico mucho [+risas]
No se si te he entendido bien.

En el caso de un Puntero tienes una zona de memoria que va a guardar una direccion de memoria ( que no es la suya logicamente )

Por ejemplo int *px; -> esta almacenado en la direccion 0x00000000 y contiene como dato 0x00000020

si hago &px obtengo 0x00000000 si utilizo px=&x en lugar de 0x00000020 va a tener la direccion de memoria donde esta x
y si hago *px=30 voy a ir a la direccion de memoria que contiene px ( 0x00000020 ) y meter 30 en esa direccion.

Con los vectores, lo que se hace si por ejemplo se hace int V[5];
el compilador lo que hace es reservar un bloque de memoria todo junto de tamaño 5*sizeof(int) ( sizeof devuelve el tamaño que ocupa un tipo de dato, en general el tamaño de los int es de 4 bytes) y se tiene un puntero a la principio del bloque asi pues :

V = &V[0]
V+1*sizeof(int) = &V[1]
...

*V=12 es lo mismo que V[0]=12
*(V+1*sizeof(int))=30 es lo mismo que V[1]=30

(Aunque el compilador tira igual con V+1 en vez de multiplicar por el tamaño del tipo de dato por que ya lo comprueba el yo creo que para algo que nunca se hace, es mejor usaar sizeof por que queda mas claro xD)
Joder, cuanto me queda por aprender, PAlib y un poco de c, ahi voy xD

Esto es interesante, asique dos preguntas:

1º- que significa, por ejemplo, int valor[4][5];

2º- pregunta realmente tonta, alguna forma de hacer una GUI para c? como netbeans y javascript.
nazareth escribió:Joder, cuanto me queda por aprender, PAlib y un poco de c, ahi voy xD

Esto es interesante, asique dos preguntas:

1º- que significa, por ejemplo, int valor[4][5];

2º- pregunta realmente tonta, alguna forma de hacer una GUI para c? como netbeans y javascript.


Que no te siente mal lo que te voy a decir, porque no es mi intención, pero antes de pensar en GUIs ni nada por el estilo aprende a programar en C, porque no es lógico pensar en esas cosas y no saber lo que es "int valor[4][5]". Es un consejo para que no te pierdas en llamas a APIs y al final en vez de programar solo sepas "leer tutos", cosa muy usual en casos parecidos.

Respecto a tus preguntas:
1ª: int valor[4][5] es una declaración de un array bidimensional de 5x5 casillas (conceptualmente se puede pensar en el como en una tabla o un "array de arrays"). Es decir, para acceder a un valor del array se hace como en un array normal pero con dos índices. Por ejemplo "valor[0][3]" hace referencia a la posición [0][3] de la tabla (no pienses cual es la columna y cual la fila porque da igual, como a ti te guste mas).
De la misma manera se pueden declarar arrays de 3, 4, 5 o 20 dimensiones: "int valor[5][6][67][23][3]" sería un array de 5 dimensiones y se accedería igual (y no, no intentes imaginartelo porque imaginarse una estructura de datos de 5 dimensiones es imposible :D)

2º: Depende de la plataforma existirán unas librerías u otras, eso si, no esperes tener un editor gráfico de interfaces drag&drop para C porque eso, que yo sepa, no lo implementa ningún entorno. Aquí tienes que hacer el código a pelo (que es lo mismo que hace netbeans, solo que netbeans en java te autogenera el código de las interfaces que tu diseñes). Para windows yo he realizado alguna cosa con la WinAPI, pero simplemente tener una ventana con 2 botones ya es bastante locura. Si te da igual usar C++ tienes mas opciones. Si lo que estas pensando es tener una librería así en NDS yo diría que no existe ni para uno ni para otro.
kbks escribió:1ª: int valor[4][5] es una declaración de un array bidimensional de 5x5 casillas


4x5

kYp escribió:...


El concepto de los punteros ya lo tengo entendido de hace tiempo :p Lo único que me sorprendió fue lo del array (de todos modos no uso demasiado C últimamente).

kYp escribió:V+1*sizeof(int) = &V[1]

kYp escribió:(Aunque el compilador tira igual con V+1 en vez de multiplicar por el tamaño del tipo de dato por que ya lo comprueba el yo creo que para algo que nunca se hace, es mejor usaar sizeof por que queda mas claro xD)


No, no funciona así, si no que el valor que se incrementa al puntero depende del tipo, siempre se multiplica automaticamente y en cualquier caso por el tamaño, aunque tu ya lo hayas multiplicado antes. "(V+1) == &V[1]" y "(V+1*sizeof(int)) != &V[1]" para cualquier array.

#include <stdio.h>

int main(void)
{
    int *x = NULL;
    printf("%p %p\n", x, x + 1);
    return 0;
}


Escribe "00000000 00000004" o similar.
kbks escribió:Que no te siente mal lo que te voy a decir, porque no es mi intención, pero antes de pensar en GUIs ni nada por el estilo aprende a programar en C, porque no es lógico pensar en esas cosas y no saber lo que es "int valor[4][5]". Es un consejo para que no te pierdas en llamas a APIs y al final en vez de programar solo sepas "leer tutos", cosa muy usual en casos parecidos.


No, no me sienta mal tranquilo, la verdad que solo lo he preguntado por curiosidad mas que otra cosa ^^

kbks escribió:Respecto a tus preguntas:
1ª: int valor[4][5] es una declaración de un array bidimensional de 5x5 casillas (conceptualmente se puede pensar en el como en una tabla o un "array de arrays"). Es decir, para acceder a un valor del array se hace como en un array normal pero con dos índices. Por ejemplo "valor[0][3]" hace referencia a la posición [0][3] de la tabla (no pienses cual es la columna y cual la fila porque da igual, como a ti te guste mas).
De la misma manera se pueden declarar arrays de 3, 4, 5 o 20 dimensiones: "int valor[5][6][67][23][3]" sería un array de 5 dimensiones y se accedería igual (y no, no intentes imaginartelo porque imaginarse una estructura de datos de 5 dimensiones es imposible :D)

2º: Depende de la plataforma existirán unas librerías u otras, eso si, no esperes tener un editor gráfico de interfaces drag&drop para C porque eso, que yo sepa, no lo implementa ningún entorno. Aquí tienes que hacer el código a pelo (que es lo mismo que hace netbeans, solo que netbeans en java te autogenera el código de las interfaces que tu diseñes). Para windows yo he realizado alguna cosa con la WinAPI, pero simplemente tener una ventana con 2 botones ya es bastante locura. Si te da igual usar C++ tienes mas opciones. Si lo que estas pensando es tener una librería así en NDS yo diría que no existe ni para uno ni para otro.


1º- Osease, que int valor[256][192] seria 256x192 que seria el equivalente a todos los pixeles de cada una de las pantallas de la ds.... si que tiene xD

2º- Ya te digo, es por curiosidad, respecto a lo de c++, primeramente prefiero c, ya que es mas ameno a PAlib, tmb se puede usar c++, pero seria como mezclar cosas distintas, osease, en mi caso, me liaria aun mas ^^
kbks escribió:2º: Depende de la plataforma existirán unas librerías u otras, eso si, no esperes tener un editor gráfico de interfaces drag&drop para C porque eso, que yo sepa, no lo implementa ningún entorno. Aquí tienes que hacer el código a pelo (que es lo mismo que hace netbeans, solo que netbeans en java te autogenera el código de las interfaces que tu diseñes). Para windows yo he realizado alguna cosa con la WinAPI, pero simplemente tener una ventana con 2 botones ya es bastante locura. Si te da igual usar C++ tienes mas opciones. Si lo que estas pensando es tener una librería así en NDS yo diría que no existe ni para uno ni para otro.

Para GUIs en ordenador yo uso GTK+, que además es multiplataforma. Es un infierno al principio, pero cuando te acostumbras está bastante bien. Lo malo es la cantidad de dlls que hay que tener junto al ejecutable en windows...
Game_Zelda escribió:No, no funciona así, si no que el valor que se incrementa al puntero depende del tipo, siempre se multiplica automaticamente y en cualquier caso por el tamaño, aunque tu ya lo hayas multiplicado antes. "(V+1) == &V[1]" y "(V+1*sizeof(int)) != &V[1]" para cualquier array.


Juraria que iba tambien con sizeof, pero bueno menuda decepcion pensaba que C te dejaba fuchicar a tan bajo nivel como en asm pero no :/.
nazareth escribió:1º- que significa, por ejemplo, int valor[4][5];

En C significa que tienes 5 array's de tamaño 4, seguidos uno detras de otro, C almacena por filas , asi el valor de valor[0][1] tiene al lado de valor[1][1] y este a su lado el de valor[2][1] etc... Guardar la info para recorrerla por filas puede suponer un gran incremento del rendimiento , si se mete por medio la gestion de memoria del SO.
kYp escribió:
nazareth escribió:1º- que significa, por ejemplo, int valor[4][5];

En C significa que tienes 5 array's de tamaño 4, seguidos uno detras de otro, C almacena por filas , asi el valor de valor[0][1] tiene al lado de valor[1][1] y este a su lado el de valor[2][1] etc... Guardar la info para recorrerla por filas puede suponer un gran incremento del rendimiento , si se mete por medio la gestion de memoria del SO.

Es al revés, 4 arrays de 5 elementos cada uno. El [0][0] está al lado del [0][1], etc... Por ejemplo, si declaras algo como "int matriz[2][3] = { {1,2,3}, {4,5,6} };" estás dando el valor a las filas de la matriz.
En realidad da bastante igual, ya que puedes pensar que las filas es el primer índice y que las columnas es el segundo o al revés, que va a funcionar igual y conceptual mente va a estar bien. No es mas que un acceso a un valor mediante dos índices.
kYp escribió:
Game_Zelda escribió:No, no funciona así, si no que el valor que se incrementa al puntero depende del tipo, siempre se multiplica automaticamente y en cualquier caso por el tamaño, aunque tu ya lo hayas multiplicado antes. "(V+1) == &V[1]" y "(V+1*sizeof(int)) != &V[1]" para cualquier array.


Juraria que iba tambien con sizeof, pero bueno menuda decepcion pensaba que C te dejaba fuchicar a tan bajo nivel como en asm pero no :/.


Se puede, lo unico que es un poco "feo"...

#include <stdio.h>

int main(void)
{
    int *x = NULL;
    printf("%p %p\n", x, (int *)((char *)x + 1));
    return 0;
}
kbks escribió:En realidad da bastante igual, ya que puedes pensar que las filas es el primer índice y que las columnas es el segundo o al revés, que va a funcionar igual y conceptual mente va a estar bien. No es mas que un acceso a un valor mediante dos índices.

Da igual, pero no siempre. Por ejemplo:
int array[512][57];
int array[57][512];
En el primero estás puteando bastante más al procesador que en el segundo, ya que en el segundo puedes acceder a las filas de la 0 a la 56 multiplicando por 512, que se puede cambiar por un bitshift, mientras que en la primera, para acceder de la 0 a la 511 tienes que multiplicar por 57, que no se puede optimizar tanto. [sonrisa]

Aunque sí, en la mayoría de casos da bastante igual... Esto es solo si realmente quieres optimizar hasta en el más mínimo detalle. [+risas]
No me refería que internamente sean iguales (que evidentemente no lo són) si no a que conceptualmente si que lo són. Por ejemplo, ¿Que array de dos dimensiones usarías para crear una tabla de 512 filas y 57 columnas :D ? (Y no, no vale un array unidimensional de 29184 posiciones y un entero para dividirlo :D)

Con esto quiero decir que cual sea la columna y cual la fila al final lo adaptamos a lo que necesitemos en cada caso, ya sea por rendimiento (como en el ejemplo) o porque simplemente nos viene mejor así.
Pero hay que saber como funciona de verdad, aunque conceptualmente sea lo mismo.

Yo siempre escribo "array[filas][columnas]" por motivos de rendimiento. Y siempre recorro este tipo de arrays de fila en fila. Con cosas como esa, por ejemplo, la cache trabaja mejor, porque trabajas con datos que están al lado, y ganas en velocidad. Más de una vez he redondeado a una potencia de 2 las dimensiones de un array, aunque me cueste algo de espacio (cuando no es demasiado, claro xD), para facilitarle las cosas al programa. Por ejemplo, en lugar de poner array[60][60], pondría array[60][64]. Pero bueno, son simples detallitos que yo tengo para intentarle facilitar el trabajo al compilador y al programa...
GameZelda escribió:Se puede, lo unico que es un poco "feo"...

Ya se, me referia a que pensaba que te dejaba a ti meter a pelo el tamaño de bytes a saltar como en ASM, lo de que es feo andar con *(V+x) ni que decir queda xD.

ANTONIOND escribió:
kYp escribió:
nazareth escribió:1º- que significa, por ejemplo, int valor[4][5];

En C significa que tienes 5 array's de tamaño 4, seguidos uno detras de otro, C almacena por filas , asi el valor de valor[0][1] tiene al lado de valor[1][1] y este a su lado el de valor[2][1] etc... Guardar la info para recorrerla por filas puede suponer un gran incremento del rendimiento , si se mete por medio la gestion de memoria del SO.

Es al revés, 4 arrays de 5 elementos cada uno. El [0][0] está al lado del [0][1], etc... Por ejemplo, si declaras algo como "int matriz[2][3] = { {1,2,3}, {4,5,6} };" estás dando el valor a las filas de la matriz.


Confusion mia otra vez hoy ( no estoy fresco ) , Aparte de la velocidad debido a la cache del procesador, puedes tener perdidas de velocidad si tienes los datos ordenados (conceptualmente) por columnas, ya que en casos que no tengas la matriz entera en ram, puedes liarla parda por culpa de que haras muchas veces el volcado a disco y despues de disco a ram.
A lo que me refería es que si yo necesito muchas columnas y/o acceder a los datos por columna, si conceptualmente pienso en "array[columna][fila]" sería mas eficiente que si pienso en como se almacena en realidad en memoria.

No se si de esta manera se ganará rendimiento, pero cuando necesito arrays realmente grandes y es un proceso crítico suelo utilizar uno unidimensional delimitando el número de elementos por fila mediante un entero y una división. Lo suelo hacer precisamente por eso, por la caché, aunque la verdad es que nunca he comprobado si el rendimiento mejora realmente. ¿Alguien podría ilustrarme ya que estamos en el tema?
kbks escribió:A lo que me refería es que si yo necesito muchas columnas y/o acceder a los datos por columna, si conceptualmente pienso en "array[columna][fila]" sería mas eficiente que si pienso en como se almacena en realidad en memoria.

No se si de esta manera se ganará rendimiento, pero cuando necesito arrays realmente grandes y es un proceso crítico suelo utilizar uno unidimensional delimitando el número de elementos por fila mediante un entero y una división. Lo suelo hacer precisamente por eso, por la caché, aunque la verdad es que nunca he comprobado si el rendimiento mejora realmente. ¿Alguien podría ilustrarme ya que estamos en el tema?

Hombre, en el caso en el que leas las columnas seguidas, si te compensa hacerlo de ese modo. Lo que pasa es que en ese caso yo posiblemente haría un array de punteros que apuntase a cada fila o columna.
Bueno, por cuestiones de rendimiento segun antonio, int array[fila][columna], ahora, como se accede a ella? seria algo tipo:

Supongames que fila=1 y columna=2

array[1][2]= le damos valor o algo, no?

Se podria estableces un array[256][192] y asignar cada valor a un pixel? (referente pantalla de nds)
nazareth escribió:Bueno, por cuestiones de rendimiento segun antonio, int array[fila][columna], ahora, como se accede a ella? seria algo tipo:

Supongames que fila=1 y columna=2

array[1][2]= le damos valor o algo, no?

Se podria estableces un array[256][192] y asignar cada valor a un pixel? (referente pantalla de nds)

array[192 (numero de filas)][256 (numero de columnas)], y los índices van de 0 a 191 y de 0 a 255. Fila 100, columna 200 = [100][200];
GameZelda escribió:
kYp escribió:Voy a ser un poco "pedante".

Como parametro tiene que ir lo que tiene que ir, no es que con una forma vaya con & y dinamica sin &, el caso es que malloc ya te da un puntero a la memoria reservada no hace falta obtenerla con &.

En ese caso es lo mismo por que en vectores es lo mismo "&Vector[0]" que "Vector".


Bueno ya respondimos los dos a que no era causa del & como decias :)


Mi error viene de que no conocía que "&x" diese el mismo resultado que "x" para un array (nunca me había encontrado con un ningún caso de este tipo, y (creo que) no tiene ningún uso práctico).

El caso es raro, porque mientras &a, en el caso de un puntero (T *) devuelve un puntero a un puntero (T **), en el caso de un array (T[n]) devuelve un puntero (T *), pero el mismo array ya se puede utilizar como si fuera un puntero directamente. No se si me explico mucho [+risas]


El nombre de un vector NO es un puntero. Es una conversión:
http://stackoverflow.com/users/10136?ta ... y#sort-top

La prueba la tienes en que si lo pasas como parámetro a una función que modifica el puntero fallará.

Y por otro lado, no me parece que tengas entendido del todo lo que es un puntero cuando dices esto:
GameZelda escribió:El caso es raro, porque mientras &a, en el caso de un puntero (T *) devuelve un puntero a un puntero (T **), en el caso de un array (T[n]) devuelve un puntero (T *), pero el mismo array ya se puede utilizar como si fuera un puntero directamente. No se si me explico mucho [+risas]

De hecho el operador de "referencia" no lo pillas muy bien me temo.
El operador &, devuelve la posición de memoria donde está alojada una variable.
Un puntero es una dirección de memoria. Pero si almacenas un puntero en una variable entonces también tiene que guardarse en alguna parte: en otra posición en memoria.

Por tanto si tienes
int b= 20;
int *a = &b;
y haces &a, esto te devuelve la dirección de memoria donde está alojada la variable que contiene el puntero a. Y como una dirección de memoria es un puntero, lo que &a devuelve es un puntero, que apunta a otro puntero que apunta a la dirección de memoria donde está b.

Por cierto, el tema de la linealidad de memoria es temas de caché y es lógico si sabes cómo funciona la caché. Sin embargo al hacer array [x][y], la memoria asignada también es contigua.
Puedes tener algún problemilla al copiar partes del array que se expandan en varias filas, pero por temas de tipado.
zheo escribió:
GameZelda escribió:
kYp escribió:Voy a ser un poco "pedante".

Como parametro tiene que ir lo que tiene que ir, no es que con una forma vaya con & y dinamica sin &, el caso es que malloc ya te da un puntero a la memoria reservada no hace falta obtenerla con &.

En ese caso es lo mismo por que en vectores es lo mismo "&Vector[0]" que "Vector".


Bueno ya respondimos los dos a que no era causa del & como decias :)


Mi error viene de que no conocía que "&x" diese el mismo resultado que "x" para un array (nunca me había encontrado con un ningún caso de este tipo, y (creo que) no tiene ningún uso práctico).

El caso es raro, porque mientras &a, en el caso de un puntero (T *) devuelve un puntero a un puntero (T **), en el caso de un array (T[n]) devuelve un puntero (T *), pero el mismo array ya se puede utilizar como si fuera un puntero directamente. No se si me explico mucho [+risas]


El nombre de un vector NO es un puntero. Es una conversión:
http://stackoverflow.com/users/10136?ta ... y#sort-top

La prueba la tienes en que si lo pasas como parámetro a una función que modifica el puntero fallará.


No he dicho que un vector es un puntero, he dicho que un vector "se puede utilizar como si fuera un puntero directamente". Es decir, puedes "dereferenciarlo" (que es lo mismo que a[0]), etc., asignarlo a una variable puntero del mismo tipo, etc.

Lo de "La prueba la tienes en que si lo pasas como parámetro a una función que modifica el puntero fallará.", te refieres a una función que acepte un parámetro como por ejemplo "int **"? En este caso claro que fallará, como un array es un trozo de stack no existe el concepto de "modificar el puntero del array".

zheo escribió:Y por otro lado, no me parece que tengas entendido del todo lo que es un puntero cuando dices esto:
GameZelda escribió:El caso es raro, porque mientras &a, en el caso de un puntero (T *) devuelve un puntero a un puntero (T **), en el caso de un array (T[n]) devuelve un puntero (T *), pero el mismo array ya se puede utilizar como si fuera un puntero directamente. No se si me explico mucho [+risas]

De hecho el operador de "desreferencia" no lo pillas muy bien me temo.
El operador &, devuelve la posición de memoria donde está alojada una variable.
Un puntero es una dirección de memoria. Pero si almacenas un puntero en una variable entonces también tiene que guardarse en alguna parte: en otra posición en memoria.

Por tanto si tienes
int b= 20;
int *a = &b;
y haces &a, esto te devuelve la dirección de memoria donde está alojada la variable que contiene el puntero a. Y como una dirección de memoria es un puntero, lo que &a devuelve es un puntero, que apunta a otro puntero que apunta a la dirección de memoria donde está b.


No se si has entendido bien a lo que me referia con mi post. Algo como así:

int a = 123; // Tipo T
int *b = &a; // Tipo T *
int **c = &b; // Tipo T **

int d[123]; // Tipo T
int *e = d; // Tipo T *
int *f = &d; // Tipo T *, tambien


Simplemente esto me sorprendió, que tanto "d" como "&d" se pudieran convertir a una variable de tipo "T *", si "d" es un vector de tipo T.
No pretendo entrar en discusiones semánticas, pero a mi es lo que me dio a entender frases como estas:
GameZelda escribió:Mi error viene de que no conocía que "&x" diese el mismo resultado que "x" para un array (nunca me había encontrado con un ningún caso de este tipo, y (creo que) no tiene ningún uso práctico).

El caso es raro, porque mientras &a, en el caso de un puntero (T *) devuelve un puntero a un puntero (T **), en el caso de un array (T[n]) devuelve un puntero (T *), pero el mismo array ya se puede utilizar como si fuera un puntero directamente. No se si me explico mucho [+risas]


Sólo pretendía dejarlo claro, porque como pongo en el link, hay diferencias importantes (como hacer un sizeof)

GameZelda escribió:No se si has entendido bien a lo que me referia con mi post. Algo como así:

int a = 123; // Tipo T
int *b = &a; // Tipo T *
int **c = &b; // Tipo T **

int d[123]; // Tipo T
int *e = d; // Tipo T *
int *f = &d; // Tipo T *, tambien


Simplemente esto me sorprendió, que tanto "d" como "&d" se pudieran convertir a una variable de tipo "T *", si "d" es un vector de tipo T.

El error que tienes ahí es que en realidad d es un tipo T[]:
int d[123]; // Tipo T[]

Cuando haces
int *e = d
se hace una conversión automática a T* con la dirección de memoria del primer elemento del array...
Cuando usas el operador de referencia & (me equivoqué en mi post anterior, ya está corregido) pides la dirección de memoria del array, es decir, la dirección del primer elemento.

La utilidad es que así puedes usar aritmética de punteros en arrays estáticos.
zheo escribió:No pretendo entrar en discusiones semánticas, pero a mi es lo que me dio a entender frases como estas:
GameZelda escribió:Mi error viene de que no conocía que "&x" diese el mismo resultado que "x" para un array (nunca me había encontrado con un ningún caso de este tipo, y (creo que) no tiene ningún uso práctico).

El caso es raro, porque mientras &a, en el caso de un puntero (T *) devuelve un puntero a un puntero (T **), en el caso de un array (T[n]) devuelve un puntero (T *), pero el mismo array ya se puede utilizar como si fuera un puntero directamente. No se si me explico mucho [+risas]


Sólo pretendía dejarlo claro, porque como pongo en el link, hay diferencias importantes (como hacer un sizeof)

GameZelda escribió:No se si has entendido bien a lo que me referia con mi post. Algo como así:

int a = 123; // Tipo T
int *b = &a; // Tipo T *
int **c = &b; // Tipo T **

int d[123]; // Tipo T
int *e = d; // Tipo T *
int *f = &d; // Tipo T *, tambien


Simplemente esto me sorprendió, que tanto "d" como "&d" se pudieran convertir a una variable de tipo "T *", si "d" es un vector de tipo T.

El error que tienes ahí es que en realidad d es un tipo T[]:
int d[123]; // Tipo T[]

Cuando haces
int *e = d
se hace una conversión automática a T* con la dirección de memoria del primer elemento del array...
Cuando usas el operador de referencia & (me equivoqué en mi post anterior, ya está corregido) pides la dirección de memoria del array, es decir, la dirección del primer elemento.

La utilidad es que así puedes usar aritmética de punteros en arrays estáticos.


int d[123]; // Tipo T


Si, aqui si que me he equivocado, pero ahora, originalmente he dicho:

mientras &a, [...] en el caso de un array (T[n]) devuelve un puntero (T *)


Con lo de T[n] me refiero a un array de tipo "T" y "n" elementos:

int a[100]; // Tipo T[n]
int *b = &b; // Tipo T *


Y a lo de:

"&x" diese el mismo resultado que "x" para un array


Si, creo que aquí me equivoqué al expresarlo (doy a entender que un array es un puntero), si no que me referia a que un array es "a efectos prácticos" como si fuera un puntero, ya que la "conversión a puntero" actua casi siempre.

#include <stdio.h>
#include <assert.h>

int main()
{
    int a[10];
    printf("%p\n", a); // Imprimir el puntero al primer elemento de un array (printf es una funcion "variadic", con lo que queda probado que siempre que se pasa un array a una función, se pasa como un puntero).
    assert(a == &a); // Comparación de array con puntero
    a == 123; // (Con GCC, ni idea con el de Microsoft): "warning: comparison between pointer and integer"
    return 0;
}
Bueno, uso el mismo hilo.

Vereis, ahora me ha dado por intentar que lo que haga (de momento nada xD) funcione por comandos, es decir, tipo:

file.exe -a

Creo, segun vi en un src, se usa argv[] que se pone en el int main, pero no estoy nada seguro, ya que ese src era de c++.

Alguna idea/sugerencia/sabidura?
int main(int argc, char* argv[])
{
}
Si exacto, eso lo tiene de defecto pero no se como hacer para usarlo.

Otra pregunta referente a los ¿buffer?:

Creo sBuffer bfr; bien, vale, lo uso, bien, vale, ahora, con .length puedo saber si tamaño (creo recordar) pero la pregunta es, hay forma de eso pasarlo a un archivo? es decir, guardar la info?
nazareth escribió:Si exacto, eso lo tiene de defecto pero no se como hacer para usarlo.

Otra pregunta referente a los ¿buffer?:

Creo sBuffer bfr; bien, vale, lo uso, bien, vale, ahora, con .length puedo saber si tamaño (creo recordar) pero la pregunta es, hay forma de eso pasarlo a un archivo? es decir, guardar la info?

Sobre que lo del programa funcione con comandos, lo que debes hacer es hacer file.exe -a como tu has dicho y cambiar los parámetros del main de tal manera que el primero de ellos reciba una cadena y luego usar la variable en tu programa como si fuera una mas:
int main(char* argv[], int argc) {
    // Tratar argv como si fuera una variable mas.
}


Sobre lo de guardar buffer en un archivo, te recomiendo leerte la teoría de archivos: http://c.conclase.net/ficheros/index.php

Un saludo!
¡No puedes cambiar el orden de los argumentos que recibe main!

Los argumentos de main los recibe tu programa con las siguientes consideraciones.
Se considera un argumento cada palabra separada por un espacio al introducir el comando, incluyendo el propio comando, esto es:
mi-programa.exe -a=file -d

Recibe tres parámetros:

mi-programa.exe
-a=file
-d

Tu programa recibirá esa información por los dos argumentos de la función main, el primero recibe el número de parámetros que has pasado (en el ejemplo 3), el segundo recibe los parámetros pasados como un array de cadenas:

argc=3

argv[0]="mi-programa.exe"
argv[1]="-a=file"
argv[2]="-d"
zheo escribió:¡No puedes cambiar el orden de los argumentos que recibe main!

Los argumentos de main los recibe tu programa con las siguientes consideraciones.
Se considera un argumento cada palabra separada por un espacio al introducir el comando, incluyendo el propio comando, esto es:
mi-programa.exe -a=file -d

Recibe tres parámetros:

mi-programa.exe
-a=file
-d

Tu programa recibirá esa información por los dos argumentos de la función main, el primero recibe el número de parámetros que has pasado (en el ejemplo 3), el segundo recibe los parámetros pasados como un array de cadenas:

argc=3

argv[0]="mi-programa.exe"
argv[1]="-a=file"
argv[2]="-d"

Ahhh okkks xD
Ya decía yo que se me hacía raro cambiar el orden de los parámetros mientras lo escribía xD
Entiendo, probare y comentare, sobre lo del buffer, os explicon un poco mejor.

Es una libreria extra que uso en palib para bajar informacion de internet.

Se usa:
sBuffer bfr;
int r;
r=ky_geturl(sBuffer *bfr); -> ky_geturl(bfr);


La r se usa para saber si se ha bajado, creo (no estoy seguro) que si r=0, se ha bajado la info, sino, se queda en -1 (por el return de la funcion).

Ahora, bfr es un buffer donde va la info, como puedo usarlo o guardarlo via FAT?
Hace tiempo cuando hacía cosillas con la DS, se utilizaba libFAT para guardar archivos en la SD.
No se si se habrán inventado cosas nuevas, pero entonces, es lo que se usaba.

Un saludo.
Si, el EFS xD; pero se prefiere FAT, la cosa no es esa, eso se como anda (mas o menos) la cosa es, que tengo la info en el buffer bfr, y no se usarla, si fuese un char, si, ahi ya se, pero es un buffer, cada cosa que pruebo, error T_T
nazareth, no se si has mirado bien la teoría de funciones, para pasar variables de una a otra y usar llamadas, se hace bastante ameno. También te recomiendo que mires variables globales que uses en todas las funciones. A mi me ayudo en su día.

También mírate la diferencia entre &x y x, son bastante diferentes una vez que empiezas a usar memoria dinámica.

Espero que el comentario no venga en mal momento ;)

Un saludo!

por cierto, para usar un argumento pasado por linea de comandos es argv[1] (el primer comando es el ejecutable .exe pero ese no lo tocas, así que el "file" es argv[1]) no se si esa era tu duda :)
SI, algo me mire del &x y x, con &x obtienes la posicion en memoria del valor que almacenas y x es el valor en si, de todas formas, debo seguir mirando cosas, gracias por la respuesta.

Respecto a lo del argv no lo entiendo bien, a ver, argv[1] seria el programa.exe, no? el argv[0] no se usa?
argv[0] es el nombre del ejecutable, argv[1] el primer parametro. Antes te lo habían explicado muy bien. Respecto a lo de las globales, aunque se pueden usar, evitalas siempre (a no ser que estes haciendo pruebas con algún programa sencillo).
NeoSX escribió:También te recomiendo que mires variables globales que uses en todas las funciones. A mi me ayudo en su día.

Y yo te recomiendo que huyas de variables globales como de la peste.
zheo escribió:
NeoSX escribió:También te recomiendo que mires variables globales que uses en todas las funciones. A mi me ayudo en su día.

Y yo te recomiendo que huyas de variables globales como de la peste.


Y más en DS con su super ram xD

PD: En cuanto a lo de grabar lo que hay dentro del buffer, yo de ti me miraba como han implementado el tipo "sBuffer", ya que auguro que será un char* o algo parecido (o un struct con uno o varios de ellos). Y para grabarlo utiliza fopen, fwrite y fclose (si buscas en google verás como se usan dichas funciones).

Un Saludo ;)
zheo escribió:
NeoSX escribió:También te recomiendo que mires variables globales que uses en todas las funciones. A mi me ayudo en su día.

Y yo te recomiendo que huyas de variables globales como de la peste.


Personalmente cuando no dominas el pasar variables de una función a otra te quita del apuro, y visto que no lo domina mucho le ayudará. Después es quitar la variable global y recolocarlo, pero para ello tendrá que mirar un poco las funciones.
Davpk escribió:Y más en DS con su super ram xD

Esto... no tienes mucha idea de como maneja la memoria devkitARM, ¿verdad? xD

En la DS se usa como pila (Stack) una parte de la RAM especialmente rápida, la DTCM, que solo es de 16KB. Como te pases un poco con las variables locales, la lías, y gorda. En la DS, si hay que crear un array grande temporal, crealo con malloc, calloc o similares, pero no se te ocurra declararlo como variable local dentro de una función porque, como te pases, simplemente se intentará acceder a una dirección de memoria fuera de la DTCM y se acabó. De hecho, creo que lo primero que se modificaría al pasarse es el controlador de interrupciones, que está en la ITCM.

http://dev-scene.com/NDS/Tutorials_Day_2
dtcm stands for data tightly coupled memory and is a special area of memory on the ARM9 intended for use as fast data memory. The standard link script places the stack in this area. dtcm is a mere 16k so be careful with those local variables.
NeoSX escribió:
zheo escribió:
NeoSX escribió:También te recomiendo que mires variables globales que uses en todas las funciones. A mi me ayudo en su día.

Y yo te recomiendo que huyas de variables globales como de la peste.


Personalmente cuando no dominas el pasar variables de una función a otra te quita del apuro, y visto que no lo domina mucho le ayudará. Después es quitar la variable global y recolocarlo, pero para ello tendrá que mirar un poco las funciones.


Cuando no dominas el coche te ayuda mucho viajar en tren, pero si lo que quieres es aprender a conducir debes intentarlo hacerlo bien. Habituarse a las variables globales crea muy malos hábitos de programación ademas de un código muy dificil de mantener.
Estoy totalmente de acuerdo, pero para hacer un debug con dudas de si esta pasando bien la variable (aunque tambien puede hacer un printf a la variable para ver su contenido) quita el problema. De todas formas tampoco quiero desviar el hilo a la cuestion de variables globales. ¿Como va el programa? ¿Ya funciona?
61 respuestas
1, 2