 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Markus Pesti Guest
|
Posted: Mon Sep 04, 2006 7:40 pm Post subject: sizeof array |
|
|
Es funktioniert zwar, aber ich bin mir nicht sicher ob das vom Standard
gedeckt ist. Lässt sich die Länge eines Arrays auf folgende Art bestimmen?:
#include <iostream>
const char char_array[] = {
'a',
'b',
'c'
};
const char* chars_array[] = {
"String 1",
"String 2",
"String 3"
};
const int int_array[] = {
1,
2,
3,
};
int main() {
std::cout << "sizeof char_array:\t" << sizeof(char_array)/sizeof(char)
<< '\n';
std::cout << "sizeof chars_array:\t" <<
sizeof(chars_array)/sizeof(char*) << '\n';
std::cout << "sizeof int_array:\t" << sizeof(int_array)/sizeof(int) <<
'\n';
}
Markus |
|
| Back to top |
|
 |
Rolf Magnus Guest
|
Posted: Mon Sep 04, 2006 10:04 pm Post subject: Re: sizeof array |
|
|
Markus Pesti wrote:
| Quote: | Es funktioniert zwar, aber ich bin mir nicht sicher ob das vom Standard
gedeckt ist. Lässt sich die Länge eines Arrays auf folgende Art
bestimmen?:
#include <iostream
const char char_array[] = {
'a',
'b',
'c'
};
const char* chars_array[] = {
"String 1",
"String 2",
"String 3"
};
const int int_array[] = {
1,
2,
3,
};
int main() {
std::cout << "sizeof char_array:\t" << sizeof(char_array)/sizeof(char)
'\n';
|
Besser wäre noch:
std::cout << "sizeof char_array:\t" << sizeof(char_array)/sizeof(*char_array);
| Quote: | std::cout << "sizeof chars_array:\t"
sizeof(chars_array)/sizeof(char*) << '\n';
std::cout << "sizeof int_array:\t" << sizeof(int_array)/sizeof(int)
'\n';
}
|
Ja, das funktioniert so. Natürlich nur solange, wie du auch wirklich
das Array hast und nicht nur einen Zeiger auf sein erstes Element.
Also z.B.:
void myfunc(const int arr[])
{
std::cout << "sizeof arr:\t" << sizeof(arr)/sizeof(int) << '\n';
}
int main()
{
myfunc(int_array);
}
In myfunc ist arr nur noch ein Zeiger auf const int, und daher ist die
Array-Größe hier unbekannt. Es würde nur die Größe eines Zeigers auf int
durch die Größe eines int geteilt. |
|
| Back to top |
|
 |
Jirka Klaue Guest
|
Posted: Tue Sep 05, 2006 1:09 am Post subject: Re: sizeof array |
|
|
Markus Pesti:
| Quote: | Es funktioniert zwar, aber ich bin mir nicht sicher ob das vom Standard
gedeckt ist. Lässt sich die Länge eines Arrays auf folgende Art bestimmen?:
const char char_array[] = {
const char* chars_array[] = {
const int int_array[] = {
sizeof(char_array)/sizeof(char)
sizeof(chars_array)/sizeof(char*)
sizeof(int_array)/sizeof(int)
|
Funktioniert und ist so definiert. Meiner Meinung nach wäre das aber
sogar einer der sinnvollen Anwendungsfälle für Präprozessor-Makros.
#define AL(array) (sizeof array / sizeof *array)
Jirka |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Tue Sep 05, 2006 1:43 pm Post subject: Re: sizeof array |
|
|
Markus Pesti wrote:
| Quote: | Es funktioniert zwar, aber ich bin mir nicht sicher ob das vom
Standard gedeckt ist. Lässt sich die Länge eines Arrays auf
folgende Art bestimmen?:
#include <iostream
const char char_array[] = {
'a',
'b',
'c'
};
const char* chars_array[] = {
"String 1",
"String 2",
"String 3"
};
const int int_array[] = {
1,
2,
3,
};
int main() {
std::cout << "sizeof char_array:\t" << sizeof(char_array)/sizeof(char)
'\n';
|
Oder: sizeof(char_array)/sizeof(char_array[0])
| Quote: | std::cout << "sizeof chars_array:\t"
sizeof(chars_array)/sizeof(char*) << '\n';
std::cout << "sizeof int_array:\t" << sizeof(int_array)/sizeof(int)
'\n';
}
|
Funktionniert, solange es tatsschlich um Felder geht. Dagegen:
void f( int array[ 10 ] )
{
std::cout << sizeof(array)/sizeof(array[0]) << std::endl ;
}
wird wahrscheinlich nicht 10 ausgeben. Auf meinen Rechnern, z.B.
bekomme ich entweder 1 oder 2.
Sichere ist etwas wie:
template< typename T, size_t N >
size_t
size( T (&array)[ N ] )
{
return N ;
}
Damit bekommst du eine Fehlermeldung, statt einen falschen Wert,
falls es nicht geht. (Dagegen funktionniert's nicht, wenn T ein
lokales Typ ist.)
Häufig wird auch benutzt:
template< typename T, size_t N >
T*
begin( T (&array)[ N ] )
{
return array ;
}
template< typename T, size_t N >
T*
end( T (&array)[ N ] )
{
return array + N ;
}
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
| Back to top |
|
 |
Rolf Magnus Guest
|
Posted: Tue Sep 05, 2006 2:09 pm Post subject: Re: sizeof array |
|
|
Jirka Klaue wrote:
| Quote: | Markus Pesti:
Es funktioniert zwar, aber ich bin mir nicht sicher ob das vom Standard
gedeckt ist. Lässt sich die Länge eines Arrays auf folgende Art
bestimmen?:
const char char_array[] = {
const char* chars_array[] = {
const int int_array[] = {
sizeof(char_array)/sizeof(char)
sizeof(chars_array)/sizeof(char*)
sizeof(int_array)/sizeof(int)
Funktioniert und ist so definiert. Meiner Meinung nach wäre das aber
sogar einer der sinnvollen Anwendungsfälle für Präprozessor-Makros.
#define AL(array) (sizeof array / sizeof *array)
|
Nee. Kann man prima mit einem Template machen:
template<typename T, size_t Elems>
size_t array_size(T (&array)[Elems])
{
return sizeof array / sizeof *array;
} |
|
| Back to top |
|
 |
Lukas Mai Guest
|
Posted: Tue Sep 05, 2006 9:06 pm Post subject: Re: sizeof array |
|
|
Rolf Magnus <ramagnus@t-online.de> schrob:
| Quote: | Nee. Kann man prima mit einem Template machen:
template<typename T, size_t Elems
size_t array_size(T (&array)[Elems])
{
return sizeof array / sizeof *array;
}
|
Oder gleich
template<typename T, size_t Elems>
size_t countof(const T (&)[Elems])
{
return Elems;
}
Lukas |
|
| Back to top |
|
 |
Thomas Maeder Guest
|
Posted: Tue Sep 05, 2006 9:40 pm Post subject: Re: sizeof array |
|
|
Rolf Magnus <ramagnus@t-online.de> writes:
| Quote: | #define AL(array) (sizeof array / sizeof *array)
Nee. Kann man prima mit einem Template machen:
template<typename T, size_t Elems>
size_t array_size(T (&array)[Elems])
{
return sizeof array / sizeof *array;
}
|
Zumindest solange man keine Konstante zur Übersetzungszeit braucht.
Wenn man sie braucht, hilft
template<typename T, size_t Elems>
char[Elems] array_sizer(T (&array)[Elems]);
, und
sizeof array_sizer(int_array)
ist eine Konstante. |
|
| Back to top |
|
 |
Stefan Reuther Guest
|
Posted: Tue Sep 05, 2006 9:45 pm Post subject: Re: sizeof array |
|
|
Rolf Magnus wrote:
| Quote: | Jirka Klaue wrote:
#define AL(array) (sizeof array / sizeof *array)
Nee. Kann man prima mit einem Template machen:
template<typename T, size_t Elems
size_t array_size(T (&array)[Elems])
{
return sizeof array / sizeof *array;
}
|
Vorteil ist, dass das Ding mit Zeigertypen definiert nicht funktioniert.
Nachteil ist, dass es kein konstanter Ausdruck mehr ist. Außerdem
funktioniert es mit dem Borland-Compiler nicht, der mag keine
Array-Referenzen. Daher bleibe ich für diesen Anwendungsfall bei Makros
(bei mir unter dem Namen 'countof').
Stefan |
|
| Back to top |
|
 |
Markus Donath Guest
|
Posted: Wed Sep 06, 2006 12:48 pm Post subject: Re: sizeof array |
|
|
Stefan Reuther wrote:
| Quote: | Vorteil ist, dass das Ding mit Zeigertypen definiert nicht funktioniert.
Nachteil ist, dass es kein konstanter Ausdruck mehr ist. Außerdem
funktioniert es mit dem Borland-Compiler nicht, der mag keine
Array-Referenzen. Daher bleibe ich für diesen Anwendungsfall bei Makros
(bei mir unter dem Namen 'countof').
Stefan
|
Also mein Borland-Compiler (BCB 5 und BDS 4) hat mit Array-Referenzen
kein Problem.
Markus |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Wed Sep 06, 2006 12:53 pm Post subject: Re: sizeof array |
|
|
Thomas Maeder wrote:
| Quote: | Rolf Magnus <ramagnus@t-online.de> writes:
#define AL(array) (sizeof array / sizeof *array)
Nee. Kann man prima mit einem Template machen:
template<typename T, size_t Elems
size_t array_size(T (&array)[Elems])
{
return sizeof array / sizeof *array;
}
Zumindest solange man keine Konstante zur Übersetzungszeit
braucht.
Wenn man sie braucht, hilft
template<typename T, size_t Elems
char[Elems] array_sizer(T (&array)[Elems]);
|
Bist du sicher? Ich habe immer geglaubt, dass Funktionen nicht
Felder zurückgeben dürfen. Steht auch in der Norm (§8.3.5/7):
»Functions shall not have a return type of tyep array or
function, although they may have a return type of type pointer
or reference to such things.«
Auch wäre deine Syntax falsch, wenn so was erlaubt wurde; in C++
komment die [] nie vor dem Namen des definierten. Also wäre es:
template< typename T, size_t N >
char array_sizer( T (&array)[ N ] )[ N ] ;
Und als Referenz, damit es legal wird:
template< typename T, size_t N >
char (&array_sizer( T (&array)[ N ] ))[ N ] ;
| Quote: | , und
sizeof array_sizer(int_array)
ist eine Konstante.
|
Mit der veränderten Vereinbarung oben. Funktionniert auch,
mindestens mit g++ 4.1.0. (Ich vermute, dass einige Compiler
damit Probleme habe, auch wenn es legal ist.)
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
| Back to top |
|
 |
Thomas Maeder Guest
|
Posted: Wed Sep 06, 2006 7:56 pm Post subject: Re: sizeof array |
|
|
"kanze" <kanze@gabi-soft.fr> writes:
Natürlich nicht. Deine Version ist die richtige. |
|
| Back to top |
|
 |
Markus Becker Guest
|
Posted: Wed Sep 06, 2006 8:16 pm Post subject: Re: sizeof array |
|
|
Thomas Maeder wrote:
| Quote: | Zumindest solange man keine Konstante zur Übersetzungszeit braucht.
, und
sizeof array_sizer(int_array)
ist eine Konstante.
|
Muss nicht das Ergebnis von 'sizeof' *immer* zur Kompilezeit
bekannt sein?
Markus |
|
| Back to top |
|
 |
Thomas Maeder Guest
|
Posted: Thu Sep 07, 2006 2:38 am Post subject: Re: sizeof array |
|
|
Markus Becker <yetispamb (AT) web (DOT) de> writes:
| Quote: | Zumindest solange man keine Konstante zur Übersetzungszeit braucht.
, und
sizeof array_sizer(int_array)
ist eine Konstante.
Muss nicht das Ergebnis von 'sizeof' *immer* zur Kompilezeit
bekannt sein?
|
Es ist immer zur Übersetzungszeit bekannt. |
|
| Back to top |
|
 |
Stefan Reuther Guest
|
Posted: Fri Sep 08, 2006 9:57 pm Post subject: Re: sizeof array |
|
|
Markus Donath wrote:
| Quote: | Stefan Reuther wrote:
Nachteil ist, dass es kein konstanter Ausdruck mehr ist. Außerdem
funktioniert es mit dem Borland-Compiler nicht, der mag keine
Array-Referenzen. Daher bleibe ich für diesen Anwendungsfall bei Makros
(bei mir unter dem Namen 'countof').
Also mein Borland-Compiler (BCB 5 und BDS 4) hat mit Array-Referenzen
kein Problem.
|
Meiner schon.
$ type as.cc
typedef unsigned int size_t;
template<typename T, size_t Elems>
size_t array_size(T (&array)[Elems])
{
return sizeof array / sizeof *array;
}
int y[20];
int x() {
return array_size(y);
}
$ bcc32 as.cc
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
as.cc:
Error E2141 as.cc 3: Declaration syntax error
Error E2451 as.cc 13: Undefined symbol 'y' in function x
Warning W8065 as.cc 13: Call to function 'array_size' with no prototype
in function x
*** 2 errors in Compile ***
Da der 5.5 immer noch (jedenfalls vor kurzem) zum freien Download
angeboten wird, halte ich es zumindest für meine privaten Projekte für
sinnvoll, auf diesen Bug^W^H^H Eigenheit Rücksicht zu nehmen. Für die
Array-Größenbestimmung eben per Makro (schon, weil das einen konstanten
Ausdruck ergibt), für weiteres mittels '#ifdef __BORLANDC__' und einem
Makro. Der Code sieht meinem Dafürhalten nach korrekt aus, und wird von
gcc (selbst so Uraltteile wie 2.8.1) akzeptiert.
Stefan |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|