18.07.2014 Views

Parámetros y Argumentos en el Lenguaje de Programación C++

Parámetros y Argumentos en el Lenguaje de Programación C++

Parámetros y Argumentos en el Lenguaje de Programación C++

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Editorial <strong>de</strong> la Universidad<br />

Tecnológica Nacional<br />

Ciclo <strong>de</strong> Seminarios y Talleres d<strong>el</strong> Área <strong>de</strong> Programación<br />

Parámetros y <strong>Argum<strong>en</strong>tos</strong> <strong>en</strong> <strong>el</strong> L<strong>en</strong>guaje <strong>de</strong><br />

Programación <strong>C++</strong><br />

Ing. Ubaldo José Bonaparte<br />

Departam<strong>en</strong>to <strong>de</strong> Sistemas <strong>de</strong> Información<br />

Facultad Regional Tucumán<br />

Universidad Tecnológica Nacional<br />

U.T.N. - Arg<strong>en</strong>tina<br />

Editorial <strong>de</strong> la Universidad Tecnológica Nacional - edUTecNe<br />

http://www.edutecne.utn.edu.ar<br />

edutecne@utn.edu.ar


2- Ciclo <strong>de</strong> Seminarios y Talleres d<strong>el</strong> Area <strong>de</strong> Programación.<br />

Parámetros y <strong>Argum<strong>en</strong>tos</strong> <strong>en</strong> <strong>el</strong> l<strong>en</strong>guaje <strong>de</strong> programación <strong>C++</strong>.<br />

Prologo:<br />

Consi<strong>de</strong>rando la necesidad <strong>de</strong> una comunicación fluida <strong>en</strong>tre los<br />

doc<strong>en</strong>tes, fundam<strong>en</strong>talm<strong>en</strong>te <strong>en</strong>tre profesores d<strong>el</strong> Area <strong>de</strong> Programación 1 ,<br />

<strong>de</strong> la carrera <strong>de</strong> Ing<strong>en</strong>iería <strong>en</strong> Sistemas <strong>de</strong> Información, como integrante 2<br />

<strong>de</strong> la cátedra <strong>de</strong> Paradigmas <strong>de</strong> Programación <strong>el</strong>eve <strong>el</strong> proyecto “Ciclos<br />

<strong>de</strong> Seminarios y Talleres d<strong>el</strong> Area <strong>de</strong> Programación”. Dicho proyecto<br />

contempla la exposición <strong>de</strong> temas incluidos <strong>en</strong> la curricula o bi<strong>en</strong> <strong>de</strong><br />

actualidad, y <strong>el</strong> <strong>de</strong>bate <strong>en</strong>tre los pres<strong>en</strong>tes con <strong>el</strong> fin <strong>de</strong> mejorar nuestra<br />

didáctica, cont<strong>en</strong>idos teórico-prácticos y bibliografías.<br />

Parti<strong>en</strong>do <strong>de</strong> esta base, <strong>de</strong> gran importancia hacia un futuro<br />

perfeccionado <strong>de</strong> nuestros estudiantes, y <strong>de</strong>s<strong>de</strong> luego <strong>de</strong> nuestros<br />

doc<strong>en</strong>tes, creo indisp<strong>en</strong>sable que las palabras expresadas <strong>en</strong> los<br />

seminarios qued<strong>en</strong> docum<strong>en</strong>tadas a partir <strong>de</strong> escritos <strong>de</strong> este tipo.<br />

Detallando conceptos y ejemplificándolos <strong>de</strong> modo que toda persona<br />

r<strong>el</strong>acionada a esta casa <strong>de</strong> altos estudios, pueda consultar y <strong>en</strong>riquecer sus<br />

conocimi<strong>en</strong>tos.<br />

En estas líneas procuro introducir al lector a un tema muy<br />

específico d<strong>en</strong>tro <strong>de</strong> la programación utilizando <strong>el</strong> l<strong>en</strong>guaje <strong>C++</strong>.<br />

Simplem<strong>en</strong>te apunto a lectores con conocimi<strong>en</strong>tos básicos <strong>en</strong> dicho<br />

l<strong>en</strong>guaje y con ganas <strong>de</strong> aclarar o bi<strong>en</strong> perfeccionar sus programas<br />

haci<strong>en</strong>do un bu<strong>en</strong> uso <strong>de</strong> estas herrami<strong>en</strong>tas d<strong>en</strong>ominadas parámetros o<br />

argum<strong>en</strong>tos.<br />

1 Departam<strong>en</strong>to <strong>de</strong> Ing<strong>en</strong>iería <strong>en</strong> Sistemas <strong>de</strong> Información, Facultad Regional Tucumán<br />

2 Profesor Asociado Ordinario, Jefe <strong>de</strong> cátedra.


UTN, FRT, Departam<strong>en</strong>to <strong>de</strong> Sistemas <strong>de</strong> Información- 3<br />

Ing. Ubaldo José Bonaparte<br />

Indice<br />

1. Introducción 4<br />

2. Conceptos <strong>de</strong> Parámetros y <strong>Argum<strong>en</strong>tos</strong> 8<br />

3. Tipos <strong>de</strong> parámetros 8<br />

3.1. Parámetros por valor 9<br />

3.2. Parámetros por refer<strong>en</strong>cia 9<br />

3.3. Parámetros por refer<strong>en</strong>cia puntero 12<br />

3.4. Combinando tipos <strong>de</strong> parámetros 15<br />

4. La función main() y sus argum<strong>en</strong>tos 16<br />

5. Variedad <strong>de</strong> ejemplos usando parámetros 18<br />

5.1. Variable nativa <strong>en</strong>tera simple 18<br />

5.2. Variable <strong>de</strong> tipo estructura 19<br />

5.3. Variable <strong>de</strong> tipo estructura autorefer<strong>en</strong>ciada 20<br />

6. Variantes <strong>de</strong> parámetros y argum<strong>en</strong>tos 23<br />

6.1. <strong>Argum<strong>en</strong>tos</strong> por <strong>de</strong>fecto u omisión 23<br />

6.2. <strong>Argum<strong>en</strong>tos</strong> punteros a void 24<br />

6.3. <strong>Argum<strong>en</strong>tos</strong> no especificados o variables 25<br />

7. Conclusiones 35<br />

8. Bibliografía 35


4- Ciclo <strong>de</strong> Seminarios y Talleres d<strong>el</strong> Area <strong>de</strong> Programación.<br />

Parámetros y <strong>Argum<strong>en</strong>tos</strong> <strong>en</strong> <strong>el</strong> l<strong>en</strong>guaje <strong>de</strong> programación <strong>C++</strong>.<br />

Introducción:<br />

Cuando com<strong>en</strong>zamos a vincularnos con <strong>el</strong> apr<strong>en</strong>dizaje d<strong>el</strong><br />

<strong>de</strong>sarrollo <strong>de</strong> programas o bi<strong>en</strong> con algún l<strong>en</strong>guaje <strong>de</strong> programación <strong>en</strong><br />

particular, incorporamos una serie <strong>de</strong> conceptos nuevos que no formaban<br />

parte <strong>de</strong> nuestros días cotidianos. Lógica, variables, constantes,<br />

estructuras <strong>de</strong> datos, archivos, subprogramas, funciones etc. etc.<br />

Ent<strong>en</strong><strong>de</strong>mos la secu<strong>en</strong>cialidad <strong>de</strong> la ejecución <strong>de</strong> nuestros comandos o<br />

s<strong>en</strong>t<strong>en</strong>cias <strong>de</strong> programas, captamos los conceptos <strong>de</strong> input y output,<br />

hacemos nuestros primeros programas, continuamos creándolos y quizá<br />

<strong>de</strong>spués <strong>de</strong> unos cincu<strong>en</strong>ta expresamos saber programar.<br />

Ahora bi<strong>en</strong>, siempre he p<strong>en</strong>sado que <strong>el</strong> arte <strong>de</strong> programar requiere<br />

<strong>de</strong> un alto porc<strong>en</strong>taje <strong>de</strong> conocimi<strong>en</strong>tos sobre las herrami<strong>en</strong>tas que nos<br />

brinda <strong>el</strong> l<strong>en</strong>guaje <strong>de</strong> programación con <strong>el</strong> que trabajamos. Eso por un<br />

lado. Por otro, nuestra creatividad <strong>de</strong>be estar motivada y sust<strong>en</strong>tada sobre<br />

una base muy sólida <strong>de</strong> <strong>de</strong>talles madurados sobre lo que t<strong>en</strong>emos que<br />

programar. Así también, siempre p<strong>en</strong>samos que nuestros programas<br />

<strong>de</strong>b<strong>en</strong> ser amigables con <strong>el</strong> usuario, sólidos, consist<strong>en</strong>tes y robustos.<br />

Cuantas veces consultamos con colegas o bibliografía, sobre<br />

<strong>de</strong>talles m<strong>en</strong>ores o muy importantes ya que no visualizamos como aplicar<br />

nuestras herrami<strong>en</strong>tas para un fin <strong>de</strong>terminado. Des<strong>de</strong> luego apr<strong>en</strong><strong>de</strong>mos<br />

constantem<strong>en</strong>te y lo mejor <strong>de</strong> todo, es que nuestros proveedores <strong>de</strong><br />

l<strong>en</strong>guajes <strong>de</strong> programación no <strong>de</strong>jan <strong>de</strong> brindarnos tecnología nueva que<br />

nos exija <strong>de</strong>dicación, estudio y mucha práctica.<br />

Este seminario ti<strong>en</strong>e la bondad <strong>de</strong> hacer un aporte sobre <strong>el</strong><br />

paradigma procedim<strong>en</strong>tal, como parte <strong>de</strong> la programación imperativa<br />

puntualm<strong>en</strong>te sobre parámetros y argum<strong>en</strong>tos <strong>en</strong> funciones <strong>de</strong>sarrolladas<br />

<strong>en</strong> <strong>el</strong> l<strong>en</strong>guaje <strong>de</strong> programación <strong>C++</strong>. Siempre procurando trabajar sobre<br />

la formación d<strong>el</strong> programador <strong>en</strong> cuanto al ord<strong>en</strong> y manejo, que <strong>de</strong>be<br />

t<strong>en</strong>er sobre las variables y sus ámbitos <strong>en</strong> un programa. Y tratando <strong>de</strong><br />

evitar los efectos colaterales que produce <strong>el</strong> per<strong>de</strong>r control sobre las<br />

mismas.<br />

Los parámetros y argum<strong>en</strong>tos forman parte es<strong>en</strong>cial para la<br />

comunicación <strong>en</strong>tre funciones o procedimi<strong>en</strong>tos <strong>de</strong> nuestros programas.


UTN, FRT, Departam<strong>en</strong>to <strong>de</strong> Sistemas <strong>de</strong> Información- 5<br />

Ing. Ubaldo José Bonaparte<br />

Ya que por paradigma, es prohibitivo <strong>el</strong> manejo <strong>de</strong> variables<br />

globales, que si podrían ser reconocidas <strong>de</strong>s<strong>de</strong> procedimi<strong>en</strong>tos y<br />

funciones, nuestro recurso <strong>de</strong> comunicación se acreci<strong>en</strong>ta a partir <strong>de</strong><br />

parámetros y argum<strong>en</strong>tos. O sea, <strong>el</strong> ámbito <strong>de</strong> nuestras variables <strong>de</strong>be ser<br />

la función don<strong>de</strong> fueron <strong>de</strong>claradas y si necesitamos dichas variables <strong>en</strong><br />

otras funciones, haremos uso <strong>de</strong> parámetros y argum<strong>en</strong>tos para disponer<br />

<strong>de</strong> <strong>el</strong>las a<strong>de</strong>cuadam<strong>en</strong>te.<br />

Entonces, a partir <strong>de</strong> parámetros y argum<strong>en</strong>tos vamos a respetar y<br />

ext<strong>en</strong><strong>de</strong>r <strong>el</strong> ámbito <strong>de</strong> variables locales?. Si, eso trataremos <strong>de</strong> lograr y<br />

nos olvidaremos <strong>de</strong> gran parte <strong>de</strong> los efectos colaterales que las variables<br />

pued<strong>en</strong> producir.<br />

Un ejemplo simple para analizar<br />

Cargar los valores <strong>de</strong> un vector <strong>de</strong> números <strong>en</strong>teros, mostrar sus<br />

valores y obt<strong>en</strong>er la suma <strong>de</strong> dichos valores, significaría <strong>de</strong>sarrollar <strong>el</strong><br />

sigui<strong>en</strong>te programa.<br />

#inclu<strong>de</strong> <br />

#inclu<strong>de</strong> <br />

int arreglo[5] = {0,0,0,0,0}; // variable global inicializada<br />

void carga(){<br />

int i;<br />

for (i = 0; i < 5; i++)<br />

cin >> arreglo[i];<br />

}<br />

void muestra(){<br />

for (int i = 0;i < 5;i++)<br />

printf("%d,",arreglo[i]);<br />

}<br />

int suma(){<br />

int i,valor;


6- Ciclo <strong>de</strong> Seminarios y Talleres d<strong>el</strong> Area <strong>de</strong> Programación.<br />

Parámetros y <strong>Argum<strong>en</strong>tos</strong> <strong>en</strong> <strong>el</strong> l<strong>en</strong>guaje <strong>de</strong> programación <strong>C++</strong>.<br />

valor = 0;<br />

for (i = 0;i < 5;i++)<br />

valor += arreglo[i];<br />

return(valor);<br />

}<br />

void main(){<br />

carga();<br />

muestra();<br />

printf("\nLa suma <strong>de</strong> los <strong>el</strong>em<strong>en</strong>tos es = %d\n",suma());<br />

}<br />

La variable arreglo, <strong>de</strong> tipo vector <strong>de</strong> <strong>en</strong>teros es global al<br />

programa. Significa que po<strong>de</strong>mos disponer <strong>de</strong> <strong>el</strong>la <strong>en</strong> cualquier función,<br />

para observar u obt<strong>en</strong>er sus datos o bi<strong>en</strong> para modificarlos. Las variables<br />

i <strong>de</strong> tipo <strong>en</strong>tero, que utilizamos para variar los subíndices, ti<strong>en</strong><strong>en</strong> sus<br />

ámbitos <strong>en</strong> cada función; y porque no, podría haber sido global. Qui<strong>en</strong><br />

expresaría que este programa esta mal escrito, que ti<strong>en</strong>e efectos<br />

colaterales?. Dada su magnitud, ext<strong>en</strong>sión, cantidad <strong>de</strong> líneas y<br />

simplicidad, este programa no estaría mal escrito. Pero si aportaría sobre<br />

los malos hábitos <strong>de</strong> un futuro programador.<br />

Mejoremos nuestro primer ejemplo.<br />

#inclu<strong>de</strong> <br />

#inclu<strong>de</strong> <br />

type<strong>de</strong>f int arreglo[]; // <strong>de</strong>claración <strong>de</strong> un tipo arreglo <strong>de</strong> <strong>en</strong>teros<br />

void carga(arreglo &a){<br />

for (int i = 0;i < 5;i++)<br />

cin>>a[i];<br />

}<br />

void muestra(arreglo b){<br />

for (int i = 0;i < 5;i++)<br />

printf("%d,",b[i]);<br />

}


UTN, FRT, Departam<strong>en</strong>to <strong>de</strong> Sistemas <strong>de</strong> Información- 7<br />

Ing. Ubaldo José Bonaparte<br />

int suma(arreglo c){<br />

int valor = 0;<br />

for (int i = 0;i < 5;i++)<br />

valor += c[i];<br />

return(valor);<br />

}<br />

void main(){<br />

arreglo vector = {0,0,0,0,0};<br />

carga(vector);<br />

muestra(vector);<br />

printf("\nLa suma <strong>de</strong> los <strong>el</strong>em<strong>en</strong>tos es = %d\n",suma(vector));<br />

}<br />

Este programa funciona casi como <strong>el</strong> ejemplo anterior, para <strong>el</strong><br />

usuario se diría que igual. Nosotros como programadores observamos<br />

que las cosas son muy distintas. Disponemos d<strong>el</strong> tipo arreglo, que nos<br />

permite <strong>de</strong>finir variables <strong>de</strong> tipo arreglos <strong>de</strong> números <strong>en</strong>teros y<br />

dim<strong>en</strong>sionarlos. Definimos la variable vector local a la función main() y<br />

si queremos utilizarla <strong>en</strong> otras funciones, al invocarlas la pasamos como<br />

parámetro. A<strong>de</strong>más observamos que las variables i, ti<strong>en</strong><strong>en</strong> como ámbito<br />

solo las estructuras don<strong>de</strong> las usamos.<br />

Estamos com<strong>en</strong>zando a t<strong>en</strong>er bu<strong>en</strong>os hábitos, no <strong>de</strong>clarando<br />

variables globales, ext<strong>en</strong>di<strong>en</strong>do ámbitos <strong>de</strong> variables locales a funciones<br />

pasándolas como parámetros y <strong>de</strong>clarando variables solo <strong>en</strong> ámbitos<br />

don<strong>de</strong> son necesarias.


8- Ciclo <strong>de</strong> Seminarios y Talleres d<strong>el</strong> Area <strong>de</strong> Programación.<br />

Parámetros y <strong>Argum<strong>en</strong>tos</strong> <strong>en</strong> <strong>el</strong> l<strong>en</strong>guaje <strong>de</strong> programación <strong>C++</strong>.<br />

Conceptos <strong>de</strong> Parámetros y <strong>Argum<strong>en</strong>tos</strong><br />

Son <strong>el</strong> medio a partir d<strong>el</strong> cual po<strong>de</strong>mos expandir <strong>el</strong> ámbito <strong>de</strong><br />

variables locales <strong>de</strong> funciones, hacia otras funciones y a<strong>de</strong>más qui<strong>en</strong>es<br />

nos permit<strong>en</strong> establecer comunicaciones <strong>en</strong>tre funciones. Si nos vemos<br />

ante la necesidad <strong>de</strong> visualizar o modificar <strong>el</strong> valor <strong>de</strong> una variable local<br />

<strong>en</strong> otra función que llamaremos, <strong>de</strong>bemos invocar a dicha función<br />

haci<strong>en</strong>do refer<strong>en</strong>cia <strong>de</strong> su nombre, seguido <strong>de</strong> los parámetros o nombres<br />

<strong>de</strong> variables para las cuales, <strong>en</strong> teoría ampliaríamos su ámbito.<br />

void funcion_llamada(int x){ // función que recibe un argum<strong>en</strong>to<br />

:<br />

}<br />

void una_funcion(void){<br />

int a,b; // variables <strong>de</strong> ámbito local<br />

:<br />

:<br />

funcion_llamada(a); // llamada <strong>de</strong> la función con un parámetro<br />

:<br />

}<br />

La expresión funcion_llamada(a); se d<strong>en</strong>omina llamado a la función<br />

funcion_llamada con un parámetro a <strong>de</strong> tipo <strong>en</strong>tero. Y la expresión void<br />

funcion_llamada(int x) se d<strong>en</strong>omina cabecera <strong>de</strong> la función<br />

funcion_llamada con un argum<strong>en</strong>to, <strong>en</strong> este caso x, también <strong>de</strong> tipo<br />

<strong>en</strong>tero.<br />

Des<strong>de</strong> luego que, sobre la base <strong>de</strong> la comunicación <strong>en</strong>tre<br />

funciones y la teoría d<strong>el</strong> paradigma procedim<strong>en</strong>tal don<strong>de</strong> aplicamos la<br />

disgregación <strong>de</strong> procesos, nos po<strong>de</strong>mos <strong>en</strong>contrar con las sigui<strong>en</strong>tes<br />

variantes:<br />

1. Llamado <strong>de</strong> funciones sin pasar parámetros.<br />

2. Llamado <strong>de</strong> funciones pasando parámetros.<br />

esta claro que dichas funciones pued<strong>en</strong> o no <strong>de</strong>volvernos valores hacia <strong>el</strong><br />

orig<strong>en</strong> <strong>de</strong> su llamado.


UTN, FRT, Departam<strong>en</strong>to <strong>de</strong> Sistemas <strong>de</strong> Información- 9<br />

Ing. Ubaldo José Bonaparte<br />

Entonces, pasamos como parámetros nombres <strong>de</strong> variables al<br />

llamar una función, que <strong>de</strong>b<strong>en</strong> correspon<strong>de</strong>rse <strong>en</strong> su tipo al ser recibidos<br />

sobre los argum<strong>en</strong>tos <strong>de</strong> dicha función. Esto básicam<strong>en</strong>te es correcto,<br />

pero <strong>de</strong>bemos completar la i<strong>de</strong>a <strong>de</strong>scribi<strong>en</strong>do con claridad los tipos <strong>de</strong><br />

parámetros que nos permite manejar <strong>el</strong> l<strong>en</strong>guaje <strong>C++</strong>.<br />

Tipos <strong>de</strong> parámetros<br />

Los tipos <strong>de</strong> parámetros a utilizar van a <strong>de</strong>p<strong>en</strong><strong>de</strong>r siempre <strong>de</strong> la<br />

necesidad que se le pres<strong>en</strong>te al programador. De todos modos hay dos<br />

necesida<strong>de</strong>s básicas que g<strong>en</strong>eralm<strong>en</strong>te están vig<strong>en</strong>tes:<br />

1. Po<strong>de</strong>r obt<strong>en</strong>er <strong>el</strong> cont<strong>en</strong>ido <strong>de</strong> una variable.<br />

2. Po<strong>de</strong>r modificar <strong>el</strong> cont<strong>en</strong>ido <strong>de</strong> una variable.<br />

Parámetros por valor<br />

Cuando surge la necesidad <strong>de</strong> obt<strong>en</strong>er <strong>el</strong> valor o cont<strong>en</strong>ido <strong>de</strong> una<br />

variable original o local a una función, <strong>en</strong> otra función, se utiliza<br />

parámetros por valor. En este caso se produce una copia <strong>de</strong> la variable<br />

original hacia <strong>el</strong> argum<strong>en</strong>to formal <strong>de</strong> la función receptora. Dicha<br />

variable t<strong>en</strong>drá como ámbito la función receptora y al culminar esta<br />

liberará <strong>el</strong> espacio <strong>de</strong> memoria que ocupa.<br />

void imprime_cantidad(int can){<br />

printf(“%d\n”,can);<br />

}<br />

void alguna_funcion(void){<br />

int cantidad;<br />

:<br />

imprime_cantidad(cantidad);<br />

:<br />

}<br />

El valor <strong>de</strong> una variable original pue<strong>de</strong> pasar <strong>de</strong> una función a<br />

otra y a su vez a otras funciones, sin inconv<strong>en</strong>i<strong>en</strong>tes. De pronto <strong>en</strong>


10- Ciclo <strong>de</strong> Seminarios y Talleres d<strong>el</strong> Area <strong>de</strong> Programación.<br />

Parámetros y <strong>Argum<strong>en</strong>tos</strong> <strong>en</strong> <strong>el</strong> l<strong>en</strong>guaje <strong>de</strong> programación <strong>C++</strong>.<br />

nuestro <strong>de</strong>sarrollo, nos po<strong>de</strong>mos <strong>en</strong>contrar con una hoja <strong>de</strong> ruta <strong>de</strong><br />

valores <strong>de</strong> variables que pasan por funciones.<br />

Si usamos parámetros por valor, nunca podremos modificar los<br />

valores <strong>de</strong> las variables originales ya que se produc<strong>en</strong> copias <strong>de</strong> las<br />

mismas hacia las variables <strong>de</strong> la función llamada y su ámbito es local.<br />

Al utilizar parámetros por valor, éstos pued<strong>en</strong> ser constantes<br />

como por ejemplo:<br />

#inclu<strong>de</strong> <br />

void imprime_datos(char nombre[], int edad){<br />

printf("Nombre :%s , edad: %d\n",nombre, edad);<br />

}<br />

void main(void){<br />

char alias[35] = {"Pepe"};<br />

imprime_datos(alias,23);<br />

}<br />

Parámetros por refer<strong>en</strong>cia<br />

La refer<strong>en</strong>cia indica trabajar sobre la dirección <strong>de</strong> memoria que<br />

ocupa <strong>el</strong> parámetro o variable original.<br />

void ingresar_cantidad(int &can){<br />

cin>>can;<br />

}<br />

void alguna_funcion(void){<br />

int cantidad;<br />

:<br />

ingresar_cantidad(cantidad);<br />

:<br />

}


UTN, FRT, Departam<strong>en</strong>to <strong>de</strong> Sistemas <strong>de</strong> Información- 11<br />

Ing. Ubaldo José Bonaparte<br />

Como se observa <strong>en</strong> este ejemplo, <strong>el</strong> argum<strong>en</strong>to <strong>de</strong> la función<br />

receptora, pres<strong>en</strong>ta <strong>el</strong> operador unario & precedi<strong>en</strong>do al nombre <strong>de</strong> la<br />

variable. Esto indica que se tome la dirección d<strong>el</strong> parámetro hacia <strong>el</strong><br />

argum<strong>en</strong>to, produci<strong>en</strong>do un espejo o alias <strong>de</strong> la variable original<br />

cantidad. Lo cual significará, que toda alteración producida sobre <strong>el</strong><br />

argum<strong>en</strong>to can, afectará a la variable original o parámetro cantidad.<br />

Siempre que surja la necesidad <strong>de</strong> afectar a las variables<br />

originales <strong>de</strong>bemos usar parámetros por refer<strong>en</strong>cia. Algunos casos serían:<br />

cargar un dato o recalcular un dato.<br />

Ya que las funciones <strong>de</strong>vu<strong>el</strong>v<strong>en</strong> solo un valor, es habitual usar<br />

varios parámetros por refer<strong>en</strong>cia cuando necesitamos que una función<br />

provoque varios resultados y no solo uno.<br />

Si al argum<strong>en</strong>to por refer<strong>en</strong>cia lo prece<strong>de</strong>mos <strong>de</strong> la palabra const,<br />

dicha variable no podrá ser alterada <strong>en</strong> <strong>el</strong> ámbito <strong>de</strong> la función receptora,<br />

por lo tanto nunca afectará a la variable original.<br />

#inclu<strong>de</strong> <br />

void icrem<strong>en</strong>ta_sin_exito(int b)<br />

{ b++;} // no afecta a la variable original a<br />

void increm<strong>en</strong>ta_con_exito(const int &b)<br />

{ b++;} // Error <strong>de</strong> compilación<br />

void main(void){<br />

int a = 4;<br />

cout


12- Ciclo <strong>de</strong> Seminarios y Talleres d<strong>el</strong> Area <strong>de</strong> Programación.<br />

Parámetros y <strong>Argum<strong>en</strong>tos</strong> <strong>en</strong> <strong>el</strong> l<strong>en</strong>guaje <strong>de</strong> programación <strong>C++</strong>.<br />

Parámetros por refer<strong>en</strong>cia puntero<br />

Kernighan y Ritchie 3 <strong>el</strong> su capítulo apuntadores y arreglos nos<br />

hac<strong>en</strong> notar que la <strong>de</strong>finición <strong>de</strong> los argum<strong>en</strong>tos char s[]; y char *s; son<br />

completam<strong>en</strong>te equival<strong>en</strong>tes cuando se pasa un nombre <strong>de</strong> un arreglo <strong>de</strong><br />

caracteres a una función. Ya que al pasar un arreglo como parámetro, lo<br />

que <strong>en</strong> realidad se esta pasando es la dirección d<strong>el</strong> comi<strong>en</strong>zo d<strong>el</strong> mismo.<br />

Recor<strong>de</strong>mos la función carga() <strong>de</strong> nuestro ejemplo <strong>de</strong> un arreglo<br />

<strong>de</strong> números <strong>en</strong>teros.<br />

void carga(int &b){ // sin & funciona igual por que?<br />

for (int i = 0;i < 5;i++)<br />

cin>>b[i];<br />

}<br />

Si escribimos<br />

void carga(int * b){<br />

for (int i = 0;i < 5;i++)<br />

cin>>b[i];<br />

}<br />

o bi<strong>en</strong><br />

void carga(int * b){<br />

for (int i = 0;i < 5;i++)<br />

cin>>*b++;<br />

}<br />

<strong>en</strong> <strong>de</strong>finitiva y aceptando los conceptos <strong>de</strong> Brian y D<strong>en</strong>nis la variable<br />

original <strong>de</strong> tipo arreglo <strong>de</strong> <strong>en</strong>teros se verá modificada al producirse la<br />

carga <strong>de</strong> <strong>el</strong>em<strong>en</strong>tos, manipulando <strong>el</strong> arreglo a partir <strong>de</strong> subíndices o bi<strong>en</strong><br />

un puntero a <strong>en</strong>teros.<br />

3 Brian W. Kerninghan and D<strong>en</strong>nis M. Ritchie, El L<strong>en</strong>guaje <strong>de</strong> Programación C


UTN, FRT, Departam<strong>en</strong>to <strong>de</strong> Sistemas <strong>de</strong> Información- 13<br />

Ing. Ubaldo José Bonaparte<br />

modo:<br />

También podríamos haber escrito la función carga d<strong>el</strong> sigui<strong>en</strong>te<br />

void carga(int * b){<br />

for (int i = 0;*b == '\0';b++){<br />

i++;<br />

cin>>*b;<br />

}<br />

}<br />

siempre y cuando los <strong>el</strong>em<strong>en</strong>tos d<strong>el</strong> arreglo estén inicializados <strong>en</strong> cero,<br />

ya que <strong>de</strong> lo contrario t<strong>en</strong>dríamos algunos inconv<strong>en</strong>i<strong>en</strong>tes.<br />

Parámetros <strong>de</strong> tipo puntero o apuntadores siempre tomarán la<br />

dirección <strong>de</strong> la variable original, por consecu<strong>en</strong>cia la refer<strong>en</strong>cia a la<br />

misma.<br />

Los parámetros por refer<strong>en</strong>cia puntero pued<strong>en</strong> t<strong>en</strong>er <strong>el</strong> mismo<br />

cometido que los por refer<strong>en</strong>cia, solo <strong>en</strong> <strong>el</strong> concepto que al modificar un<br />

argum<strong>en</strong>to, se afectará al parámetro. Pero no <strong>en</strong> su tratami<strong>en</strong>to, don<strong>de</strong> se<br />

trabaja siempre sobre la base <strong>de</strong> la aritmética <strong>de</strong> punteros.<br />

Completemos la i<strong>de</strong>a, con un ejemplo s<strong>en</strong>cillo:<br />

#inclu<strong>de</strong> <br />

void increm<strong>en</strong>ta(int *b) {<br />

(*b)++;<br />

}<br />

void main(void){<br />

int a = 4;<br />

increm<strong>en</strong>ta(&a);<br />

cout


14- Ciclo <strong>de</strong> Seminarios y Talleres d<strong>el</strong> Area <strong>de</strong> Programación.<br />

Parámetros y <strong>Argum<strong>en</strong>tos</strong> <strong>en</strong> <strong>el</strong> l<strong>en</strong>guaje <strong>de</strong> programación <strong>C++</strong>.<br />

void increm<strong>en</strong>ta(int *b) {<br />

(*b)++;<br />

}<br />

void main(void){<br />

int a = 4; int * ptero;<br />

ptero = &a;<br />

increm<strong>en</strong>ta(ptero);<br />

cout


UTN, FRT, Departam<strong>en</strong>to <strong>de</strong> Sistemas <strong>de</strong> Información- 15<br />

Ing. Ubaldo José Bonaparte<br />

}<br />

void main(){<br />

matriz m = {0,0,0,0};<br />

cargapuntero(&m[0][0]);<br />

muestra(m);<br />

printf("\nLa suma <strong>de</strong> los <strong>el</strong>em<strong>en</strong>tos es = %d\n",suma(m));<br />

}<br />

Al trabajar con una variable subindizada y bidim<strong>en</strong>sional cuando<br />

invocamos a la función carga(), <strong>de</strong>bemos pasarle como parámetro la<br />

dirección <strong>de</strong> la variable local <strong>en</strong>tera m (&m[0][0]), para tratar la matriz<br />

con punteros. El argum<strong>en</strong>to <strong>de</strong> la función carga(), recibe dicha dirección<br />

sobre una variable <strong>de</strong> tipo puntero a un <strong>en</strong>tero a, y manipula las<br />

direcciones <strong>de</strong> memoria <strong>de</strong> la matriz m con la aritmética <strong>de</strong> punteros<br />

aplicada a dicha variable.<br />

Combinando tipos <strong>de</strong> parámetros<br />

Al invocar funciones, po<strong>de</strong>mos hacerlo pasando parámetros <strong>de</strong><br />

distintos tipos e inclusive con tipos <strong>de</strong> variables difer<strong>en</strong>tes.<br />

Prototipos <strong>de</strong> funciones como ejemplos:<br />

double mayor( double a, double b);<br />

Para averiguar cual cont<strong>en</strong>ido <strong>de</strong> variable es mayor, <strong>el</strong> tipo <strong>de</strong><br />

parámetro solo <strong>de</strong>be ser por valor.<br />

double suma_uno_al_mayor(double &, double &);<br />

Si <strong>de</strong>seamos increm<strong>en</strong>tar al cont<strong>en</strong>ido <strong>de</strong> la variable mayor <strong>en</strong><br />

uno, <strong>de</strong>bemos t<strong>en</strong>er <strong>en</strong> cu<strong>en</strong>ta que se podrá modificar una u otra variable.<br />

De modo que <strong>el</strong> tipo <strong>de</strong> parámetro <strong>de</strong>be ser por refer<strong>en</strong>cia.<br />

void carga_datos( cha * nombre, int & edad, int tipo);


16- Ciclo <strong>de</strong> Seminarios y Talleres d<strong>el</strong> Area <strong>de</strong> Programación.<br />

Parámetros y <strong>Argum<strong>en</strong>tos</strong> <strong>en</strong> <strong>el</strong> l<strong>en</strong>guaje <strong>de</strong> programación <strong>C++</strong>.<br />

Como tipo indicará alguna alternativa <strong>de</strong> ingreso <strong>de</strong> datos, <strong>el</strong><br />

parámetro es por valor. Y ya que <strong>el</strong> interés es afectar variables originales<br />

que respond<strong>en</strong> a un nombre y la edad, dichos parámetros son por<br />

refer<strong>en</strong>cia.<br />

int funcion(int, int &, char *, int *, float);<br />

Otras variantes <strong>de</strong> combinaciones <strong>de</strong> parámetros.<br />

La función main() y sus argum<strong>en</strong>tos.<br />

Los parámetros pasados <strong>en</strong> la línea <strong>de</strong> órd<strong>en</strong>es d<strong>el</strong> DOS o líneas<br />

<strong>de</strong> comandos d<strong>el</strong> Windows a un programa, son recibidos por la<br />

función main() sobre sus argum<strong>en</strong>tos. Exist<strong>en</strong> dos variables pre<strong>de</strong>finidas<br />

d<strong>en</strong>tro d<strong>el</strong> l<strong>en</strong>guaje que recib<strong>en</strong> los argum<strong>en</strong>tos que se pasan al ejecutar<br />

un programa.<br />

Tipo<br />

Finalidad<br />

conti<strong>en</strong>e <strong>el</strong> número <strong>de</strong> argum<strong>en</strong>tos que se han<br />

argc <strong>en</strong>tero<br />

introducido mas uno.<br />

argv array array <strong>de</strong> punteros a caracteres.<br />

El argv conti<strong>en</strong>e los parámetros que se han pasado <strong>de</strong>s<strong>de</strong> <strong>el</strong><br />

sistema operativo al invocar <strong>el</strong> programa. La <strong>de</strong>claración <strong>de</strong> los<br />

argum<strong>en</strong>tos es:<br />

La variable argc como mínimo valdrá 1, ya que <strong>el</strong> nombre d<strong>el</strong><br />

programa se toma como primer parámetro, almac<strong>en</strong>ado con argv[0], que<br />

es <strong>el</strong> primer <strong>el</strong>em<strong>en</strong>to <strong>de</strong> la matriz. Cada <strong>el</strong>em<strong>en</strong>to d<strong>el</strong> array apunta a un<br />

parámetro <strong>de</strong> la línea <strong>de</strong> órd<strong>en</strong>es. Todos los parámetros <strong>de</strong> la línea <strong>de</strong><br />

órd<strong>en</strong>es son cad<strong>en</strong>as.<br />

#inclu<strong>de</strong> <br />

void main(int argc, char *argv[]) {<br />

if(argc != 2){


UTN, FRT, Departam<strong>en</strong>to <strong>de</strong> Sistemas <strong>de</strong> Información- 17<br />

Ing. Ubaldo José Bonaparte<br />

printf("Ha olvidado su nombre.\n");<br />

return;}<br />

printf("Hola %s", argv[1]);<br />

printf("Parámetros d<strong>el</strong> usuario %d", argc);<br />

}<br />

Este programa imprime Hola y su nombre <strong>en</strong> la pantalla si se<br />

escribe directam<strong>en</strong>te tras <strong>el</strong> nombre d<strong>el</strong> programa. Supongamos que<br />

hemos llamado al programa saludo.cpp, <strong>en</strong>tonces, al compilarlo se creará<br />

un ejecutable saludo.exe, al llamar al programa saludo con un nombre,<br />

por ejemplo:Juan, para ejecutar <strong>el</strong> programa t<strong>en</strong>drá que introducir<br />

c:\tcwin\bin\saludo Juan<br />

Y la salida d<strong>el</strong> programa sería<br />

Hola Juan<br />

Parámetros d<strong>el</strong> usuario 2.<br />

Observaremos para un nuevo ejemplo, que a pesar <strong>de</strong> no<br />

ejecutarse inicialm<strong>en</strong>te la función main(), ya que se ejecuta la función<br />

inicio (especificado por #pragma startup), <strong>el</strong> comportami<strong>en</strong>to <strong>de</strong> los<br />

parámetros es igual al ejemplo anterior.<br />

#inclu<strong>de</strong> <br />

void inicio(void){<br />

printf("Com<strong>en</strong>zo la ejecución\n");<br />

}<br />

void fin(void){<br />

printf("\nTermino la ejecución\n");<br />

}<br />

#pragma startup inicio<br />

#pragma exit fin<br />

void main(int argc, char *argv[]) {<br />

if(argc < 2){<br />

printf("Ha olvidado su nombre.\n");


18- Ciclo <strong>de</strong> Seminarios y Talleres d<strong>el</strong> Area <strong>de</strong> Programación.<br />

Parámetros y <strong>Argum<strong>en</strong>tos</strong> <strong>en</strong> <strong>el</strong> l<strong>en</strong>guaje <strong>de</strong> programación <strong>C++</strong>.<br />

return; }<br />

<strong>el</strong>se<br />

printf("Hola %s\n", argv[1]);<br />

printf("Parametros %d", argc);<br />

}<br />

En la mayoría <strong>de</strong> los <strong>en</strong>tornos, cada parámetro <strong>de</strong> la línea <strong>de</strong><br />

órd<strong>en</strong>es <strong>de</strong>be estar separado por un espacio o una tabulación. Las comas,<br />

puntos y comas, y similares no se consi<strong>de</strong>ran separadores. argv[0]<br />

conti<strong>en</strong>e <strong>el</strong> path (camino) y nombre d<strong>el</strong> programa que se esta ejecutando.<br />

Main() pue<strong>de</strong> no recibir parámetros si fue <strong>de</strong>finida como:<br />

main(void) {<br />

:<br />

:<br />

return(tipo_<strong>de</strong>_dato);<br />

}<br />

Variedad <strong>de</strong> ejemplos usando parámetros<br />

Vamos a observar una serie <strong>de</strong> ejemplos que utilizan los tres tipos<br />

<strong>de</strong> parámetros sobre argum<strong>en</strong>tos <strong>de</strong> tipos distintos.<br />

Ejemplo para una variable nativa simple, <strong>en</strong>tera:<br />

#inclu<strong>de</strong> <br />

void increm<strong>en</strong>ta_valor(int b) // por valor no afecta a la variable original a<br />

{ b++;}<br />

void increm<strong>en</strong>ta_refer<strong>en</strong>cia(int &b) // afecta a la variable original a<br />

{ b++;}<br />

void increm<strong>en</strong>ta_ref_puntero(int *b) // afecta a la variable original a<br />

{ (*b)++;} // la aritmética <strong>de</strong> punteros nos exige colocar los paréntesis.<br />

void main(void){<br />

int a = 4; // variable local <strong>de</strong> la función main<br />

cout


UTN, FRT, Departam<strong>en</strong>to <strong>de</strong> Sistemas <strong>de</strong> Información- 19<br />

Ing. Ubaldo José Bonaparte<br />

increm<strong>en</strong>ta_valor(a);<br />

cout


20- Ciclo <strong>de</strong> Seminarios y Talleres d<strong>el</strong> Area <strong>de</strong> Programación.<br />

Parámetros y <strong>Argum<strong>en</strong>tos</strong> <strong>en</strong> <strong>el</strong> l<strong>en</strong>guaje <strong>de</strong> programación <strong>C++</strong>.<br />

suma_ref_puntero(&b);<br />

cout


UTN, FRT, Departam<strong>en</strong>to <strong>de</strong> Sistemas <strong>de</strong> Información- 21<br />

Ing. Ubaldo José Bonaparte<br />

suma_ref_puntero(&b);<br />

cout


22- Ciclo <strong>de</strong> Seminarios y Talleres d<strong>el</strong> Area <strong>de</strong> Programación.<br />

Parámetros y <strong>Argum<strong>en</strong>tos</strong> <strong>en</strong> <strong>el</strong> l<strong>en</strong>guaje <strong>de</strong> programación <strong>C++</strong>.<br />

cout


UTN, FRT, Departam<strong>en</strong>to <strong>de</strong> Sistemas <strong>de</strong> Información- 23<br />

Ing. Ubaldo José Bonaparte<br />

Ahora bi<strong>en</strong>, al pasar como parámetro la dirección <strong>de</strong> la variable a,<br />

<strong>de</strong>be ser recibida por un argum<strong>en</strong>to <strong>de</strong> tipo puntero a puntero <strong>de</strong> un<br />

<strong>en</strong>tero. En este caso toda modificación que se produzca sobre <strong>el</strong><br />

cont<strong>en</strong>ido d<strong>el</strong> argum<strong>en</strong>to afectará a la variable original.<br />

Para no afectar a la variable original, se <strong>de</strong>be pasar como<br />

parámetro <strong>el</strong> cont<strong>en</strong>ido <strong>de</strong> la misma increm<strong>en</strong>ta_valor(*a); que será<br />

recibido <strong>en</strong> un argum<strong>en</strong>to <strong>de</strong> tipo <strong>en</strong>tero.<br />

Variantes <strong>de</strong> parámetros y argum<strong>en</strong>tos<br />

Ya conocidos los tipos <strong>de</strong> parámetros básicos, po<strong>de</strong>mos ver<br />

algunas variantes que <strong>C++</strong> nos brinda como alternativas validas <strong>en</strong> la<br />

especificación <strong>de</strong> argum<strong>en</strong>tos <strong>de</strong> funciones.<br />

<strong>Argum<strong>en</strong>tos</strong> por <strong>de</strong>fecto (omisión)<br />

Una mejora <strong>de</strong> las funciones <strong>en</strong> <strong>C++</strong> es que se pued<strong>en</strong> especificar<br />

los valores por <strong>de</strong>fecto para los argum<strong>en</strong>tos cuando se proporciona un<br />

prototipo <strong>de</strong> una función. Cuando se llama a una función se pued<strong>en</strong><br />

omitir argum<strong>en</strong>tos e inicializarlos a un valor por <strong>de</strong>fecto.<br />

Un argum<strong>en</strong>to por <strong>de</strong>fecto u omisión es un parámetro que <strong>el</strong><br />

llamado a una función no va a proporcionar. Los argum<strong>en</strong>tos por <strong>de</strong>fecto<br />

también pued<strong>en</strong> ser parámetros opcionales. Si se pasa un valor a uno <strong>de</strong><br />

<strong>el</strong>los, se utiliza ese valor. Si no se pasa un valor a un parámetro opcional,<br />

se utiliza un valor por <strong>de</strong>fecto como argum<strong>en</strong>to.<br />

Ejemplo:<br />

#inclu<strong>de</strong> <br />

void f(int ,int = 2); // prototipo <strong>de</strong> función<br />

void main(){<br />

f(4,5);


24- Ciclo <strong>de</strong> Seminarios y Talleres d<strong>el</strong> Area <strong>de</strong> Programación.<br />

Parámetros y <strong>Argum<strong>en</strong>tos</strong> <strong>en</strong> <strong>el</strong> l<strong>en</strong>guaje <strong>de</strong> programación <strong>C++</strong>.<br />

f(6);<br />

}<br />

void f(int i, int j){<br />

cout


UTN, FRT, Departam<strong>en</strong>to <strong>de</strong> Sistemas <strong>de</strong> Información- 25<br />

Ing. Ubaldo José Bonaparte<br />

ver(cad,cad<strong>en</strong>a);<br />

}<br />

void ver( void *p, dato d){<br />

switch(d){<br />

case caracter: printf("%c\n",*(char *)p);<br />

break;<br />

case <strong>en</strong>tero: printf("%d\n",*(int *)p);<br />

break;<br />

case real: printf("%ld\n",*(double *)p);<br />

break;<br />

case cad<strong>en</strong>a: printf("%s\n",(char *)p);<br />

}<br />

}<br />

El argum<strong>en</strong>to void *p recibe <strong>el</strong> parámetro <strong>en</strong>viado <strong>de</strong>sconoci<strong>en</strong>do<br />

<strong>el</strong> tipo, lo cual es indisp<strong>en</strong>sable <strong>de</strong> especificar para direccionar, como <strong>en</strong><br />

<strong>el</strong> printf() <strong>de</strong> la función ver() *(char *)p, <strong>en</strong> <strong>el</strong> caso <strong>de</strong> ser un caracter. En<br />

este caso nos apoyamos sobre <strong>el</strong> <strong>en</strong>umerado dato, para id<strong>en</strong>tificar <strong>el</strong> tipo<br />

al que apunta *p.<br />

<strong>Argum<strong>en</strong>tos</strong> no especificados o variables<br />

<strong>C++</strong> permite <strong>de</strong>clarar una función cuyo número y tipo <strong>de</strong><br />

argum<strong>en</strong>tos no son conocidos <strong>en</strong> <strong>el</strong> mom<strong>en</strong>to <strong>de</strong> la compilación. Esta<br />

característica se indica con la ayuda d<strong>el</strong> operador especial puntos<br />

susp<strong>en</strong>sivos (...) <strong>en</strong> la <strong>de</strong>claración <strong>de</strong> la función. void f1(...);<br />

Esta <strong>de</strong>claración indica que f1 es una función que no <strong>de</strong>vu<strong>el</strong>ve<br />

ningún valor y que tomará un número variable <strong>de</strong> argum<strong>en</strong>tos <strong>en</strong> cada<br />

llamada. Si algunos argum<strong>en</strong>tos se conoc<strong>en</strong>, <strong>de</strong>b<strong>en</strong> situarse al principio<br />

<strong>de</strong> la lista:<br />

void f2(int a,float b,...);<br />

Los puntos susp<strong>en</strong>sivos indican que la función se pue<strong>de</strong> llamar<br />

con difer<strong>en</strong>tes conjuntos <strong>de</strong> argum<strong>en</strong>tos <strong>en</strong> distintas ocasiones. Este


26- Ciclo <strong>de</strong> Seminarios y Talleres d<strong>el</strong> Area <strong>de</strong> Programación.<br />

Parámetros y <strong>Argum<strong>en</strong>tos</strong> <strong>en</strong> <strong>el</strong> l<strong>en</strong>guaje <strong>de</strong> programación <strong>C++</strong>.<br />

formato <strong>de</strong> prototipo reduce la cantidad <strong>de</strong> verificación que <strong>el</strong> compilador<br />

realiza.<br />

Así, la función pre<strong>de</strong>finida printf(), que ti<strong>en</strong>e <strong>el</strong> prototipo:<br />

int printf(char *formato,...);<br />

Esto significa que la función <strong>de</strong>vu<strong>el</strong>ve un <strong>en</strong>tero y acepta un<br />

puntero a un parámetro fijo <strong>de</strong> caracteres y cualquier número <strong>de</strong><br />

parámetros adicionales <strong>de</strong> tipo <strong>de</strong>sconocido. Con este prototipo, <strong>el</strong><br />

compilador verifica <strong>en</strong> tiempo <strong>de</strong> compilación los parámetros fijos, y los<br />

parámetros variables se pasan sin verificación <strong>de</strong> tipos.<br />

Para <strong>en</strong>t<strong>en</strong><strong>de</strong>r cómo es posible crear este tipo <strong>de</strong> funciones con<br />

parámetros variables, es interesante compr<strong>en</strong><strong>de</strong>r aunque sólo sea <strong>de</strong><br />

manera superficial, cómo funciona un compilador. En especial <strong>el</strong><br />

mecanismo <strong>de</strong> llamadas a funciones.<br />

Cuando <strong>el</strong> compilador traduce <strong>el</strong> código fu<strong>en</strong>te a código máquina<br />

utiliza una pila para realizar ciertas tareas. La pila es, básicam<strong>en</strong>te, una<br />

zona <strong>de</strong> almac<strong>en</strong>ami<strong>en</strong>to temporal <strong>en</strong> memoria a la cual se hace<br />

refer<strong>en</strong>cia con un puntero. A través <strong>de</strong> este puntero se pue<strong>de</strong> conocer sus<br />

cont<strong>en</strong>idos. Cuando se llama a una función, se crea una nueva zona <strong>en</strong><br />

<strong>el</strong>la (un frame) don<strong>de</strong> se almac<strong>en</strong>a cierta información, como por ejemplo,<br />

la dirección <strong>de</strong> retorno, las variables automáticas <strong>de</strong> la función, etc. A<br />

nosotros, lo que nos interesa es que <strong>en</strong> esa zona, también se copian los<br />

argum<strong>en</strong>tos <strong>de</strong> la función.<br />

En C los argum<strong>en</strong>tos se pasan por valor, es <strong>de</strong>cir, se hac<strong>en</strong> copias<br />

<strong>de</strong> los mismos, y por eso po<strong>de</strong>mos usarlos como variables d<strong>en</strong>tro d<strong>el</strong><br />

cuerpo <strong>de</strong> la función, sin miedo a que varí<strong>en</strong> fuera, y <strong>de</strong>bemos trabajar<br />

con punteros cuando queremos <strong>el</strong> comportami<strong>en</strong>to contrario, es <strong>de</strong>cir <strong>el</strong><br />

paso <strong>de</strong> argum<strong>en</strong>tos por refer<strong>en</strong>cia.<br />

Veamos un caso s<strong>en</strong>cillo. T<strong>en</strong>emos la sigui<strong>en</strong>te función y<br />

llamada:


UTN, FRT, Departam<strong>en</strong>to <strong>de</strong> Sistemas <strong>de</strong> Información- 27<br />

Ing. Ubaldo José Bonaparte<br />

void funcion(int a, int b);<br />

funcion(10, 20);<br />

En <strong>el</strong> frame <strong>de</strong> la pila t<strong>en</strong>dremos los valores <strong>de</strong> dichas variables.<br />

Por lo tanto, si la dirección <strong>de</strong> memoria d<strong>el</strong> primer parámetro es X, <strong>el</strong><br />

cont<strong>en</strong>ido [X] es 10 –<strong>en</strong> ad<strong>el</strong>ante, usaré la conv<strong>en</strong>ción <strong>de</strong> los corchetes<br />

para indicar <strong>el</strong> cont<strong>en</strong>ido <strong>de</strong> una posición <strong>de</strong> memoria-. A<strong>de</strong>más, <strong>el</strong><br />

segundo parámetro estará <strong>en</strong> XXXX+sizeof(int), por<br />

tanto [X+sizeof(int)] es 20.<br />

Parece claro que las variables están contiguas <strong>en</strong> memoria. Si<br />

t<strong>en</strong>emos ahora una función y la llamada:<br />

void funcion(char *s , ... );<br />

funcion("Estos son dos<br />

números: %d y %f", 10, 0.5);<br />

Entonces, como vimos antes, sabemos que [X], por ser un puntero<br />

conti<strong>en</strong>e la dirección <strong>de</strong> memoria don<strong>de</strong> se almac<strong>en</strong>a la letra 'E'. Pero<br />

a<strong>de</strong>más, sabemos que <strong>de</strong> existir otro parámetro este estaría <strong>en</strong> la<br />

posición X+sizeof(char *), y que <strong>el</strong> sigui<strong>en</strong>te estaría <strong>en</strong>X+sizeof(char<br />

*)+sizeof(tipo) -<strong>el</strong> tipo es <strong>de</strong>sconocido a priori-. Es aritmética <strong>de</strong><br />

punteros pura. De este modo, es s<strong>en</strong>cillo obt<strong>en</strong>er todos los argum<strong>en</strong>tos<br />

que se pas<strong>en</strong> a la función, sin importar cuantos sean ni <strong>de</strong> que tipo.<br />

En realidad, esto no ti<strong>en</strong>e porque suce<strong>de</strong>r <strong>de</strong> este modo tan i<strong>de</strong>al,<br />

<strong>de</strong>p<strong>en</strong><strong>de</strong>rá <strong>de</strong> la arquitectura, <strong>el</strong> sistema operativo, <strong>el</strong> compilador, etc. Sin<br />

embargo, este mod<strong>el</strong>o <strong>de</strong> posiciones contiguas para los argum<strong>en</strong>tos es la<br />

base d<strong>el</strong> sistema que usa C, y ayudará al lector a <strong>en</strong>t<strong>en</strong><strong>de</strong>r <strong>el</strong> mecanismo<br />

que se nos proporciona.


28- Ciclo <strong>de</strong> Seminarios y Talleres d<strong>el</strong> Area <strong>de</strong> Programación.<br />

Parámetros y <strong>Argum<strong>en</strong>tos</strong> <strong>en</strong> <strong>el</strong> l<strong>en</strong>guaje <strong>de</strong> programación <strong>C++</strong>.<br />

El archivo stdarg.h conti<strong>en</strong>e macros que se pued<strong>en</strong> utilizar <strong>en</strong><br />

funciones <strong>de</strong>finidas por <strong>el</strong> usuario con número variable <strong>de</strong> parámetros.<br />

En <strong>C++</strong> hay otro método para proporcionar argum<strong>en</strong>tos a<br />

funciones que ti<strong>en</strong><strong>en</strong> listas <strong>de</strong> argum<strong>en</strong>tos <strong>en</strong> número variable. Este<br />

método facilita al compilador toda la información necesaria <strong>en</strong> una lista<br />

con un número variable <strong>de</strong> argum<strong>en</strong>tos, proporcionándole un conjunto <strong>de</strong><br />

variables preescritas que le indican cuántos argum<strong>en</strong>tos conti<strong>en</strong>e la lista y<br />

qué tipo <strong>de</strong> datos son.<br />

Las macros que se pued<strong>en</strong> utilizar para este propósito están<br />

<strong>de</strong>finidas <strong>en</strong> un archivo <strong>de</strong> cabecera d<strong>en</strong>ominado stdarg.h y<br />

son va_start(), va_arg() y va_<strong>en</strong>d().<br />

Las macros d<strong>el</strong> archivo stdarg.h ti<strong>en</strong><strong>en</strong> dos características útiles:<br />

- Han sido escritas para uso d<strong>el</strong> programador y son bastantes versátiles,<br />

<strong>de</strong> modo que se pued<strong>en</strong> utilizar <strong>de</strong> diversas formas.<br />

- Las macros proporcionan un medio transportables para pasar<br />

argum<strong>en</strong>tos variables. Esto se <strong>de</strong>be a que están disponibles dos versiones<br />

<strong>de</strong> macros: las <strong>de</strong>finidas <strong>en</strong> stdarg.h, que sigu<strong>en</strong> <strong>el</strong> standard ANSI C, y<br />

las <strong>de</strong>finidas <strong>en</strong> varargs.h, que son compatibles con UNIXSystem V.<br />

La macro va_list es un tipo <strong>de</strong> dato que es equival<strong>en</strong>te a una lista<br />

<strong>de</strong> variables. Una vez que se <strong>de</strong>fine una variable va_list, se pue<strong>de</strong> utilizar<br />

como un parámetro <strong>de</strong> las macros va_start()y va_<strong>en</strong>d().<br />

La sintaxis <strong>de</strong> la macro va_start() es: void va_start(va_list<br />

arg_ptr, prev_param); arg_ptr apunta al primer argum<strong>en</strong>to opcional <strong>en</strong><br />

una lista variable <strong>de</strong> argum<strong>en</strong>tos pasados a una función. Si la lista <strong>de</strong><br />

argum<strong>en</strong>tos <strong>de</strong> una función conti<strong>en</strong>e parámetros que se han especificado<br />

<strong>en</strong> la <strong>de</strong>claración <strong>de</strong> la función, <strong>el</strong> argum<strong>en</strong>to prev_param <strong>de</strong> va_start()<br />

proporciona <strong>el</strong> nombre d<strong>el</strong> argum<strong>en</strong>to especificado <strong>de</strong> la función que<br />

prece<strong>de</strong> inmediatam<strong>en</strong>te al primer argum<strong>en</strong>to opcional <strong>de</strong> la lista <strong>de</strong><br />

argum<strong>en</strong>tos.


UTN, FRT, Departam<strong>en</strong>to <strong>de</strong> Sistemas <strong>de</strong> Información- 29<br />

Ing. Ubaldo José Bonaparte<br />

Cuando la macro va_start() se ejecuta, hace que <strong>el</strong> parámetro<br />

arg_ptr apunte al argum<strong>en</strong>to especificado por prev_param.<br />

La sintaxis <strong>de</strong> la macro va_arg() es: void va_arg(va_list<br />

arg_ptr,tipo);<br />

La macro va_arg() ti<strong>en</strong>e un propósito doble:<br />

- Primero, va_arg() <strong>de</strong>vu<strong>el</strong>ve <strong>el</strong> valor d<strong>el</strong> objeto apuntado por <strong>el</strong><br />

argum<strong>en</strong>to arg_ptr.<br />

- Segundo, va_arg() increm<strong>en</strong>ta arg_ptr para apuntar al sigui<strong>en</strong>te<br />

<strong>el</strong>em<strong>en</strong>to <strong>de</strong> la lista variable <strong>de</strong> argum<strong>en</strong>tos <strong>de</strong> la función que se está<br />

llamando, utilizando <strong>el</strong> tamaño tipo para <strong>de</strong>terminar dón<strong>de</strong> comi<strong>en</strong>za <strong>el</strong><br />

sigui<strong>en</strong>te argum<strong>en</strong>to.<br />

La sintaxis <strong>de</strong> la macro va_<strong>en</strong>d() es: void va_<strong>en</strong>d(va_list<br />

arg_ptr);<br />

La macro va_<strong>en</strong>d() realiza las tareas auxiliares que son necesarias<br />

para que la función llamada retorne correctam<strong>en</strong>te. Cuando todos los<br />

argum<strong>en</strong>tos se le<strong>en</strong>, va_<strong>en</strong>d() reinicializa arg_ptr a NULL.<br />

El pseudocódigo d<strong>el</strong> proceso para manejar la lista variable <strong>de</strong><br />

argum<strong>en</strong>tos sería:<br />

tipo funcionVariable(last , ...) {<br />

va_list pa;<br />

tipo_X argum<strong>en</strong>to_<strong>de</strong>_tipo_X;<br />

va_start(pa,last);<br />

while (quedan<strong>Argum<strong>en</strong>tos</strong>)<br />

argum<strong>en</strong>to_<strong>de</strong>_tipo_X = va_arg(pa, tipo_X);<br />

va_<strong>en</strong>d(pa);<br />

}<br />

El ord<strong>en</strong> es innegociable. Debe <strong>de</strong>finirse <strong>el</strong> puntero <strong>de</strong> tipo va_list<br />

que se <strong>de</strong>be inicializar con va_start para po<strong>de</strong>r com<strong>en</strong>zar a trabajar.


30- Ciclo <strong>de</strong> Seminarios y Talleres d<strong>el</strong> Area <strong>de</strong> Programación.<br />

Parámetros y <strong>Argum<strong>en</strong>tos</strong> <strong>en</strong> <strong>el</strong> l<strong>en</strong>guaje <strong>de</strong> programación <strong>C++</strong>.<br />

Mi<strong>en</strong>tras haya argum<strong>en</strong>tos, hay que obt<strong>en</strong>erlos con va_arg y para<br />

terminar, hay que llamar siempre a va_<strong>en</strong>d.<br />

Hay que prestar at<strong>en</strong>ción a unos <strong>de</strong>talles cuando usemos este tipo <strong>de</strong><br />

construcciones.<br />

1. La lista variable siempre va al final <strong>de</strong> los argum<strong>en</strong>tos.<br />

2. Ti<strong>en</strong>e que haber al m<strong>en</strong>os un argum<strong>en</strong>to <strong>de</strong>finido (last), para<br />

po<strong>de</strong>r t<strong>en</strong>er una refer<strong>en</strong>cia y acce<strong>de</strong>r al resto <strong>de</strong> argum<strong>en</strong>tos.<br />

3. Dado que la dirección <strong>de</strong> last es utilizada por va_start no <strong>de</strong>be ser<br />

ni una variable register, ni una función, ni un array.<br />

4. Si no hay próximo argum<strong>en</strong>to, o si tipo no es compatible con <strong>el</strong><br />

tipo d<strong>el</strong> próximo argum<strong>en</strong>to, se producirán errores impre<strong>de</strong>cibles<br />

al llamar a va_arg.<br />

5. Cuidado con los tipos. T<strong>en</strong>gan <strong>en</strong> cu<strong>en</strong>ta que por <strong>de</strong>fecto C hace<br />

promoción <strong>de</strong> los parámetros pasados, así, si pasan un float, este<br />

será promovido a double y la s<strong>en</strong>t<strong>en</strong>cia va_arg(pa,float) será<br />

incorrecta. Lo mismo con shorts, etc. Normalm<strong>en</strong>te <strong>el</strong> compilador<br />

nos avisará <strong>de</strong> esto.<br />

6. Las macros nos ayudan a trabajar <strong>de</strong> modo portable. No importa,<br />

por ejemplo, que un int t<strong>en</strong>ga 32 o 16 bits. Las macros y <strong>el</strong><br />

compilador se <strong>en</strong>cargan <strong>de</strong> resolver la difer<strong>en</strong>cia. Nosotros sólo<br />

vemos una lista <strong>de</strong> variables <strong>de</strong> distintos tipos.<br />

Como controlar <strong>el</strong> número <strong>de</strong> argum<strong>en</strong>tos<br />

Controlar <strong>el</strong> número <strong>de</strong> argum<strong>en</strong>tos es importante para evitar<br />

errores. Pongamos como ejemplo algo muy habitual cuando se nos<br />

escapa un <strong>de</strong>talle: equivocarnos <strong>en</strong> un printf. Si escribimos lo sigui<strong>en</strong>te:<br />

printf("%d %d %d\n", 3, 4, 5, 6);<br />

printf("%d %d %d\n", 3, 4); // error 3 imág<strong>en</strong>es para 2 datos<br />

obt<strong>en</strong>dremos la salida, don<strong>de</strong> <strong>el</strong> último número pue<strong>de</strong> variar <strong>de</strong> una<br />

sistema operativo a otro.<br />

3 4 5<br />

3 4 134513729


UTN, FRT, Departam<strong>en</strong>to <strong>de</strong> Sistemas <strong>de</strong> Información- 31<br />

Ing. Ubaldo José Bonaparte<br />

Pasarse <strong>en</strong> <strong>el</strong> número <strong>de</strong> argum<strong>en</strong>tos no parece muy problemático,<br />

sin embargo, quedarse corto provoca resultados extraños. El compilador<br />

está buscando un <strong>en</strong>tero pero <strong>en</strong>cu<strong>en</strong>tra memoria sin inicializar (basura)<br />

que <strong>en</strong> este caso particular equivale a un 134513729, si se interpreta<br />

como un <strong>en</strong>tero.<br />

Hay que t<strong>en</strong>er mucho cuidado. En este s<strong>en</strong>cillo ejemplo, t<strong>en</strong>emos<br />

un problema visual, que no parece muy grave. ¿Y si <strong>el</strong> argum<strong>en</strong>to fuese<br />

un puntero? los efectos colaterales podrían ser terribles, podríamos t<strong>en</strong>er<br />

un error <strong>de</strong> segm<strong>en</strong>to o uno <strong>de</strong> esos bugs casi imposibles <strong>de</strong> <strong>de</strong>purar.<br />

De todos modos, parece que stdarg.h nos ofrece un mecanismo un<br />

poco escaso. Sería mejor disponer <strong>de</strong> algo similar a los argum<strong>en</strong>tos <strong>de</strong><br />

línea <strong>de</strong> comandos <strong>en</strong> main(int argc y char* argv[]), o al m<strong>en</strong>os t<strong>en</strong>er una<br />

macro va_count, o similar, que nos exprese cuántos argum<strong>en</strong>tos t<strong>en</strong>emos.<br />

Por <strong>de</strong>sgracia no es así y t<strong>en</strong>emos que usar otra aproximación don<strong>de</strong>,<br />

como programadores, t<strong>en</strong>emos que hacer explícito <strong>el</strong> número <strong>de</strong> los<br />

mismos.<br />

En g<strong>en</strong>eral, hay dos modos <strong>de</strong> hacerlo:<br />

1. Con un contador... uno <strong>de</strong> los argum<strong>en</strong>tos fijos es un <strong>en</strong>tero que<br />

indica <strong>el</strong> número <strong>de</strong> argum<strong>en</strong>tos variables que <strong>de</strong>bemos esperar.<br />

No permite indicar <strong>el</strong> tipo <strong>de</strong> los argum<strong>en</strong>tos a m<strong>en</strong>os que usemos<br />

un artificio adicional (como indicarlos con constantes<br />

simbólicas). Su<strong>el</strong>e usarse con funciones que recib<strong>en</strong> argum<strong>en</strong>tos<br />

<strong>de</strong> un tipo concreto.<br />

2. Con una cad<strong>en</strong>a <strong>de</strong> formateo... <strong>el</strong> estilo que usa la familia <strong>de</strong><br />

funciones printf y scanf. La función recibe un argum<strong>en</strong>to que<br />

indica <strong>de</strong> alguna manera la cantidad <strong>de</strong> argum<strong>en</strong>tos variables<br />

esperados y <strong>el</strong> tipo <strong>de</strong> los mismos.<br />

Ejemplo Nº 1:<br />

#inclu<strong>de</strong> <br />

#inclu<strong>de</strong> <br />

int suma_<strong>en</strong>teros(int primero,...);


32- Ciclo <strong>de</strong> Seminarios y Talleres d<strong>el</strong> Area <strong>de</strong> Programación.<br />

Parámetros y <strong>Argum<strong>en</strong>tos</strong> <strong>en</strong> <strong>el</strong> l<strong>en</strong>guaje <strong>de</strong> programación <strong>C++</strong>.<br />

void main(){<br />

cout


UTN, FRT, Departam<strong>en</strong>to <strong>de</strong> Sistemas <strong>de</strong> Información- 33<br />

Ing. Ubaldo José Bonaparte<br />

}<br />

return resultado;<br />

void pprintf(char *formato, ...) {<br />

char *p;<br />

va_list pa;<br />

va_start(pa, formato);<br />

for (p = formato; *p; p++) {<br />

if (*p != '?') {<br />

putchar (*p);<br />

continue;<br />

}<br />

switch (*++p) {<br />

case 'd':<br />

printf("{%d}", va_arg(pa, int));<br />

break;<br />

case 's':<br />

printf("{%s}", va_arg(pa, char *));<br />

break;<br />

<strong>de</strong>fault:<br />

putchar(*p);<br />

break;<br />

}<br />

}<br />

va_<strong>en</strong>d(pa);<br />

}<br />

int main (void) {<br />

printf("Resultado es %g\n", suma_reales(3, 0.3,0.1, 0.2));<br />

pprintf("Probemos a poner llaves a una ?s y a un ?d \n", "cad<strong>en</strong>a", 25);<br />

return 0;<br />

}<br />

La función suma_reales() muy similar a la función<br />

suma_<strong>en</strong>teros() d<strong>el</strong> ejemplo anterior, recibe como parámetros un <strong>en</strong>tero<br />

que indica la cantidad <strong>de</strong> argum<strong>en</strong>tos variables a buscar <strong>en</strong> la pila y una<br />

lista <strong>de</strong> argum<strong>en</strong>tos variables <strong>de</strong> tipos double.


34- Ciclo <strong>de</strong> Seminarios y Talleres d<strong>el</strong> Area <strong>de</strong> Programación.<br />

Parámetros y <strong>Argum<strong>en</strong>tos</strong> <strong>en</strong> <strong>el</strong> l<strong>en</strong>guaje <strong>de</strong> programación <strong>C++</strong>.<br />

La función pprintf() que recibe un puntero a una cad<strong>en</strong>a como<br />

parámetro (formato), don<strong>de</strong> pa <strong>de</strong> tipo va_list apuntará al primer carácter<br />

<strong>de</strong> la misma (“P”) y una lista variable <strong>de</strong> argum<strong>en</strong>tos a <strong>en</strong>contrar con<br />

va_arg(pa, tipo).<br />

Se produce la salida <strong>de</strong> caracteres hasta <strong>en</strong>contrar <strong>el</strong> carácter ?, <strong>el</strong><br />

cual seguido <strong>de</strong> una d establece que se busque <strong>el</strong> sigui<strong>en</strong>te argum<strong>en</strong>to <strong>de</strong><br />

tipo <strong>en</strong>tero y seguido <strong>de</strong> una s un argum<strong>en</strong>to <strong>de</strong> tipo cad<strong>en</strong>a, que nos<br />

<strong>de</strong>vu<strong>el</strong>ve va_arg() y se imprim<strong>en</strong>.


UTN, FRT, Departam<strong>en</strong>to <strong>de</strong> Sistemas <strong>de</strong> Información- 35<br />

Ing. Ubaldo José Bonaparte<br />

Conclusiones:<br />

Los parámetros juegan un pap<strong>el</strong> <strong>de</strong>masiado importante <strong>en</strong> los<br />

<strong>de</strong>sarrollos, don<strong>de</strong> <strong>el</strong> programador haci<strong>en</strong>do <strong>el</strong> uso a<strong>de</strong>cuado <strong>de</strong> los<br />

mismos, alim<strong>en</strong>tará <strong>el</strong> bu<strong>en</strong> hábito <strong>de</strong> controlar exhaustivam<strong>en</strong>te la<br />

persist<strong>en</strong>cia y manipulación <strong>de</strong> sus variables u objetos y como<br />

consecu<strong>en</strong>cia mant<strong>en</strong>drá distancia <strong>de</strong> los efectos colaterales.<br />

En la actualidad, la programación con l<strong>en</strong>guajes como Java, J#,<br />

.Net, C# y otros, continua sobre la base <strong>de</strong> los conceptos expuestos. De<br />

modo tal que recom<strong>en</strong>damos este artículo, especialm<strong>en</strong>te a principiantes<br />

que <strong>de</strong>se<strong>en</strong> manejar cuidadosam<strong>en</strong>te los parámetros y argum<strong>en</strong>tos.<br />

Bibliografía principal:<br />

- El L<strong>en</strong>guaje <strong>de</strong> Programación C, Brian W. Kernighan y D<strong>en</strong>nis M.<br />

Ritchie.<br />

- El <strong>C++</strong> L<strong>en</strong>guaje <strong>de</strong> Programación, Bjarne Stroustrup.<br />

- Programación y resolución <strong>de</strong> problemas <strong>en</strong> <strong>C++</strong>, N<strong>el</strong>l Dale y Chip<br />

Weems

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!