配列引数のサイズを調べる
配列引数のサイズを調べる
void main(){
int a[20];
int i;
for ( i = 0 ; i < sizeof(a) / sizeof(int) ; i ++ )
a = i;
}
上のように書くと配列の要素数だけループしますよね
しかし関数の引数に配列を渡した場合は先頭のアドレスが渡されるだけなので
sizeof演算子は要素数を返してくれません
何か良い方法は無いでしょうか?
int a[20];
int i;
for ( i = 0 ; i < sizeof(a) / sizeof(int) ; i ++ )
a = i;
}
上のように書くと配列の要素数だけループしますよね
しかし関数の引数に配列を渡した場合は先頭のアドレスが渡されるだけなので
sizeof演算子は要素数を返してくれません
何か良い方法は無いでしょうか?
Re:配列引数のサイズを調べる
こんな感じですかね。
void func(int a[/url],int size)
{
int i;
for ( i = 0 ; i < size ; i ++ )
a = i;
}
}
int main(){
int a[20];
func(a,sizeof(a) / sizeof(int));
return 0;
}
ちなみに、呼び出しをこうする方法もあります。
#define FUNC(array) func((array),sizeof((array))/sizeof(int))
int main(){
int a[20];
FUNC(a);
return 0;
}
void func(int a[/url],int size)
{
int i;
for ( i = 0 ; i < size ; i ++ )
a = i;
}
}
int main(){
int a[20];
func(a,sizeof(a) / sizeof(int));
return 0;
}
ちなみに、呼び出しをこうする方法もあります。
#define FUNC(array) func((array),sizeof((array))/sizeof(int))
int main(){
int a[20];
FUNC(a);
return 0;
}
Re:配列引数のサイズを調べる
C言語の引数の受け渡しの仕組みでは無理です。
オブジェクト指向言語のJavaやC#なら言語仕様自体で配列の仕組みが違うので必要ないですが。
C++でもクラスを使えば擬似的には可能です。
オブジェクト指向言語のJavaやC#なら言語仕様自体で配列の仕組みが違うので必要ないですが。
C++でもクラスを使えば擬似的には可能です。
Re:配列引数のサイズを調べる
STLのvectorを参照渡しで使います。
すいません、いま説明している時間が無いので検索してみてください。
分からなければ、明日またお答えします。
すいません、いま説明している時間が無いので検索してみてください。
分からなければ、明日またお答えします。
Re:配列引数のサイズを調べる
配列の要素数は一般的に以下の形式が多用されてるみたいです。
これでプログラムがすっきりすると思います。
int main() { int array[20]; // num は20になる int num = sizeof( array ) / sizeof( array[0] ); return 0; } また、define定義を用いれば #define array_sizeof(p) ( sizeof( p) / sizeof( (p)[0] ) ) int main() { int array[20]; // num は20になる int num = array_sizeof(array); return 0; }
これでプログラムがすっきりすると思います。
Re:配列引数のサイズを調べる
本文読み直したら、勘違いしていました^^;
関数に配列を渡しても、要素数は引き継げないっていう話でしたね・・・・申し訳ないです。
関数先にC++のテンプレートを用いれば、要素数も引き継いでくれるのですが、一応解決された
みたいなのでまたの機会に。
関数に配列を渡しても、要素数は引き継げないっていう話でしたね・・・・申し訳ないです。
関数先にC++のテンプレートを用いれば、要素数も引き継いでくれるのですが、一応解決された
みたいなのでまたの機会に。
Re:配列引数のサイズを調べる
C++でtemplateを使用すれば、引数をサイズを渡す必要はありません。
#include <iostream> template<class T, int N> void func(T (&ar)[N]) { for (int i = 0; i < N; ++i) { std::cout << ar << std::endl; } } int main() { int data[/url] = { 0, 1, 2, 3 }; func(data); }
Re:配列引数のサイズを調べる
C++の次期規格であれば...
template <typename T, std::size_t N> constexpr std::size_t count(T (&arg)[N]) { return N; }とすれば、定数式として扱うこともできますね。
Re:配列引数のサイズを調べる
>解説サイトとかあったら教えてください
少し古い記事ですが
テンプレート引数の一致
ttp://msdn.microsoft.com/ja-jp/library/cc440189(VS.71).aspx
Re:配列引数のサイズを調べる
う~ん良くわかりませんでしたね・・
ちなみに
template<class T, int N>
のclassとintの違いは何でしょうか?
あとTに入る型が全て同じの場合に
Nだけにする事はできないでしょうか?
ちなみに
template<class T, int N>
のclassとintの違いは何でしょうか?
あとTに入る型が全て同じの場合に
Nだけにする事はできないでしょうか?
Re:配列引数のサイズを調べる
>あとTに入る型が全て同じの場合に
>Nだけにする事はできないでしょうか?
部分特殊化を使えばOK.
>Nだけにする事はできないでしょうか?
部分特殊化を使えばOK.
#include <iostream> using namespace std; //int 型バージョン template<std::size_t N> void func(int (&ar)[N]) { std::cout << "int " << std::endl; for(int i=0; i<N;++i){ std::cout << ar << std::endl; } } //なんでも型バージョン template<class T, std::size_t N> void func(T (&ar)[N]) { std::cout << "not int" << std::endl; for (int i = 0; i < N; ++i) { std::cout << ar << std::endl; } } int main() { //int型の配列 int data[/url] = { 0, 1, 2, 3 }; //const int型の配列 const int data2[/url]={0, 1, 2, 3}; func(data); func(data2); return 0; }
Re:配列引数のサイズを調べる
これは良いですね、最初に比べてかなり短くなりました
どこまで短くできるか気になりますね
そこで
>template<int N>
>(int (&Graph)[N])
ここをもっと短く書けないでしょうか?
あとテンプレートの柔軟性に期待して
関数を呼ぶ前に配列を作成しないで
引数の(と)の中に数値や変数を並べて渡せないでしょうか?
つまり
Draw({1,2,3,4,5});
見たいな事はできないでしょうか?
template<int N> int Draw(int (&Graph)[N]){ int i; for( i=0;i<N;i++ ); return i; }これは練習で作った関数ですが
どこまで短くできるか気になりますね
そこで
>template<int N>
>(int (&Graph)[N])
ここをもっと短く書けないでしょうか?
あとテンプレートの柔軟性に期待して
関数を呼ぶ前に配列を作成しないで
引数の(と)の中に数値や変数を並べて渡せないでしょうか?
つまり
Draw({1,2,3,4,5});
見たいな事はできないでしょうか?
Re:配列引数のサイズを調べる
>これは練習で作った関数ですが
>どこまで短くできるか気になりますね
意図が見えないのですが、
ループ回さずにreturn N;
で十分なような気が。。。
テンプレートのところは短くできないです。
>Draw({1,2,3,4,5});
>見たいな事はできないでしょうか?
次期C++ならできるような気もしますが、現在はマクロを併用して擬似的にするしかないのかな、
配列を引数にと考えなければ可長変引数を使えばできますけど、安全性に不安が出てきますね。
>どこまで短くできるか気になりますね
意図が見えないのですが、
ループ回さずにreturn N;
で十分なような気が。。。
テンプレートのところは短くできないです。
>Draw({1,2,3,4,5});
>見たいな事はできないでしょうか?
次期C++ならできるような気もしますが、現在はマクロを併用して擬似的にするしかないのかな、
配列を引数にと考えなければ可長変引数を使えばできますけど、安全性に不安が出てきますね。
Re:配列引数のサイズを調べる
簡略化はこの辺が限界みたいですね
でも当初の目的は達せたので助かりました
これから実装してみるので少々お待ちください
ちなみに
>現在はマクロを併用して擬似的にするしかないのかな
これはどんな感じでしょうか?
でも当初の目的は達せたので助かりました
これから実装してみるので少々お待ちください
ちなみに
>現在はマクロを併用して擬似的にするしかないのかな
これはどんな感じでしょうか?
Re:配列引数のサイズを調べる
こんな風にして定数式にすることもできます。
template <typename T, std::size_t N> char (*count_helper(T (&array)[N]))[N]; #define count(array) sizeof(*count_helper(array))マクロであること自体も問題点を除けば、結構優れものかもしれません。
Re:配列引数のサイズを調べる
> どんな感じで使うのでしょうか?
そんなに難しく考える必要はありません。
そんなに難しく考える必要はありません。
int a[7]; std::size_t n = count(a);とすれば、nに7が代入されるはずです。
Re:配列引数のサイズを調べる
> しかしこれでDraw({1,2,3,4,5});
> が擬似的に実現できるのでしょうか?
それを目指したものではありません。
Draw({1, 2, 3, 4, 5})を実現するには、C99かC++の次期標準でなければ無理です。GCCでも何とかなります。
多少シンタックスを変えてもよいなら実現することは可能ですが、オーバーヘッドが大きくなります。
> が擬似的に実現できるのでしょうか?
それを目指したものではありません。
Draw({1, 2, 3, 4, 5})を実現するには、C99かC++の次期標準でなければ無理です。GCCでも何とかなります。
多少シンタックスを変えてもよいなら実現することは可能ですが、オーバーヘッドが大きくなります。
Re:配列引数のサイズを調べる
> Draw({1,2,3,4,5});は無理だとしても
> 予め配列を作成しておかなくても良いような方法は無いでしょうか?
要素数の上限があらかじめ決まっているのであれば、make_tupleを使う方法もありますし、
可変個数引数を使う方法もありますが、あまりお勧めはしません。
> 予め配列を作成しておかなくても良いような方法は無いでしょうか?
要素数の上限があらかじめ決まっているのであれば、make_tupleを使う方法もありますし、
template <typename T> void Draw(const T& e1); template <typename T> void Draw(const T& e1, const T& e2); template <typename T> void Draw(const T& e1, const T& e2, const T& e3); ...のように、数だけ多重定義しておく方法もあります。
可変個数引数を使う方法もありますが、あまりお勧めはしません。
Re:配列引数のサイズを調べる
遅くなってしまいましたが、
>> 部分特殊化を使えばOK.
>関数テンプレートの部分特殊化はできないので、これは単なる多重定義ですね。
正しくないことを書いてしまってすみませんでした。
>> 部分特殊化を使えばOK.
>関数テンプレートの部分特殊化はできないので、これは単なる多重定義ですね。
正しくないことを書いてしまってすみませんでした。