Hilo
Declaración e inicialización de punteros y typedef. (marcelinux) 2018-03-02 08:59:05
Después de completar el curso propuesto en esta web me he propuesto complementarlo con el libro de Bjarne Stroustrup, The C++ Programming language.
En el capítulo 5 se proponen unos ejercicios, que transcribo.
Me gustaría saber si los he realizado correctamente.
No se me ocurre cómo serían las dos últimas definiciones. Si alguien pudiera
explicarme cómo deberían ser, le estaría muy agradecido.
<code>
/* The C++ Programming language
* Ejercicios del capítulo 5.
*
* ej_01 Write declarations for the following:
* a pointer to a character,
* an array of 10 integers,
* a reference to an array of 10 integers,
* a pointer to an array of character strings,
* a pointer to a pointer to a character,
* a constant integer,
* a pointer to a constant integer
* and a constant pointer to an integer.
* Initialize each one.
*
* ej_03 Use typedef to define the types:
* unsigned char,
* const unsigned char,
* pointer to integer,
* pointer to pointer to char,
* pointer to arrays of char,
* array of 7 pointers to int,
* pointer to an array of 7 pointers to int
* and array of 8 arrays of 7 pointers to int.
*/
#include iostream
using namespace std;
void ej_01()
{
char c = 'M';
cout << "char c = " << c << '\n';
// a pointer to a character
char* pc = &c;
cout << "char* pc = " << pc << " apunta a c = " << *pc << '\n';
// an array of 10 integers
int arr_i[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 32};
cout << "arr_i[10] ... " << arr_i[0] << '\n';
// a reference to an array of 10 integers
int (&ref_i)[10] = arr_i;
cout << "ref_i = " << ref_i << " hace referencia a " << ref_i[0] << '\n';
// a pointer to an array of character strings
char* arr_c[] = {"primero",
"segundo",
"tercero"};
cout << "arr_c[] ... " << arr_c[0] << " .. o .. " << *arr_c << '\n';
// a pointer to a pointer to a character
char** ppc = arr_c;
cout << "ppc = " << ppc << " que apunta a " << *ppc << '\n';
// a constant integer
const int ci = 356;
cout << "ci = " << ci << '\n';
// a pointer to a constant integer
const int* pci = &ci;
cout << "pci = " << pci << " que apunta a " << *pci << '\n';
// a constant pointer to an integer
int ii = 88;
int *const icons = ⅈ
cout << "icons = " << icons << " que apunta a " << *icons << '\n';
}
void ej_03()
{
// unsigned char
typedef unsigned char uchar_t;
uchar_t uc = 179;
cout << "unsigned char 179 se representa con " << uc << '\n';
// const unsigned char
typedef const unsigned char cuchar_t;
cuchar_t cuc = 179;
cout << "const unsigned char 179 se representa con " << cuc << '\n';
//pointer to integer
typedef int* pint_t;
int i = 6;
pint_t pi = &i;
cout << "pointer to integer sobre i = 6 está en " << pi << " y contiene " << *pi << '\n';
//pointer to pointer to char
typedef char** ppchar_t;
char ch1 = 'c';
char* pch1 = &ch1;
ppchar_t ppch1 = &pch1;
cout << "pointer to pointer to char está en " << ppch1
<< " y contiene " << *ppch1
<< " que es, a su vez " << **ppch1 << '\n';
// pointer to arrays of char --->>> es equivalente a pointer to pointer to char
//array of 7 pointers to int
int i7_1, i7_2, i7_3, i7_4, i7_5, i7_6, i7_7;
i7_7 = i7_6 = i7_5 = i7_4 = i7_3 = i7_2 = i7_1 = 101;
typedef int* pint7_t;
pint7_t i7[7] = {&i7_1, &i7_2, &i7_3, &i7_4, &i7_5, &i7_6, &i7_7};
cout << "array of 7 pointers to int: " << i7[0] << " => " << *i7[0]
<< ", " << i7[1] << " => " << *i7[1]
<< ", " << i7[2] << " => " << *i7[2]
<< ", " << i7[3] << " => " << *i7[3]
<< ", " << i7[4] << " => " << *i7[4]
<< ", " << i7[5] << " => " << *i7[5]
<< ", " << i7[6] << " => " << *i7[6] << '\n';
//pointer to an array of 7 pointers to int
//array of 8 arrays of 7 pointers to int
}
int main()
{
ej_01();
ej_03();
return 0;
}
</code>
_______________________________________________
Lista de correo Cconclase Cconclase@listas.conclase.net
http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ
Re: Declaración e inicialización de punteros y typedef. (Steven Davidson) 2018-03-02 14:54:38
Hola Marcelinux,
1. Como ya sabes, sintácticamente un puntero se define con un astersico y
un array con una pareja de corchetes. El "problema" es que estos
declaradores siguen las reglas de los operadores. Esto implica que las
reglas de precedencia y de asociatividad siguen vigentes. Vemos que el
declarador [] tiene mayor precedencia que el declarador *.
Como queremos un puntero de arrays, debemos obligar que el declarador del
puntero se realice antes que el declarador de arrays. Para obligar usamos
paréntesis; esto es,
¿? (*ptr)[7];
Luego dice que el tipo de cada elemento del array es un puntero a 'int'.
Bien, pues ahora agregamos esta parte:
int * (*ptr)[7];
Cuando uno empieza a hacer este tipo de declaraciones complejas, aconsejo
usar 'typedef' para aclararnos; esto es,
typedef int * tipo_array_ptr[7];
tipo_array_ptr *ptr;
Esto es definitivamente mejor cuando queremos crear memoria dinámicamente
usando 'new' o 'new[]'; por ejemplo,
ptr = new tipo_array_ptr[100];
2. Esto no tiene mucho misterio. Solamente necesitas ir poco a poco:
array de 8 elementos:
¿? array[8];
cada elemento es un array de 7 elementos:
¿? array[8][7];
que a su vez cada elemento es un puntero a 'int':
int * array[8][7];
Espero haber aclarado las dudas.
Steven
On Fri, Mar 2, 2018 at 3:59 AM, marcelinux <marcelinator@gmail.com> wrote:
> Después de completar el curso propuesto en esta web me he propuesto
> complementarlo con el libro de Bjarne Stroustrup, The C++ Programming
> language.
> En el capítulo 5 se proponen unos ejercicios, que transcribo.
> Me gustaría saber si los he realizado correctamente.
> No se me ocurre cómo serían las dos últimas definiciones. Si alguien
> pudiera
> explicarme cómo deberían ser, le estaría muy agradecido.
> <code>
> /* The C++ Programming language
> * Ejercicios del capítulo 5.
> *
> * ej_01 Write declarations for the following:
> * a pointer to a character,
> * an array of 10 integers,
> * a reference to an array of 10 integers,
> * a pointer to an array of character strings,
> * a pointer to a pointer to a character,
> * a constant integer,
> * a pointer to a constant integer
> * and a constant pointer to an integer.
> * Initialize each one.
> *
> * ej_03 Use typedef to define the types:
> * unsigned char,
> * const unsigned char,
> * pointer to integer,
> * pointer to pointer to char,
> * pointer to arrays of char,
> * array of 7 pointers to int,
> * pointer to an array of 7 pointers to int
> * and array of 8 arrays of 7 pointers to int.
> */
>
> #include iostream
> using namespace std;
>
> void ej_01()
> {
> char c = 'M';
> cout << "char c = " << c << '\n';
>
> // a pointer to a character
> char* pc = &c;
> cout << "char* pc = " << pc << " apunta a c = " << *pc << '\n';
>
> // an array of 10 integers
> int arr_i[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 32};
> cout << "arr_i[10] ... " << arr_i[0] << '\n';
>
> // a reference to an array of 10 integers
> int (&ref_i)[10] = arr_i;
> cout << "ref_i = " << ref_i << " hace referencia a " << ref_i[0]
> << '\n';
>
> // a pointer to an array of character strings
> char* arr_c[] = {"primero",
> "segundo",
> "tercero"};
> cout << "arr_c[] ... " << arr_c[0] << " .. o .. " << *arr_c <<
> '\n';
>
> // a pointer to a pointer to a character
> char** ppc = arr_c;
> cout << "ppc = " << ppc << " que apunta a " << *ppc << '\n';
>
> // a constant integer
> const int ci = 356;
> cout << "ci = " << ci << '\n';
>
> // a pointer to a constant integer
> const int* pci = &ci;
> cout << "pci = " << pci << " que apunta a " << *pci << '\n';
>
> // a constant pointer to an integer
> int ii = 88;
> int *const icons = ⅈ
> cout << "icons = " << icons << " que apunta a " << *icons << '\n';
> }
>
> void ej_03()
> {
> // unsigned char
> typedef unsigned char uchar_t;
> uchar_t uc = 179;
> cout << "unsigned char 179 se representa con " << uc << '\n';
>
> // const unsigned char
> typedef const unsigned char cuchar_t;
> cuchar_t cuc = 179;
> cout << "const unsigned char 179 se representa con " << cuc <<
> '\n';
>
> //pointer to integer
> typedef int* pint_t;
> int i = 6;
> pint_t pi = &i;
> cout << "pointer to integer sobre i = 6 está en " << pi << " y
> contiene " << *pi << '\n';
>
> //pointer to pointer to char
> typedef char** ppchar_t;
> char ch1 = 'c';
> char* pch1 = &ch1;
> ppchar_t ppch1 = &pch1;
> cout << "pointer to pointer to char está en " << ppch1
> << " y contiene " << *ppch1
> << " que es, a su vez " << **ppch1 << '\n';
>
> // pointer to arrays of char --->>> es equivalente a pointer to
> pointer to char
>
> //array of 7 pointers to int
> int i7_1, i7_2, i7_3, i7_4, i7_5, i7_6, i7_7;
> i7_7 = i7_6 = i7_5 = i7_4 = i7_3 = i7_2 = i7_1 = 101;
> typedef int* pint7_t;
> pint7_t i7[7] = {&i7_1, &i7_2, &i7_3, &i7_4, &i7_5, &i7_6, &i7_7};
> cout << "array of 7 pointers to int: " << i7[0] << " => " << *i7[0]
> << ", " << i7[1] << " => " << *i7[1]
> << ", " << i7[2] << " => " << *i7[2]
> << ", " << i7[3] << " => " << *i7[3]
> << ", " << i7[4] << " => " << *i7[4]
> << ", " << i7[5] << " => " << *i7[5]
> << ", " << i7[6] << " => " << *i7[6] << '\n';
>
> //pointer to an array of 7 pointers to int
>
> //array of 8 arrays of 7 pointers to int
> }
>
> int main()
> {
> ej_01();
> ej_03();
> return 0;
> }
> </code>
_______________________________________________
Lista de correo Cconclase Cconclase@listas.conclase.net
http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ
Re: Declaración e inicialización de punteros y typedef. (marcelinux) 2018-03-03 07:32:37
El pasado 2018-03-02 14:54:38, Steven Davidson escribió:
SD> Hola Marcelinux,
SD> 1. Como ya sabes, sintácticamente un puntero se define con un astersico y
SD> ...
SD> usar 'typedef' para aclararnos; esto es,
SD> typedef int * tipo_array_ptr[7];
SD> tipo_array_ptr *ptr;
SD> Esto es definitivamente mejor cuando queremos crear memoria dinámicamente
SD> usando 'new' o 'new[]'; por ejemplo,
SD> ptr = new tipo_array_ptr[100];
De acuerdo. Entonces, ¿debo hacerlo en "dos veces"?
¿Podría hacerse con un único typedef *(int *)[7] tipo_array_ptr ?
¿Para usar tipo_array_ptr puntero?
puntero = new tipo_array_ptr;
puntero[0] = &entero[0];
Creo que es demasiado anidamiento para mí (de momento).
SD> 2. Esto no tiene mucho misterio. Solamente necesitas ir poco a poco:
SD> array de 8 elementos:
SD> ¿? array[8];
SD> cada elemento es un array de 7 elementos:
SD> ¿? array[8][7];
SD> que a su vez cada elemento es un puntero a 'int':
SD> int * array[8][7];
typedef int*array[8][7] tipo_array_ptr;
tipo_array_ptr puntero;
puntero[0] = array1;
puntero[1] = array2;
etc.
SD> Espero haber aclarado las dudas.
SD> Steven
Muchísimas gracias.
_______________________________________________
Lista de correo Cconclase Cconclase@listas.conclase.net
http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ
Re: Declaración e inicialización de punteros y typedef. (Steven Davidson) 2018-03-03 16:30:03
Hola Marcelinux,
Para el primer caso, sí podrías definir el tipo de dato completamente. Por
ejemplo,
typedef int * (*tipo_array_ptr_puntero)[7];
tipo_array_ptr_puntero ptr;
El problema vendría a la hora de usar el operador 'new' o 'new[]', ya que
necesitas el tipo del dato apuntado, y no el tipo del puntero. Es decir, lo
siguiente es incorrecto:
ptr = new tipo_array_ptr_puntero;
El operador 'new' necesita el tipo: 'int * [7]', que es el tipo del dato
apuntado.
Lo que podríamos hacer es crear dos tipos de datos en una sola sentencia
'typedef'. Por ejemplo,
typedef int * tipo_array_ptr[7], * tipo_array_ptr_puntero;
tipo_array_ptr_puntero ptr;
ptr = new tipo_array_ptr;
Para el último caso, tienes que separar las dos sentencias en dos
sentencias. En otras palabras, no puedes declarar una variable y definir un
tipo en una sola sentencia: son dos sentencias diferentes.
Espero haber aclarado las dudas.
Steven
2018-03-03 2:32 GMT-05:00 marcelinux <marcelinator@gmail.com>:
> El pasado 2018-03-02 14:54:38, Steven Davidson escribió:
>
> SD> Hola Marcelinux,
> SD> 1. Como ya sabes, sintácticamente un puntero se define con un
> astersico y
> SD> ...
> SD> usar 'typedef' para aclararnos; esto es,
> SD> typedef int * tipo_array_ptr[7];
> SD> tipo_array_ptr *ptr;
> SD> Esto es definitivamente mejor cuando queremos crear memoria
> dinámicamente
> SD> usando 'new' o 'new[]'; por ejemplo,
> SD> ptr = new tipo_array_ptr[100];
>
> De acuerdo. Entonces, ¿debo hacerlo en "dos veces"?
> ¿Podría hacerse con un único typedef *(int *)[7] tipo_array_ptr ?
> ¿Para usar tipo_array_ptr puntero?
> puntero = new tipo_array_ptr;
> puntero[0] = &entero[0];
> Creo que es demasiado anidamiento para mí (de momento).
>
> SD> 2. Esto no tiene mucho misterio. Solamente necesitas ir poco a poco:
> SD> array de 8 elementos:
> SD> ¿? array[8];
> SD> cada elemento es un array de 7 elementos:
> SD> ¿? array[8][7];
> SD> que a su vez cada elemento es un puntero a 'int':
> SD> int * array[8][7];
>
> typedef int*array[8][7] tipo_array_ptr;
> tipo_array_ptr puntero;
> puntero[0] = array1;
> puntero[1] = array2;
> etc.
>
>
> SD> Espero haber aclarado las dudas.
> SD> Steven
>
> Muchísimas gracias.
>
>
_______________________________________________
Lista de correo Cconclase Cconclase@listas.conclase.net
http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ
Re: Declaración e inicialización de punteros y typedef. (marcelinux) 2018-03-05 10:05:59
El pasado 2018-03-03 16:30:03, Steven Davidson escribió:
SD> Hola Marcelinux,
SD> Para el primer caso, sí podrías definir el tipo de dato completamente. Por
SD> ejemplo,
SD> typedef int * (*tipo_array_ptr_puntero)[7];
SD> tipo_array_ptr_puntero ptr;
SD> El problema vendría a la hora de usar el operador 'new' o 'new[]', ya que
SD> necesitas el tipo del dato apuntado, y no el tipo del puntero. Es decir, lo
SD> siguiente es incorrecto:
SD> ptr = new tipo_array_ptr_puntero;
SD> El operador 'new' necesita el tipo: 'int * [7]', que es el tipo del dato
SD> apuntado.
SD> Lo que podríamos hacer es crear dos tipos de datos en una sola sentencia
SD> 'typedef'. Por ejemplo,
SD> typedef int * tipo_array_ptr[7], * tipo_array_ptr_puntero;
SD> tipo_array_ptr_puntero ptr;
SD> ptr = new tipo_array_ptr;
SD> Para el último caso, tienes que separar las dos sentencias en dos
SD> sentencias. En otras palabras, no puedes declarar una variable y definir un
SD> tipo en una sola sentencia: son dos sentencias diferentes.
SD> Espero haber aclarado las dudas.
SD> Steven
Lo siento. Creo que es demasiado para mi nivel actual.
Volveré a intentarlo cuando profundice en el manejo de punteros.
Muchísimas gracias. Seguiremos en contacto.
_______________________________________________
Lista de correo Cconclase Cconclase@listas.conclase.net
http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ