- ベストアンサー
なんでchar型なんでしょうか??
なぜここ(☆☆)で char型なのかが よく・・いやさっぱりわかりません。 他の型ではだめなんでしょーか? この関数自体は挿入ソートだとわ思われるんで なんとなくこの☆☆(から以下三行あたりまで) のところの動作の意味はわかるんですが なぜchar型でなくてはならないのかが。 知っている方いたら どうか教えてください。 typedef User* PUser; typedef int (*CFT)(const void*, const void*); void ssort(void* base, unsigned int n, unsigned int sz, CFT cmp) { for (int i = 0; i < n - 1; i++) for (int j = n - 1; i < j; j--) { char* pj = (char*)base + j * sz; //←ここ☆☆ char* pj1 = pj - sz; //とここ☆☆ if (cmp(pj, pj1) < 0) { for (int k = 0; k < sz; k++) { char temp = pj[k]; pj[k] = pj1[k]; pj1[k] = temp; } } } /* ssort関数の引数の関数ポインタで 利用される比較関数 */ int cmp1(const void* p, const void* q) { return strcmp(PUser(p)->name, PUser(q)->name); } int cmp2(const void* p, const void* q) { return PUser(p)->dept - PUser(q)->dept; }
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
- ベストアンサー
ポインタの基本的な事なのですが、 char *pc = (char*)0 + 1; // pc は (char*)1 になる int *pi = (int*)0 + 1; // pi は (int*)4 になる ※intが32ビットの場合 つまり、void* をバイト単位で増減させる為に、char* にキャストしているわけです。
その他の回答 (2)
- TMINET
- ベストアンサー率32% (45/140)
構造体(ここでの User heads[] )も配列ですからcharポインタとの間でアドレスを交換できますよ。 このケースですとheadsのデータ(6レコード)をソート(入れ替え)する処理のようですね。 引数のn(件数)とsz(構造体のサイズ)でレコードの先頭を割り出していますね。
お礼
ホントすみません 知識不足なもんでどう説明していいのか 自分でもうまくできませんでした。 僕が聞いてみたかったのは inthefloiさんが回答してくれたとこです。 (ピンポイントでした) 右往左往したときまたお世話になりますw
- TMINET
- ベストアンサー率32% (45/140)
char型ではなくcharポインタ型ですね。配列を意味しています。 文字列中の文字を入れ替えるのが目的ですからこれで良いのでは。
補足
関数ssortの引数baseで受けるのが文字列や文字型とかならそうだろうということはわかります。はい。 すいません先のプログラムでは不足してたみたいです 下にプログラム全体を載せちゃいます。 で質問 引数baseで構造体Userを受け取った場合は どうなるんでしょうか。 状況の説明不足本当にすみません m(__)m struct User { char* name; char* id; int dept; }; typedef User* PUser; User heads[] = { "Ritchie D. M.", "dmr", 11271, "Sethi R.", "ravi", 11272, "Szymanski T. G.", "tgs", 11273, "Schryer N. L.", "nls", 11274, "Schryer N. L.", "nls", 11275, "Kernighan B. W.", "bwk", 11276, }; typedef int (*CFT)(const void*, const void*); void ssort(void*, unsigned int, unsigned int, CFT cmp); void print_id(PUser , int); int cmp1(const void*, const void*); int cmp2(const void*, const void*); void ssort(void* base, unsigned int n, unsigned int sz, CFT cmp) { for (int i = 0; i < n - 1; i++) for (int j = n - 1; i < j; j--) { char* pj = (char*)base + j * sz; char* pj1 = pj - sz; if (cmp(pj, pj1) < 0) { for (int k = 0; k < sz; k++) { char temp = pj[k]; pj[k] = pj1[k]; pj1[k] = temp; } } } } void print_id(PUser v, int n) { for (int i = 0; i < n; i++) cout << v[i].name << '\t' << v[i].id << '\t' << v[i].dept << '\n'; } int cmp1(const void* p, const void* q) { return strcmp(PUser(p)->name, PUser(q)->name); } int cmp2(const void* p, const void* q) { return PUser(p)->dept - PUser(q)->dept; } int main() { cout << "Heads in alphabetical order\n"; ssort(heads, 6, sizeof(User), cmp1); print_id(heads, 6); cout << "\n"; cout << "Heads in department number\n"; ssort(heads, 6, sizeof(User), cmp2); print_id(heads, 6); cout << "\n"; return true; }
お礼
>>void* をバイト単位で増減させる為に、char* にキャストしているわけです。 ナルホド! そのためのcharだったんですか。 それで、 Userクラスのオブジェクトをひとつずつずらすために sizeof(User)をbaseに足していくという作業があるんですね。 そんでもって、比較関数の中では さらにその操作されたpjやpj1に格納されたアドレスをPUserでキャストしてname同士を 比較する・・・というしくみで・・ 大体あってますか?w (文章変ですがすみません) 「ポインタの基本的なこと」と書かれていて、ちょと自分に反省しました。 ポインタをナメテマシタ ホントもやもやがすっきりしたって感じです どうもありがとうございました またお世話になると思いますですw