bsearchの使い方が分かりません

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
リディアンドミナント
記事: 8
登録日時: 2年前

bsearchの使い方が分かりません

#1

投稿記事 by リディアンドミナント » 2年前

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;
}

Math

Re: bsearchの使い方が分かりません

#2

投稿記事 by Math » 2年前

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 スキップ ==========
となりますね。

リディアンドミナント
記事: 8
登録日時: 2年前

Re: bsearchの使い方が分かりません

#3

投稿記事 by リディアンドミナント » 2年前

Mathさん
ありがとうございます。
とりあえず問題は解決しました。
C拡張子では動くけど、C++拡張子では動かないという認識ですね。
C++では使えない(?)ようですね。
最後に編集したユーザー リディアンドミナント on 2017年7月18日(火) 22:46 [ 編集 1 回目 ]

Math

Re: bsearchの使い方が分かりません

#4

投稿記事 by Math » 2年前

その通りですね。
C と C/C++(拡張CとC++) は微妙に違いますね!

アバター
みけCAT
記事: 6149
登録日時: 8年前
住所: 千葉県
連絡を取る:

Re: bsearchの使い方が分かりません

#5

投稿記事 by みけCAT » 2年前

リディアンドミナント さんが書きました:C拡張子では動くけど、C++拡張子では動かないという認識ですね。
C++では使えない(?)ようですね。
Math さんが書きました:その通りですね。
その通りではありません。
「明示的なキャストが必要です。」とあるので、それに従って明示的なキャストを書けば使えるはずです。
リディアンドミナント さんが書きました: エラー C2664 'void *bsearch(const void *,const void *,::size_t,::size_t,_CoreCrtNonSecureSearchSortCompareFunction)':
引数 5 を 'void (__cdecl *)(const void *,const void *)' から '_CoreCrtNonSecureSearchSortCompareFunction' へ変換できません。
このエラーが再現できていませんが、リディアンドミナントさんが使用しているコンパイラは何ですか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Math

Re: bsearchの使い方が分かりません

#6

投稿記事 by Math » 2年前

>「明示的なキャストが必要です。」とあるので、それに従って明示的なキャストを書けば使えるはずです。
勿論そういう意味では使えるわけですがVisualStudioではC用にかかれたProgramがそのままではC/C++で動かないという意味ですね。

かずま

Re: bsearchの使い方が分かりません

#7

投稿記事 by かずま » 2年前

みけ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の使い方が分かりません

#8

投稿記事 by かずま » 2年前

すみません。まちがって送信してしまいました。
みけ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
に変更すると、再現できます。

最初の質問のソースとエラーメッセージの対応が間違っているものと思われます。

リディアンドミナント
記事: 8
登録日時: 2年前

Re: bsearchの使い方が分かりません

#9

投稿記事 by リディアンドミナント » 2年前

みけCATさん、かずまさん返信ありがとうございます。

ややこしくしてしまって、すみません。
かずまさんの言うとおり、私はvoid(*)でキャスト変換して、コンパイルしてそのままエラーを掲示してしまいました。
質問項目2のプロセスで記載すべきでした。

みけCATさん
私が使ってるコンパイルは、visual studio2017Community
新規作成->プロジェクト->visual C++->win32コンソールアプリケーション
です

最初のエラーはこれでした。
(アクティブ) E0513 型 "void *" の値を型 "int *" のエンティティに割り当てることはできません

最終的には、
Mathさんが言ってるように、VisualStudioではC用にかかれたProgramがそのままではC/C++で動かないという認識でいいのでしょうか…。

結城紬
記事: 42
登録日時: 2年前

Re: bsearchの使い方が分かりません

#10

投稿記事 by 結城紬 » 2年前

リディアンドミナントさん

Visual C++ に限った話ではなく、C++ は細かい仕様が C から変わっているため、そのままではコンパイルできないことはよくあることです。
今回の問題は void* の扱いが異なることが原因です。
C では void* は他のポインタ型(今回の場合、 int* )へ勝手にキャストされていましたが、
C++ では void* 型は勝手にキャストされなくなり、明示的に (int*)bsearch(... のようにキャストする必要があります。
特に C では malloc の戻り値をキャストしない人が多く、C++ への移行時に問題になりやすい部分です。

リディアンドミナント
記事: 8
登録日時: 2年前

Re: bsearchの使い方が分かりません

#11

投稿記事 by リディアンドミナント » 2年前

結城紬さんありがとうございます。
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++ への移行時に問題になりやすい部分です。
最後に編集したユーザー リディアンドミナント on 2017年7月18日(火) 23:07 [ 編集 1 回目 ]

リディアンドミナント
記事: 8
登録日時: 2年前

Re: bsearchの使い方が分かりません

#12

投稿記事 by リディアンドミナント » 2年前

かずまさんも同じようなソースになってますね。
参考になりました。
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]

返信

“C言語何でも質問掲示板” へ戻る