質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Q&A

解決済

2回答

1093閲覧

関数でのポインタ渡しについて

tentative_user

総合スコア1

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

0グッド

1クリップ

投稿2021/04/29 13:15

編集2021/04/29 13:24

疑問点

C言語のポインタを学習しているものです。こちらのサイトのコードで疑問に
感じた箇所があるのでお伺いします。

配列中に指定した数字がどこに入っているか調べる関数でポインタ渡しを使っているのですが、
整数を扱っているにもかかわらず、実引数で渡すアドレスがなぜかcharとして取り扱われています。

この理由がなぜか教えていただけますでしょうか。

コードに書いてあるコメントでは

Since char takes one byte, we can use char pointer for any type

と書いてあるのですが、charが1byteだと整数を扱っていい意味が分かりません。。。

該当のソースコード

C

1#include <stdio.h> 2#include <stdbool.h> 3 4bool compare (const void * a, const void * b){ 5return ( *(int*)a == *(int*)b ); 6} 7 8int search(void *arr, int arr_size, int ele_size, void *x, 9 bool compare (const void * , const void *)){ 10 11 char *ptr = (char *)arr; // <- ここでなぜcharとして扱われているかが不明 12 13 int i; 14 for (i=0; i<arr_size; i++) 15 if (compare(ptr + i*ele_size, x)) 16 return i; 17 18 // If element not found 19 return -1; 20} 21 22int main(){ 23 int arr[] = {2, 5, 7, 90, 70}; // <- 取り扱う対象は整数 24 int n = sizeof(arr)/sizeof(arr[0]); 25 int x = 7; 26 printf ("Returned index is %d ", search(arr, n, 27 sizeof(int), &x, compare)); 28 return 0; 29} 30

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

intの配列からintの値を探す機能限定なら、char *ptr;は不要で

C

1int search(int *arr, int arr_size, int *x, 2 bool compare (const int * , const int *)){ 3 4 int i; 5 for (i=0; i<arr_size; i++) 6 if (compare(arr + i, x)) 7 return i; 8 9 // If element not found 10 return -1; 11}

ですね。
元の関数は、int型だけじゃなくて、charとかshortとかdoubleとかあるいはstructとかどんなサイズの型でも対応できるように、1バイト型であるcharへのポインターを使って、要素のサイズ分(ele_size)ずつ加算するようにしてあります。
ptrという別変数を用意せず、(char*)arrとキャストして使うだけで十分だと思いますが)

投稿2021/04/29 14:30

otn

総合スコア85901

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tentative_user

2021/04/30 01:17 編集

ご回答ありがとうございます。 確認で重ねて質問よろしいでしょうか。 (char *)ptr = (char *)arrのコードがあることで、if (compare(ptr + i*ele_size, x)) でポインタ変数がcharのサイズである1byteずつ動かすことでができる。 ここで例えば(int *)ptr = (int *)arrとおいてしまうとintのサイズである4byteずつ動いてしまう。 。。。という認識でよろしいでしょうか 参考:http://www.nurs.or.jp/~sug/soft/tora/tora5.htm
otn

2021/04/30 12:32

そうですね。 char *ptr; だと、ptr + i*ele_size は、ptrに入っているアドレスに、i*ele_size*sizeof(char)の演算結果を足したアドレスを意味しますが、 int *ptr; だと、ptr + i*ele_size は、ptrに入っているアドレスに、i*ele_size*sizeof(int)を足したアドレスを意味しますので、サイズを2回掛けることになってしまいます。 intのみ扱うなら、int *ptr; で、ptr + i と書けば良いのですが、intと異なるサイズのデータを扱えません。
guest

0

ここでなぜcharのサイズ分だけ渡しているのかが不明

ってのがそもそも間違ってます
ele_sizeってのはどういう値なのかをよく見てください


質問が編集されたんで追記

ここでなぜcharとして扱われているかが不明

void* では扱いようがないからです。
なので、char*の変数に代入してますね

投稿2021/04/29 13:24

編集2021/04/29 13:36
y_waiwai

総合スコア88042

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tentative_user

2021/04/29 13:35

早速のご回答ありがとうございます。 if (compare(ptr + i*ele_size, x)) の中で、i*ele_sizeが配列を整数一個ずつ動かすというのはわかるのですが、ptrが char *ptr = (char *)arr; でcharポインタ型で宣言されている理由がわかりかねてます。 main関数中ではarrはもともとint配列だったのでintポインタ型でやるのが直感的に思ったのですが この理解は間違ってますでしょうか。。。
y_waiwai

2021/04/29 13:39

void* のポインタでは加算減算できません そのために、char* としてます。 提示のmain内では、intのポインタでどーこーしてますが、 これがshortのポインタでどーこ~したいときはどうしましょ。 long のポインタでは? その場合でも対応できるようになってるってのを読み取りましょう
tentative_user

2021/04/29 14:26

理解が追い付かず、申し訳ありません。。。 char *ptr = (char *)arr;の様にするとintやshortでもlongでも対応できるのはなぜでしょうか。 私の認識ではchar *ptr = (char *)arr;でptrにarrのアドレスが代入されると思っているのですが、ここでcharを使うと汎用的に様々な型が使える理由が正直まだ理解できておりません。 何度も質問してしまい、申し訳ありません
y_waiwai

2021/04/29 14:29

そのための仕組みが、 ptr + i*ele_size の演算です。 ele_sizeってのはどういう値なのかをよく見てください (再
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問