0

この質問に対する簡単な答えがあることを願っていますので、しばらくお待ちください。CヘッダーファイルがTYPEを次のように定義している場合:

struct Example {
    char description[EXAMPLE_DESC_SIZE];    
    int val;                          
};

typedef struct Example Example;

# ifndef TYPE
# define TYPE      Example
# define TYPE_SIZE sizeof(Example)
# endif

次に、.c ファイルには、次のような関数があります。

TYPE createExample (int val, char *desc) {
}

メインから次のように呼び出されます

TYPE newEx;
char desc[EXAMPLE_DESC_SIZE], filename[50], *nlptr;
int val;

newEx = createExample(val, desc);

TYPE を返すように createExample をコーディングするにはどうすればよいですか? 私は次のことを試しました(および他のいくつかの失敗した試み):

TYPE createExample (int val, char *desc)
{
    TYPE temp;
    struct Example example;
    example->val = val;
    strcpy(example->description, desc);

    return temp = example;
}
4

3 に答える 3

2

質問が変わったので、答えを少し変更します。

基本的に TYPE 定義は正しく、コードも正しいです。唯一間違っているのは in のインスタンスの使用ですexample:createExampleスタック変数を宣言しているので、フィールドにアクセスするために "->" 演算子を使用してはなりません。「.」を使用する必要があります。オペレーター。したがって、フィールドへの正しいアクセスvalexample.val = val. それがあなたのコンパイラがあなたに伝えるものです

'->' の型引数が無効です。

まだ

struct Example {
    char description[EXAMPLE_DESC_SIZE];    
    int val;                          
};

typedef struct Example Example;

に短縮できます

typedef struct Example {
    char description[EXAMPLE_DESC_SIZE];    
    int val;                          
}Example;

また、構造体を値で返すことが良い考えかどうかを検討する必要があります。これは、毎回スタック領域との間で構造体をコピーすることを意味するためです。構造体のサイズによっては、状況によってはスタックが壊れる可能性があります。たぶん、動的割り当てとポインタの受け渡しについて考える必要があるかもしれません。

于 2013-02-24T00:13:48.693 に答える
1

->の代わりに aを使用するという単純な問題のよう.です。

->はポインタ用なので、もしあれTYPE *temp->.

これはうまくいくはずです:

TYPE createTask (int val, char *desc)
{
    TYPE temp;
    temp.val = val;
    strcpy(temp.description, desc);
    return temp;
}
于 2013-02-24T00:12:59.877 に答える
0

TYPE反論:特定の名前の代わりに一般的な名前を使用したいのはなぜExampleですかstruct Example? 特定の名前に固執する方がよいでしょう。それ以外はすべて、条件付きで を定義する別のヘッダーがあるTYPE場合、どのヘッダーが最初に含まれるかによって、非常に奇妙な結果になります。

pro temを使用することを受け入れるとTYPE、関数に必要な変数は 1 つだけtempですexample。これらのいずれかが機能し、意味があります。

TYPE createExample(int val, char *desc)
{
    struct Example example;
    example.val = val;
    strcpy(example.description, desc);

    return example;
}

->からへの変更に注意してください.。構造体へのポインタではなく、ローカル構造体を扱っています。

TYPE createExample(int val, char *desc)
{
    TYPE temp;
    temp.val = val;
    strcpy(temp.description, desc);

    return temp;
}

個人的には、私は見たいと思っています:

Example createExample(int val, char *desc)
{
    Example example;
    example.val = val;
    strncpy(example.description, desc, sizeof(example.description)-1);
    example.description[sizeof(example.description)-1] = '\0';
    return example;
}

表記上、これは全体で typedef 名を使用しますExample。を使用する場合はstruct Example、typedef を気にしないでください。

もう 1 つの変更により、初期化によってバッファ オーバーフローが発生しないことが保証されます。このようなバッファ オーバーフローを防止することは、この段階では少し奇妙かもしれませんが、非常に慎重です。他にも次のような方法があります。

size_t len = strlen(desc);
if (len >= sizeof(example.description))
    len = sizeof(example.description) - 1;
memmove(example.description, desc, len);
example.description[len] = '\0';

私はおそらくこれを使用します。直感に反するいくつかのプロパティがstrncpy()あり、理想的ではありません (特に、null 終了は保証されませんが、ソース文字列がはるかに短い場合でも、ターゲット バッファー内のすべてのバイトを (指定された長さまで) 上書きすることが保証されます)。ターゲット バッファより)。

于 2013-02-24T00:49:00.367 に答える