ページ 1 / 1
bsearchの使い方が分かりません
Posted: 2017年7月17日(月) 20:55
by リディアンドミナント
1. 自分は今何がしたくて
プログラムのコンパイルエラーを直したい
2. どう取り組んで(作ったプログラムはどれで
google検索をしたのですが、上手くいきませんでした。
こちらで質問させてもらいます。
3. どのようなエラーやトラブルで困っていて
エラー C2664 'void *bsearch(const void *,const void *,::size_t,::size_t,_CoreCrtNonSecureSearchSortCompareFunction)':
引数 5 を 'void (__cdecl *)(const void *,const void *)' から '_CoreCrtNonSecureSearchSortCompareFunction' へ変換できません。
4. 自分は何が解らないのか、知りたいのか
bsearchの(int(*)(const void *, const void *))int_cmpをどう改良すればいいのか分かりません。
5. 今のCの知識はどの程度なのか
基本的な文法知識は身についてると思います。
コード:
#include "stdafx.h"
#include<stdio.h>
#include<stdlib.h>
int int_cmp(const int *a, const int *b) {
if (*a < *b)
return -1;
else if (*a > *b)
return 1;
else
return 0;
}
int main(void) {
int i, nx, ky;
int *x;
int *p;
puts("bsearch関数による探索");
printf("要素数:");
scanf_s("%d", &nx);
x = (int *)calloc(nx, sizeof(int));
printf("昇順に入力してください\n");
printf("x[0]:");
scanf_s("%d", &x[0]);
for (i = 1; i < nx; i++) {
do {
printf("x[%d]:", i);
scanf_s("%d", &x[i]);
} while (x[i] < x[i - 1]);
}
printf("探す値:");
scanf_s("%d", &ky);
p = bsearch(&ky,
x,
nx,
sizeof(int),
(int(*)(const void *, const void *))int_cmp
);
if (p == NULL)
puts("探索に失敗しました");
else
printf("%dはx[%d]にあります\n", ky, (int)(p - x));
free(x);
return 0;
}
Re: bsearchの使い方が分かりません
Posted: 2017年7月17日(月) 22:07
by Math
Windows10,VS2017Community,C言語(拡張子*.c)ではエラー発生せず正常動作しますね。
コード:
// #include "stdafx.h"
#include<stdio.h>
#include<stdlib.h>
int int_cmp(const int *a, const int *b) {
if (*a < *b)
return -1;
else if (*a > *b)
return 1;
else
return 0;
}
int main(void) {
int i, nx, ky;
int *x;
int *p;
puts("bsearch関数による探索");
printf("要素数:");
scanf_s("%d", &nx);
x = (int *)calloc(nx, sizeof(int));
printf("昇順に入力してください\n");
printf("x[0]:");
scanf_s("%d", &x[0]);
for (i = 1; i < nx; i++) {
do {
printf("x[%d]:", i);
scanf_s("%d", &x[i]);
} while (x[i] < x[i - 1]);
}
printf("探す値:");
scanf_s("%d", &ky);
p = bsearch(&ky,
x,
nx,
sizeof(int),
(int(*)(const void *, const void *))int_cmp
);
if (p == NULL)
puts("探索に失敗しました");
else
printf("%dはx[%d]にあります\n", ky, (int)(p - x));
free(x);
return 0;
}
C++(拡張子*.cpp)では
コード:
1>------ ビルド開始: プロジェクト: ConsoleApplication5, 構成: Debug Win32 ------
1>c1.cpp
1>d:\z17a\07\16\consoleapplication5\consoleapplication5\c1.cpp(45): error C2440: '=': 'void *' から 'int *' に変換できません。
1>d:\z17a\07\16\consoleapplication5\consoleapplication5\c1.cpp(45): note: 'void*' から非 'void' 型への変換には明示的なキャストが必要です。
1>プロジェクト "ConsoleApplication5.vcxproj" のビルドが終了しました -- 失敗。
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========
となりますね。
Re: bsearchの使い方が分かりません
Posted: 2017年7月17日(月) 23:23
by リディアンドミナント
Mathさん
ありがとうございます。
とりあえず問題は解決しました。
C拡張子では動くけど、C++拡張子では動かないという認識ですね。
C++では使えない(?)ようですね。
Re: bsearchの使い方が分かりません
Posted: 2017年7月17日(月) 23:47
by Math
その通りですね。
C と C/C++(拡張CとC++) は微妙に違いますね!
Re: bsearchの使い方が分かりません
Posted: 2017年7月18日(火) 00:01
by みけCAT
リディアンドミナント さんが書きました:C拡張子では動くけど、C++拡張子では動かないという認識ですね。
C++では使えない(?)ようですね。
Math さんが書きました:その通りですね。
その通りではありません。
「明示的なキャストが必要です。」とあるので、それに従って明示的なキャストを書けば使えるはずです。
リディアンドミナント さんが書きました:
エラー C2664 'void *bsearch(const void *,const void *,::size_t,::size_t,_CoreCrtNonSecureSearchSortCompareFunction)':
引数 5 を 'void (__cdecl *)(const void *,const void *)' から '_CoreCrtNonSecureSearchSortCompareFunction' へ変換できません。
このエラーが再現できていませんが、リディアンドミナントさんが使用しているコンパイラは何ですか?
Re: bsearchの使い方が分かりません
Posted: 2017年7月18日(火) 00:10
by Math
>「明示的なキャストが必要です。」とあるので、それに従って明示的なキャストを書けば使えるはずです。
勿論そういう意味では使えるわけですがVisualStudioではC用にかかれたProgramがそのままではC/C++で動かないという意味ですね。
Re: bsearchの使い方が分かりません
Posted: 2017年7月18日(火) 06:27
by かずま
みけCAT さんが書きました:「明示的なキャストが必要です。」とあるので、それに従って明示的なキャストを書けば使えるはずです。
p = (int *)bsearch(&ky,
にするということですね。
リディアンドミナント さんが書きました:
エラー C2664 'void *bsearch(const void *,const void *,::size_t,::size_t,_CoreCrtNonSecureSearchSortCompareFunction)':
引数 5 を 'void (__cdecl *)(const void *,const void *)' から '_CoreCrtNonSecureSearchSortCompareFunction' へ変換できません。
このエラーが再現できていませんが、リディアンドミナントさんが使用しているコンパイラは何ですか?[/quote]
(&ky,
Re: bsearchの使い方が分かりません
Posted: 2017年7月18日(火) 06:30
by かずま
すみません。まちがって送信してしまいました。
みけCAT さんが書きました:
リディアンドミナント さんが書きました:
エラー C2664 'void *bsearch(const void *,const void *,::size_t,::size_t,_CoreCrtNonSecureSearchSortCompareFunction)':
引数 5 を 'void (__cdecl *)(const void *,const void *)' から '_CoreCrtNonSecureSearchSortCompareFunction' へ変換できません。
このエラーが再現できていませんが、リディアンドミナントさんが使用しているコンパイラは何ですか?
(int(*)(const void *, const void *))int_cmp
を
(void(*)(const void *, const void *))int_cmp
に変更すると、再現できます。
最初の質問のソースとエラーメッセージの対応が間違っているものと思われます。
Re: bsearchの使い方が分かりません
Posted: 2017年7月18日(火) 20:23
by リディアンドミナント
みけCATさん、かずまさん返信ありがとうございます。
ややこしくしてしまって、すみません。
かずまさんの言うとおり、私はvoid(*)でキャスト変換して、コンパイルしてそのままエラーを掲示してしまいました。
質問項目2のプロセスで記載すべきでした。
みけCATさん
私が使ってるコンパイルは、visual studio2017Community
新規作成->プロジェクト->visual C++->win32コンソールアプリケーション
です
最初のエラーはこれでした。
(アクティブ) E0513 型 "void *" の値を型 "int *" のエンティティに割り当てることはできません
最終的には、
Mathさんが言ってるように、VisualStudioではC用にかかれたProgramがそのままではC/C++で動かないという認識でいいのでしょうか…。
Re: bsearchの使い方が分かりません
Posted: 2017年7月18日(火) 22:34
by 結城紬
リディアンドミナントさん
Visual C++ に限った話ではなく、C++ は細かい仕様が C から変わっているため、そのままではコンパイルできないことはよくあることです。
今回の問題は void* の扱いが異なることが原因です。
C では void* は他のポインタ型(今回の場合、 int* )へ勝手にキャストされていましたが、
C++ では void* 型は勝手にキャストされなくなり、明示的に (int*)bsearch(... のようにキャストする必要があります。
特に C では malloc の戻り値をキャストしない人が多く、C++ への移行時に問題になりやすい部分です。
Re: bsearchの使い方が分かりません
Posted: 2017年7月18日(火) 22:46
by リディアンドミナント
結城紬さんありがとうございます。
C++で実行する際は、このコードで行けそうです。
malloc関数についても悩んだことあったのですが、このサイトで解決した覚えがあります。
http://www9.plala.or.jp/sgwr-t/lib/malloc.html
コード:
#include "stdafx.h"
#include<stdio.h>
#include<stdlib.h>
int int_cmp(const int *a, const int *b) {
if (*a < *b)
return -1;
else if (*a > *b)
return 1;
else
return 0;
}
int main(void) {
int i, nx, ky;
int *x;
int *p;
puts("bsearch関数による探索");
printf("要素数:");
scanf_s("%d", &nx);
x = (int *)calloc(nx, sizeof(int));
printf("昇順に入力してください\n");
printf("x[0]:");
scanf_s("%d", &x[0]);
for (i = 1; i < nx; i++) {
do {
printf("x[%d]:", i);
scanf_s("%d", &x[i]);
} while (x[i] < x[i - 1]);
}
printf("探す値:");
scanf_s("%d", &ky);
p = (int *)bsearch(&ky,
x,
nx,
sizeof(int),
(int(*)(const void *, const void *))int_cmp
);
if (p == NULL)
puts("探索に失敗しました");
else
printf("%dはx[%d]にあります\n", ky, (int)(p - x));
free(x);
return 0;
}
結城紬 さんが書きました:リディアンドミナントさん
Visual C++ に限った話ではなく、C++ は細かい仕様が C から変わっているため、そのままではコンパイルできないことはよくあることです。
今回の問題は void* の扱いが異なることが原因です。
C では void* は他のポインタ型(今回の場合、 int* )へ勝手にキャストされていましたが、
C++ では void* 型は勝手にキャストされなくなり、明示的に (int*)bsearch(... のようにキャストする必要があります。
特に C では malloc の戻り値をキャストしない人が多く、C++ への移行時に問題になりやすい部分です。
Re: bsearchの使い方が分かりません
Posted: 2017年7月18日(火) 23:07
by リディアンドミナント
かずまさんも同じようなソースになってますね。
参考になりました。
C++でも動かせて良かったです。
C++でも動かせたいという趣旨で次回は質問しようと思います。
かずま さんが書きました:みけCAT さんが書きました:「明示的なキャストが必要です。」とあるので、それに従って明示的なキャストを書けば使えるはずです。
p = (int *)bsearch(&ky,
にするということですね。
リディアンドミナント さんが書きました:
エラー C2664 'void *bsearch(const void *,const void *,::size_t,::size_t,_CoreCrtNonSecureSearchSortCompareFunction)':
引数 5 を 'void (__cdecl *)(const void *,const void *)' から '_CoreCrtNonSecureSearchSortCompareFunction' へ変換できません。
このエラーが再現できていませんが、リディアンドミナントさんが使用しているコンパイラは何ですか?
(&ky,[/quote]