質問

のような機能があります

void printMe (void *i)
{
    printf("%d", i);
}

ここで、void ポインターを渡して画面に出力したいと考えています。上記の例は、i が整数、float、または double の場合は問題ありませんが、i が char の場合はクラッシュします。私が通常 C++ で使用するようなオーバーロードは C にはありません。そこで質問は、パラメータである要素を出力する関数を C で作成できるかということです。作成できる場合、現時点ではまったく理解できないので、どのようにしてこれが可能になるのでしょうか。

役に立ちましたか?

解決

Q1: そこで質問は、パラメータである要素を出力する関数をCで作成できるかということです。

答え:あなたが望む方法ではありません。関数に情報を渡して、渡すデータの種類を伝える必要があります。

Q2: もしそうなら、どうしてそんなことが可能なのか、現時点では私にはまったく理解できません。

答え:それはできないから避けているのです。void* に関連付けられたメタデータはなく、コンパイラーまたはランタイムがそれが指している型を把握するために使用できます。次のいずれかを行う必要があります

  1. を含む構造体を渡します
    ポインタと何についての情報
    ポインタが指しているのは(例:列挙)。
  2. ポインターが指していることに関する情報を追加パラメーターに渡します

コードが現状では、ここで出力できるのは i が指すアドレスだけです。

void ポインターは生データを指します。printf は印刷するデータ型をユーザーが知っていると想定しており、インテリジェンスがなく、ユーザーに代わって「それを理解する」ことはできません。

それはとても簡単です。

できることは型情報を関数に渡すことですが、最終的には printf 自体とよく似たものになり、次の引数でデータに関する型情報を含む書式設定文字列を渡します。

お役に立てれば。

また 。。。」私が通常 C++ で使用するようなオーバーロードは C にはありません"

C++ でもオーバーロードはコンパイル時に発生しますが、ここではコンパイラーがどのデータがその関数に渡されるかを知る方法がないため、たとえオーバーロードに慣れていても、このように動作することはありません (例:printf を使用してこれと同じことを試してください。ただし、C++ コンパイラでコンパイルすると、まったく同じ結果が得られます)。実際に試してみる

cout << i;

上記の関数では、i の「値」ではなく、i が指すアドレスが得られます。値を取得する前に、 i をキャストして推論する必要があります

cout << *(int*)i;

したがって、上記を C++ で動作させるには、多数のオーバーロードされた関数 (または、コンパイラが関数をロールする点を除けば実際には同じであるテンプレート関数) を多数用意する必要があります。オーバーロードされた関数

printMe(int i){...}
printMe(double d){...}
printMe(char c){...}
printMe(char* string){...}

c では、これらの関数に特定の名前を付けるだけで済みます。

printInt(int i){...}
printDouble(double d){...}
printChar(char c){...}
printString(char* string){...}

他のヒント

開始のために、あなたはそれが何を指して、ポインタではなく、印刷しています。実際の内容を印刷するには、*i、ないprintf渡すiする必要があります。

あなたが本当にこれをしたい場合は、一つの解決策はあります:

void printMe (void *p, int typ) {
    switch(typ) {
        case TYP_INT: printf("%d", *((int*)p)); break;
        case TYP_CHR: printf("%c", *((char*)p)); break;
        /* and so on ... */
    }
}
  

そこで質問はこれです、我々はそれが

パラメータだある要素を出力しますCで関数を作成することができます

はい、我々はできます。このような機能はすでに標準ライブラリの一部である - それは呼ばれていますprintf;)

Cでのオーバーロードなしコンパイル時の機能がないので、あなたは何とか実行時に引数のタイプを指定する必要があります。 <=>フォーマット文字列は、これを行うために使用することができ、その作業溶液がすでにあります時に、独自のラッパー関数を構築する理由は本当にありません。

あなたはポインタ値をプリントアウトしようとしている場合は、正しい使用方法はprintf("%p", i);です。 「D」指定子は整数のためである、と「p」はポインタのためです。それは、これらが正しい得るためにあなたの責任だし、あなたがそれらをミックスあれば悪いことが起こることができます。

これはchar型の*はなくint型*のために失敗する理由を私は知らない、あなたがこれを引き起こし、他の問題を持っている可能です。それはまだ%pで失敗した場合、何か他のものはめちゃくちゃしまいました。あなたはその時点でスマートなお金はあなたがどこかのメモリを破損したことだから、ダングリングポインタまたは)(無料ダブルSをチェックするために、メモリモニタソフトウェアのいくつかの並べ替えをインストールできるかどうかを確認します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top