8

私は次のような機能を持っています

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

ボイドポインターを渡して画面に出力したい場所。上記の例は、i が integer、float、または double の場合は問題ありませんが、i が char の場合はクラッシュします。私が通常C++で使用するようなオーバーロードはCにはありません。したがって、問題はこれです.Cで関数を作成して、そのパラメーターである要素を出力できますか.

4

4 に答える 4

25

Q1:質問はこれです。パラメータである要素を出力する関数を C で作成できますか?

A: ご希望の方法ではありません。関数に情報を渡して、渡すデータのタイプを伝える必要があります。

Q2:はいの場合、どのようにこれが可能なのでしょうか?

A: それができないので、それはあなたを逃れています。void* に関連付けられたメタデータはありません。コンパイラまたはランタイムが、それが指している型を把握するために使用できます。どちらかにする必要があります


  1. ポインターと、ポインターが指すものに関する情報
    (列挙型など)を含む構造体を渡します。
  2. ポインターが指すものに関する情報を含む追加のパラメーターを渡します

コードが立っているので、ここに印刷できるのは i が指すアドレスだけです。

void ポインターは生データを指します。printf は、印刷しているデータ型がわかっていると想定します。これには知性がなく、「それを理解する」ことはできません。

それはとても簡単です。

できることは、関数に型情報を渡すことですが、次の引数でデータに関する型情報を含む書式設定文字列を渡す printf it's self に非常に似たものになってしまいます。

お役に立てれば。

また 。. . " 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){...}
于 2009-01-27T09:25:32.367 に答える
8

まず、ポインタが指しているものではなく、ポインタを出力します。*i実際の内容を印刷するには、printfではなくに渡す必要がありますi

本当にこれを実行したい場合、1つの解決策は次のとおりです。

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 ... */
    }
}
于 2009-01-27T09:30:27.053 に答える
0

だから問題はこれです、それのパラメータである要素を出力するCで関数を作成できますか?

はい、できます。このような関数はすでに標準ライブラリの一部です-それはprintf;)と呼ばれています

Cにはコンパイル時の関数のオーバーロードがないため、実行時に引数の型を指定する必要があります。フォーマット文字列を使用してこれを行うことができるため、printfすでに機能するソリューションがある場合に独自のラッパー関数を作成する理由は実際にはありません。

于 2009-01-27T09:36:20.910 に答える
0

ポインター値を出力しようとしている場合、正しい使い方はprintf("%p", i);です。「d」指定子は整数用で、「p」はポインター用です。これらを正しくするのはあなたの責任であり、それらを混同すると悪いことが起こる可能性があります。

int * ではなく char * でこれが失敗する理由がわかりません。これを引き起こす他の問題が発生している可能性があります。それでも %p で失敗する場合は、別の何かがおかしくなっています。何らかのメモリ モニタ ソフトウェアをインストールして、ダングリング ポインタや二重の free() をチェックできるかどうかを確認してください。

于 2009-01-27T15:03:49.280 に答える