Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - Loretz

#71
RayR; hay una falta de ortografía en tu ejemplo:

Cita de: RayR en  2 Mayo 2019, 19:42 PM
int **matriz = new int*[10];
for(int i = 0; i < 10; i++)
    matriz[i] = new int[10];


debería ser:
int** matriz = new int* [10];
    for (int i = 0; i < 10; i++)
        matriz[i] = new int; // sin el [10]


Amplío un poco el ejemplo que muestra un ciclo completo:

#include <iostream>

int main()
{
    // puntero a un array de 10 punteros a int
    int** matriz = new int* [10];
    for (int i = 0; i < 10; i++)
        matriz[i] = new int{i};  // cada uno de esos 10 punteros con valores inicializados con el indice i.

    // a ver...
    for (int i = 0; i < 10; ++i)
        std::cout << *matriz[i] << '\n';
    std::cout << '\n';

    // deletes:
    for (int i = 0; i < 10; ++i)
        delete[] matriz[i];
    delete[] matriz;
   
}

#72
Aprovechando que este es un tema un poco recurrente, creo que este programita puede ayudar a aclarar un poco dónde están las cosas. Puedes convertir las salidas en hexadecimal a decimal si te resulta más cómodo (calculadora de Windows o la que te guste) y ver que los punteros están realmente lejos unos de otros.

Código (cpp) [Seleccionar]
#include <iostream>

int main()
{
    const char* puntero_probablemente_a_zona_de_solo_lectura = "hola";  // segmento "data" en el ejecutable
    std::cout << "apunta al string literal: \"" << puntero_probablemente_a_zona_de_solo_lectura << "\"\n";
    std::cout << "su direccion es: "
        << (void*)puntero_probablemente_a_zona_de_solo_lectura << "\n\n";

    const char* puntero_a_heap = new char[6] { "adios" };  // asignación "dinámica" en heap, usa new / delete
    std::cout << "apunta a la C string en heap: \"" << puntero_a_heap << "\"\n";
    std::cout << "su direccion es: "
        << (void*)puntero_a_heap << "\n\n";
    delete[] puntero_a_heap;

    char ch = 'a';
    const char* puntero_a_stack = &ch;  // en el stack frame de main
    std::cout << "apunta al char en stack: \'" << *puntero_a_stack << "\'\n";
    std::cout << "su direccion es: "
        << (void*)puntero_a_stack << "\n\n";

}


#73
Tú dices:
CitarMás adelante dice:
"La declaración static, aplicada a una variable o función externa, ...

En esta porción de tu pregunta encuentro dos problemas:

1.- Un error del traductor:
Donde dice:
CitarLa declaración static, aplicada a una variable o función externa, ... "
El original dice:
Citar"The static declaration, applied to an external variable or function, ...."

El problema aquí es que las variables pueden ser "externas" (en el sentido de que no están definidas en el cuerpo de una función sino fuera), pero no las funciones. Quizá pudo haberse traducido por:
La declaración static, aplicada a una variable externa o a una función, ..."

Este punto no hace a la cuestión, pero me pareció que valía la pena aclararlo. El otro problema que encuentro es:

2.- Un descuido tuyo:
Comienzas diciendo
Citar"Más adelante dice: ..."

El problema aquí es que esa frase que citas está incompleta, la primera parte es importante a la idea esta de nombres de cosas "visibles" u "ocultas" para quién y desde dónde.

La frase de la versión en inglés que veo ahora comienza diciendo
Citar"The variables sp and val in stack.c , and buf and bufp in getch.c , are for the private
use of the functions in their respective source files, and are not meant to be accessed by
anything else."

Que aunque no tengo tu traducción, supongo que debe estar de alguna manera. Mal, bien o más o menos, como siempre, pero algo debe decir ¿verdad?. Supongo que si lees esa primera parte te podrás formar una mejor idea sobre a qué se refieren los autores con "visible" o "no visible" en este contexto.


#74
Citar¿Qué significa "ocultar nombres" y que "no son visibles"?

En general creo que conviene tener algún cuidado y no olvidar que lo que se está leyendo es una traducción; así que al estilo de los autores, no siempre la mejor prosa posible, naturalmente, también hay que añadir la buena o mala suerte del traductor.

Yo entiendo que en la frase que citas, la relación es:
Las variables no son visibles (a los meros usuarios de getch y de ungetch) porque tienen sus nombres ocultos (gracias a que han sido declaradas "static").

El problema que veo en el ejemplo es que ni buf ni bufp están declaradas "static", lo que no ayuda mucho al entendimiento. Pero si pones:

#include <stdio.h>
#define BUFSIZE 100

static char buf[BUFSIZE];  ///< ahora buf esta declarada "static"
static int bufp = 0;       ///< bufp tambien.            
itn getch(void) {
  ...
}

void ungetch(int) {
  ...
}


Pero... aunque las variables no fueran declaradas "static", de todos modos sus nombres tampoco serían "visibles" fuera del archivo getch.c, a no ser que se las declare como "extern" en un header, por ejemplo.

Como ves, la cosa no es muy lineal, ahora además de "static" apareció "extern". Bueno, creo que hubiera convenido presentar antes la declaración "extern", que hace que se puedan compartir variables entre archivos. ¿Me disculpas? Te lo dejo a ti.

De todos modos, la idea es que:
Al declarar las variables globales como "static", se está prohibiendo su acceso desde otros archivos (se ocultan sus nombres, ya no serán visibles desde otros archivos, incluso aunque algún pícaro o descuidado las declare "extern")

[Nota]
- Pero, ¿a quién se le ocultan esos nombres, si yo los estoy viendo y supongo que tú también?
- Al compilador hombre, ni a tí ni a mí, al compilador.
[/Nota]
#75
CitarY al parecer, char * es una excepción a la regla, es lo único que implícitamente solicita memoria dinámica ...

No, no se trata de una excepción, lo que sucede es que las expresiones como "data.db" son de tipo "string literal", que tienen"static storage duration" [https://en.cppreference.com/w/c/language/static_storage_duration], por lo que existen durante toda la vida del programa y se inicializan antes de main().

Por ejemplo, el tipo de "data.db" es const char[8] (los 7 caracteres visibles más el 0 del final). Como los arrays decaen en punteros, es también natural escribir:
const char* file_name = "data.db";
Entonces, file_name es un puntero a carácter que apunta a la primera 'd' del array, se le asigna esa dirección de memoria, que ya existe, por eso es que no es necesario crearla.

Otra cosa; al declarar las variables "static", si vas a poner tu UTools en un .h, estarás haciendo que cada unidad donde se incluya (cada .cpp) tenga su propia copia de todas esas variables. En este caso son todas const char* y nadie las va a modificar, pero de todos modos creo que conviene tenerlo en cuenta.

#76
CitarBajo que circunstancias se puede usar puntero a función y método miembro?

En C++ hay funciones pero no "métodos", algunas veces se dice así por costumbre adquirida en otros lenguajes, pero en C++ sólo hay funciones, algunas serán "member functions" y otras no, pero no hay más.

Y francamente no tengo una respuesta de esas iluminadoras, pero creo que en general se usa un puntero a función miembro más o menos de la manera en que se usa un puntero a función.

Como has estado viendo, QT Creator implementa sus event handlers usando punteros a funciones miembro.

Muchas veces puede usarse otro mecanismo para conseguir el mismo resultado, comúnmente apelando a las funciones virtuales.

También, en la biblioteca estándar están std::function que puede inicializarse con una función miembro, y está std::bind, que devuelve un function object que puede invocar una función (miembro o no), con sus parámetros de llamada asociados.

Aunque no encuentro un ejemplo simple donde pueda mostrarse fácilmente un uso indiscutible, se puede ver su uso en la aplicación del "Open-close principle" https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle; por ejemplo, en "The Safe Bool Idiom": https://www.artima.com/cppsource/safebool2.html


#77
CitarEntonces las funciones también estarían ocupando un espacio en la memoria?

Los punteros a funciones sí, pero en tu caso no tienes un puntero a función sino un "puntero a función miembro", que es diferente.

Un puntero a función miembro no apunta a nada hasta que no se cree el objeto y se defina a qué función apuntará, y como es "implementation defined", dependerá del compilador si lo implementa como un puntero u otra cosa.

La sintaxis es un poco compleja; un ejemplo simple ya lo muestra:

Código (cpp) [Seleccionar]
#include <iostream>

class UnaClase {
public:
    void unMetodo()
    {
        std::cout << "UnaClase::unMetodo()\n";
    }
};

void unaFuncion(UnaClase* p, void(UnaClase::* pmf)())
{
    (p->*pmf)();  ///< recien aqui se define a que funcion de que objeto apunta el "puntero a funcion miembro" (pmf)
}

int main()
{
    UnaClase unaClase;
    unaFuncion(&unaClase, &UnaClase::unMetodo);  ///< debe invocarse con el objeto ademas del "puntero a funcion miembro";
                                                 ///< y si la funcion miembro toma parametros, tambien habra que pasarselos.
}


#78
Programación C/C++ / Re: Duda de sintaxis..
13 Abril 2019, 19:34 PM
No puedo decirte cómo son las reglas del C++/CLI, que ignoro olímpicamente, pero te comento para el C++ (sobreescribo tu ejemplo):

Código (cpp) [Seleccionar]
namespace Stuffs {
    class UnaCosa {
    public: ///< En C++ getTrue debe ser public para que pueda ser accedida desde fuera.
        static bool getTrue() /*const*/ {  ///< En C++ una funcion miembro static no puede tener calificador de tipo
            return true;
        }
    };
}

int main() {
    bool unaExpresion = Stuffs::UnaCosa::getTrue();

    //una instancia a UnaCosa
    Stuffs::UnaCosa unaCosa;
    unaCosa.getTrue();     //Esto deberia dar error verdad?
                           ///< En C++ es una expresion valida, equivalente a Stuffs::UnaCosa::getTrue();

    //puntero
    Stuffs::UnaCosa* p_unaCosa = new Stuffs::UnaCosa;
    p_unaCosa->getTrue();   //Esto tambien deberia dar error, si?
                            ///< En C++ es una expresion valida, equivalente a Stuffs::UnaCosa::getTrue();
}

#79
CitarLo que dijiste de la funcion print en el visual studio te da error al compilar o te compila sin problemas?
Me da error al compilar.
#80
Citarwait causes the current thread to block until the condition variable is notified or a spurious wakeup occurs,

https://en.cppreference.com/w/cpp/thread/condition_variable/wait