Hola amig@s ya estoy de vuelta y leo varios mensajes
que buen debate hay, yo les tengo que decir que sé muy poco sobre el tema del stack manejado en forma de parametros, como lo plantea Mauricio. no se si será mejor o peor, ya la experiencia me lo dirá. y sus opiniones deben ser tomadas muy en cuenta por la gran experiencia que poseen.
en base a esa pregunta que haces Cryn es parte del siguiente estudio, pero me atrevo a decirte que en lenguaje C no se pasa un array como argumento, y por eso el uso de puntero es un buen ejemplo de aplicación, en tu código lo que debes hacer es pasar la dirección del primer dato como parámetro (usando el operador & )y luego dentro del código haces el llamado de los demas datos (ya sea usando el operador * ó por medio de subindices)
parámetro= argumento
continuamos ....
-
Punteros en Arrayscomo sabran los arrays son arreglos de datos que van en direcciones consecutivas, es decir, uno detras del otro. un ejemplo de ello:
char cadena[7]={'T','o','d','o','P','i','c'};
probandolo en un código:
#include <18F4550.h>
#use delay(clock=4000000)
//*********************************
char cadena[7]={'T','o','d','o','P','i','c'};
void main(){
char c;
int t;
for(t=0;t<7;t++){
c=cadena[t];
}
delay_cycles(1);
}
se puede usar punteros en el ejemplo anterior ¿como?
- declarando un puntero como char:
char c, *p;
- lo inicializamos (le damos la dirección del primer elemento del array:
p=&cadena[0];
- luego hacemos un barrido de direcciones para tomar el contenido de cada elemento y guardarlo en c
for(t=0;t<7;t++){
c= *p + t;
}
ese programa tiene 2 errores y ya de una les digo que no funcionará:
- el primer error:
según la precedencia del operador primero está el puntero y luego viene la suma, y así estariamos sumando direcciones que varian, la solución es usar *(p+i)
¿y que es eso de que varian?
cuando se recorre el arrays con el puntero, este debe ir sumando direcciones, pero direcciones de numeros constantes, es decir, si el tipo de datos es 1 byte, entonces el puntero debe acumular numeros enteros de 1 byte en 1 byte
si el tipo de datos es long (entero largo) entonces el puntero debe ir sumando direcciones de 2 bytes en 2 bytes
¿porque digo esto? es que p quedará fijo (la dirección) y el truco está en desplazar al puntero tantas posiciones sea el size del tipo de dato
este sería el segundo error y la solución es la misma *(p+i)
vamos a cambiar ese ejemplo por numeros long para que se entienda
#include <18F4550.h>
#use delay(clock=4000000)
//*********************************
long cadena[7]={1000,2000,3000,4000,5000,6000,7000};
void main(){
long c, *p;
int t;
p=&cadena[0];
for(t=0;t<7;t++){
c= *p + t;
}
delay_cycles(1);
}
fijense que p queda inmutable, y lo que hace el programa es contenido[0] + t
¡grave error!
arreglando el programa con *(p+t)
con esto estamos garantizando que el puntero se moverá de 2 bytes en 2 bytes, es decir
*(p+t) =
0x5 + 0x2 (desplazamiento de 2 byte)-> dame el contenido de la dirección 0x5
0x5 + 1x2 " -> dame el contenido de la dirección 0x7
0x5 + 2x2 " -> dame el contenido de la dirección 0x9
0x5 + 3x2 " -> dame el contenido de la dirección 0xA
...
noten que la suma se realiza no intervalos de t sino en intervalos del ancho del tipo de dato.
una pregunta ¿y esto no es lo mismo que se hizo en el código del inicio del post?
o sea que ¿ c = cadena[t]; es igual a c = *(p + t) cuando p = &cadena[0]; ?
pues si señores y señoras, acabamos de ver un array al desnudo, como funciona en realidad, no es mas que un vulgar puntero escondido a nuestra vista.
solo que para hacer fácil la programación el compilador lo acepta de esta manera
si p es un puntero -> p = cadena (para el primer indice del arreglo)
es totalmente válido, se acepta que cadena es un puntero constante, o como le diría yo: un puntero nulo (ya que no se ve y tampoco se puede modificar)
ejemplos validos:
cadena[0] = *cadena
cadena[2] = *(cadena + 2)
cadena
= *(cadena + i)
nota:
- el operador () es el primero que atiende el compilador antes que al resto
- cuando vayamos a matrices (arrays multidimensionales) vamos a ver con claridad el recorrido de un puntero
acomodando el código original, el que tenía la cadena de caracteres:
#include <18F4550.h>
#use delay(clock=4000000)
//*********************************
char cadena[7]={'T','o','d','o','P','i','c'};
void main(){
char c, *p;
int t;
p=cadena;
for(t=0;t<7;t++){
c=*(p+t);
}
delay_cycles(1);
}
Nota Errata: los ejemplos de programas de este post, donde sale ...p+i... en realidad quise decir ...p+t... la variable i no existe en los ejemplos de este post