I am reading C++ primer book and completely don\'t understand one line:
using int_array = int[4];
typedef int int_array[4]; // This line
for (int_array *
Both are doing the exact same thing: Defining int_array
as an alias of an array of 4 int
s
using
has a nice A = B notation that is generally much easier to understand.
using alias = type;
typedef
's notation is not quite backward. For a simple typedef
typedef type alias;
but more complicated typedef
s tend to sprawl. I suspect the syntax was modeled after how one would define a variable, but I can't find where I packed my copy of the old K&R C programming book and can't look that up at the moment.
int int_array[4];
would define int_array
to be an array of 4 int
s. Slapping typedef
on the front
typedef int int_array[4];
makes int_array
a type alias instead of a variable.
Another example,
int * intp;
Defines intp
to be a pointer to an int
.
typedef int * intp;
Defines intp
to be an alias to the type pointer to an int
.
This gets ugly with more complicated data types as the name of the typedef
ed alias may be buried somewhere in the middle of the definition. A typedef
ed function pointer for example:
typedef void (*funcp)(param_t param1, param_t param2, ...);
vs using
using funcp = void (*)(param_t param1, param_t param2, ...);
If you want a 2D array you could
using int_array2D = int[4][4];
or you could define an array of int_array
using int_array2D = int_array[4];
And of course that means you can
using int_array3D = int_array2D[4];
and keep on going until the cows come home or you've packed on so many dimensions that The Doctor's brain melts.
Both type aliases are the same:
Type alias, alias template (since C++11):
Type alias is a name that refers to a previously defined type (similar to typedef):
using identifier attr(optional) = type-id ;
so you may use:
typedef int int_array[4];
or you may just use (it is the same as above):
using int_array = int[4];
When you need to address the memory with 4*sizeof(int)
steps, e.g. if the system int
size is 4 bytes, then the memory step size is 4*4=16 bytes. even you may use int_array *p;
in this case ++p
advances p
by one memory step e.g. 16 bytes.
see:
1- working sample with using int_array = int[4];
:
#include <iostream>
using std::cout; using std::endl;
int main()
{
int ia[3][4] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
// a range for to manage the iteration
// use type alias
using int_array = int[4];
for (int_array& p : ia)
for (int q : p)
cout << q << " ";
cout << endl;
// ordinary for loop using subscripts
for (size_t i = 0; i != 3; ++i)
for (size_t j = 0; j != 4; ++j)
cout << ia[i][j] << " ";
cout << endl;
// using pointers.
// use type alias
for (int_array* p = ia; p != ia + 3; ++p)
for (int *q = *p; q != *p + 4; ++q)
cout << *q << " ";
cout << endl;
return 0;
}
output 1:
0 1 2 3 4 5 6 7 8 9 10 11
0 1 2 3 4 5 6 7 8 9 10 11
0 1 2 3 4 5 6 7 8 9 10 11
2- working sample using typedef int int_array[4];
:
#include <iostream>
using std::cout; using std::endl;
int main()
{
int ia[3][4] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
// a range for to manage the iteration
// use type alias
typedef int int_array[4];
for (int_array& p : ia)
for (int q : p)
cout << q << " ";
cout << endl;
// ordinary for loop using subscripts
for (size_t i = 0; i != 3; ++i)
for (size_t j = 0; j != 4; ++j)
cout << ia[i][j] << " ";
cout << endl;
// using pointers.
// use type alias
for (int_array* p = ia; p != ia + 3; ++p)
for (int *q = *p; q != *p + 4; ++q)
cout << *q << " ";
cout << endl;
return 0;
}
output 2(same):
0 1 2 3 4 5 6 7 8 9 10 11
0 1 2 3 4 5 6 7 8 9 10 11
0 1 2 3 4 5 6 7 8 9 10 11
ref: https://github.com/Mooophy/Cpp-Primer/blob/master/ch03/ex3_44.cpp
note: use -std=c++11
for compile/link.
3- just for demo(excerpt):
some real world usage in embedded system:
extern const char kpd2ascii[6][6] PROGMEM;
typedef const char cint8a6_t[6];
cint8a6_t *p;
p = kpd2ascii;
kpdBuffer = pgm_read_byte(&p[row][col - 1]);
I hope this helps.
The lines
using int_array = int[4];
and
typedef int int_array[4];
do the same thing. See reference for using and typedef. You can leave one or the other out and the behaviour is the same. It is not an error to have two different declarations, as they are not conflicting (they do the exact same thing).
The first way of doing it (using the using
keyword) was introduced with C++11 and is in my opinion easier to read, so I prefer it over the typedef version.