Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Juan Sanchez en 9 Abril 2020, 03:37 am



Título: Funciones por referencia
Publicado por: Juan Sanchez en 9 Abril 2020, 03:37 am
Saludos, Soy casi nuevo en este lenguaje y tengo ganas de profundizar el lenguaje.
Quiero hacer una función con dos parámetros el primero por valor y el segundo por referencia, en el primer parámetro quiero recibir texto que la función devuelva. como un ejemplo quiero resaltar la funcion de windows
Código
  1. Private Declare Function GetComputerName Lib "kernel32" Alias "GetComputerNameA" (ByVal lpBuffer As String, ByRef nSize As Long) As Long
Es similar el resultado que quiero obtener, lo cual en su primer parámetro obtengo el nombre del equipo y el segundo le paso el tamaño de caracteres que debe de rellenar.
La función que intento hacer es de esta manera, por favor les agradezco de antemano como lo puedo hacer?.
Código
  1. int NombreFuncion(char* Dato, int &BufferDato) {
  2. char* texto = "resultado";
  3. Dato = texto;//BufferDato para ver la cantidad de caracteres para el texto
  4. return 1;
  5. }
Imagino que se debe manejar punteros lo cual tengo varias dudas sobre el manejo de punteros.


Título: Re: Funciones por referencia
Publicado por: Loretz en 9 Abril 2020, 05:11 am
Puedes hacer algo como esto, pero ten en cuenta que en C++ no debes usar punteros, no debes usar new (ni delete).

Código:
#include <iostream> // para cout
#include <cstring>  // para strncpy

int NombreFuncion(char* Dato, size_t &BufferDato) {
const char* texto = "resultado";
if (BufferDato < strlen(texto)+1) {
BufferDato = strlen(texto) +1;
return 0; // texto es más largo que BufferDato
}
strncpy(Dato, texto, BufferDato);
Dato[BufferDato-1] = '\0';
return 1;
}

int main()
{
size_t size = 1;
char* dato = new char[size];

if (NombreFuncion(dato, size))
std::cout << "dato = " << dato << '\n';
else
std::cout << "dato debe ser al menos de " << size << " bytes\n";

delete[] dato;
}



Título: Re: Funciones por referencia
Publicado por: ThunderCls en 9 Abril 2020, 16:10 pm
Puedes hacer algo como esto, pero ten en cuenta que en C++ no debes usar punteros, no debes usar new (ni delete).

En C++ no se deben usar punteros?, ni new ni delete? Podrias dar algunos de tus motivos para este razonamiento?

Saludos, Soy casi nuevo en este lenguaje y tengo ganas de profundizar el lenguaje.

Mi consejos si lo que te interesa es aprender C++:
- Separa conceptos de C y C++
- Aprende el lenguaje puro, de ser posible versiones modernas (17+)
- Usa la libreria estandar de C++
- Evita siempre que puedas el manejo de arreglos de chars para las cadenas, en C++ tienes std::string la cual es mucho mas segura y facil de usar

Código
  1. #include <iostream>
  2.  
  3. void NombreFuncion(string &str);
  4.  
  5. int main()
  6. {
  7.    std::string dato;
  8.    NombreFuncion(dato);
  9.    cout << dato << endl;
  10. }
  11.  
  12. void NombreFuncion(std::string &dato)
  13. {
  14.    const std::string texto = "resultado";
  15.    dato.assign(texto);
  16. }

Suerte


Título: Re: Funciones por referencia
Publicado por: Juan Sanchez en 9 Abril 2020, 18:41 pm
Puedes hacer algo como esto, pero ten en cuenta que en C++ no debes usar punteros, no debes usar new (ni delete).

Código:
#include <iostream> // para cout
#include <cstring>  // para strncpy

int NombreFuncion(char* Dato, size_t &BufferDato) {
const char* texto = "resultado";
if (BufferDato < strlen(texto)+1) {
BufferDato = strlen(texto) +1;
return 0; // texto es más largo que BufferDato
}
strncpy(Dato, texto, BufferDato);
Dato[BufferDato-1] = '\0';
return 1;
}

int main()
{
size_t size = 1;
char* dato = new char[size];

if (NombreFuncion(dato, size))
std::cout << "dato = " << dato << '\n';
else
std::cout << "dato debe ser al menos de " << size << " bytes\n";

delete[] dato;
}
Gracias Loretz, hice correr el código en dev c++ y todo ok, y tambien probé en el IDE de visual studio 2015 y me salta el error al compilar en la siguiente linea
Código
  1. ...
  2. strncpy(Dato, texto, BufferDato);
  3. ...
El error que se muestra es lo siguiente
Código
  1. Error C4996 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
Generalmente yo uso el IDE de visual studio 2015, alguna librería debo incluir?
tambien probé con strncpy_s y nada me dice ninguna sobrecarga coincide para la función.

Una vez mas gracias por tu respuesta estimado:


Título: Re: Funciones por referencia
Publicado por: RayR en 9 Abril 2020, 20:33 pm
Lo de las funciones ya te lo respondieron, pero me parece necesario aclarar un punto. Y es que, si algún día te interesa meterte a nivel profesional a C++, los punteros son indispensables.

Es una pena que muchos autores se empeñen en meter a los estudiantes el miedo al manejo de memoria. Entiendo que quizás sea para que no se compliquen, pero me parece que hacen más daño que beneficio. Otra cosa sería si dijeran que no conviene usarlos sino hasta que uno tiene más experiencia, pero la mayoría de esos autores se limita a recomendar que nunca se usen, como como si a nivel profesional tampoco fueran muy necesarios, cosa que no podría estar más alejada de la realidad. Cualquiera que lleve un tiempo programando profesionalmente en este lenguaje se reirá ante la idea, y te dirá que la situación es totalmente la opuesta. Y es que es tan obvio y tan cierto como que 2+2=4 para cualquiera que esté metido en el tema, que no sé cómo esos autores pueden seguir publicando. De hecho, y por suerte, cualquier lector de estos libros que se llegue a dedicar profesionalmente a C++, se dará cuenta de lo importantes y útiles que son esos temas cuando llegue a la industria. El problema son los muchos estudiantes que luego se se pasarán a otros lenguajes, llevándose la idea de que esos temas, y la optimización en general, ya no importan porque las computadoras son "suficientemente rápidas". Y llegan al ámbito laboral sin saber hacer nada si no hay una biblioteca o framework que les dé todo masticadito, y de ahí la baja calidad y rendimiento de gran parte del software actual (pues en el mundo de Java, C# y, sobre todo, la programación web, estos temas les suelen interesar muy poco). Enseñarles a manejar correctamente la memoria a su debido tiempo, en lugar de crear un miedo irracional y ridículo, les daría habilidades muy importantes que después podrían aplicar aún en otros lenguajes.

C++ sin manejo de memoria no tiene prácticamente razón de ser. A la fecha, yo tengo casi 17 años de experiencia profesional (la mayoría de ellos programando en C++) y he conocido bastantes programadores del mundillo, y jamás he sabido de alguien que no use punteros en sus proyectos, incluyéndome. Seguro que alguno habrá, pero es rarísimo. Más aún, no conozco un sólo profesional de C++ que no considere el hecho de que este lenguaje permita usar punteros y acceder más o menos directamente a la memoria, como una de las mayores ventajas de programar en él. Salvo pocas excepciones, si no necesitamos manejar la memoria, no necesitamos (ni deberíamos usar) C++. Hoy ya casi ninguna aplicación "simple" (punto de venta, almacén, contabilidad, etc.) se hace en C++, y por buena razón. Hay lenguajes mucho más simples, productivos, y en general, más adecuados, como C#. C++ ha ido quedando relegado a proyectos donde se trabaje de cerca al hardware o donde se requieran grandes optimizaciones, y, obviamente, desde hace dos décadas no se pueden hacer optimizaciones significativas —salvo las más triviales— sin manejar manualmente la memoria. Es imposible. De hecho, según los requerimientos que se tengan, los propios new y delete (y malloc y free) predeterminados pueden ser de demasiado alto nivel para usarse. Por eso tampoco es raro que en su lugar se usen allocators propios y llamadas a las funciones nativas del sistema operativo para implementar un sistema personalizado de manejo de memoria. Porque tener un control preciso de cuándo y cómo se reserva y libera suele dar muchos beneficios. Según el caso, es perfectamente posible hacer que código crítico se ejecute 2, 3, 5 veces más rápido sin cambiar absolutamente nada del código, salvo las funciones de manejo de memoria. Y no es que estas cosas sólo se hagan en proyectos grandísimos de la NASA o similares. En la industria del videojuego, por ejemplo, esto es muy común, tanto en PC como consolas.

Resumiendo: al estar empezando, sí conviene mantenerte alejado de punteros y acceso "directo" a la memoria. Y si sólo te interesa programar como pasatiempo es perfectamente válido seguir así. Pero debes saber que, si tienes el interés de alguna vez dedicarte profesionalmente a programar en C++, manejarte con soltura en estos temas es indispensable. Estimaría que más o menos por cada 20 empleos de C++ donde vas a necesitar aplicar estos conocimientos, habrá con suerte uno donde no sea así. Y, si ya de por sí, hoy en día no hay tantos empleos en C++, pues, imagínate...

Si te interesa profundizar, además de libros, en youtube hay muchos videos de conferencias de C++. Muchas de ellas son dadas por personas que principalmente se dedican a escribir libros, dar charlas y "consultorías", por lo que, aunque suelen ser bastante correctas en cuanto a describir cómo funcionan las cosas (y con ese fin las recomiendo), yo me tormaría con muuuchas reservas sus consejos sobre buenos usos y prácticas. Para eso, limitarse a programadores de verdad, que programan día a día, y simplemente, en ocasiones dan charlas. Mike Acton es un buen ejemplo, aunque sus temas son más dirigidos a gente con nivel ya intermedio al menos.


Título: Re: Funciones por referencia
Publicado por: Juan Sanchez en 9 Abril 2020, 21:09 pm
Primero agradecer a Loretz por su código y a los que administran el foro, por responderme en un tiempo muy corto y por los conceptos que me dan.
Se que el lenguaje c++ es un poco complicado cuando uno comienza aun sabiendo otros lenguajes de alto nivel, yo vengo de esos lenguajes de alto nivel, por eso tengo esa curiosidad de profundizar en cuanto a programación, por eso un rato me parece complicado el lenguaje, en ese sentido acudí a este foro y lo cual seguiré haciendo consultas mas adelante.
Gracias por ayudarme Saludos.