2017-07-31 10 views
-4

長い数字を取得し、何桁の数字を数えてから、その数字の2桁目の最後の数字を2倍してから、各数字の掛け算を繰り返すそれを配列に追加します。もしあなたが私が何を話しているのか知っていれば、それはcs50から設定されたクレジットカードの問題です。C - 返された配列が機能しない

私はそれが戻ってこのエラーをスロープログラムを作成する場合:

error: format specifies type 'long' but the argument has type '<dependent type>' [-Werror,-Wformat] 
credit.c:22:21: error: use of undeclared identifier 'array' 
    printf("%ld\n", array); 
        ^
credit.c:40:8: error: incompatible pointer to integer conversion returning 'long [nDigits]' from a function with result type 'long' [-Werror,-Wint-conversion] 
return array; 
     ^~~~~ 
3 errors generated. 
make: *** [credit] Error 1 

コード:

#include <cs50.h> 
#include <stdio.h> 
#include <math.h> 

long find_2ndlast_nums(long x); 

int main(void) 
{ 
    long n; 
    long nDigits; 
    do 
    { 
     n = get_long_long("Please enter your credit card number:\n"); 
     nDigits = floor(log10(labs(n))) + 1; 
    } 
    while (nDigits < 13 || nDigits > 16); 

    find_2ndlast_nums(n); 

    printf("%ld\n", array); 
} 

long find_2ndlast_nums(long x) 
{ 
    long nDigits = floor(log10(labs(x))) + 1; 
    long array[nDigits]; 

    for (int y = 1; y < nDigits; y += 2) 
    { 
     x = (fmod((floor(x/10^y)), 10)) * 2; 
     array[nDigits - y] = x; 
    } 
    return array; 
} 
+0

これは何度も要求されていますが、関数から配列を返すことはできません。あなたは 'malloc()'を使うか、配列を関数に渡してパラメータとして渡す必要があります。 –

+1

あなたの関数は 'long'を返すと宣言され、' long [nDigits] 'を返そうとします。メモリの問題はさておき、なぜこれはうまくいくと思いましたか? – ApproachingDarknessFish

+0

'long find_2ndlast_nums(long x)'では、最初の 'long'が何を意味するのか理解していますか? –

答えて

4

ここで2つの問題があります。

  1. あなたは、アレイ内を宣言する場合Cは[count]型でスタックに割り当てられます。関数が戻るとすぐに、現在のスタックフレームのすべてが無効になるため、このようにスタックに割り当てられた配列を返すことはできません。

  2. この配列を返すことができたとしても、関数はlongへのポインタではなくlongを返すと宣言したので、署名は正しくありません。

私は、mallocを使用してヒープ上の配列にメモリを割り当てることです。関数をポインタを返すとして宣言し、ポインタを配列に返します。残念ながら、呼び出し関数は後でポインタを解放することを覚えておく必要があります。そうしないとメモリリークが発生しますが、これはCを使用しているときに領域に入るものの1つに過ぎません。

このように:あなたは、配列の最大サイズがどうなるか事前に知ることができれば

long *array = myFunc(); 

// do something with array, and when you're done: 

free(array); 

あるいは、あなたは関数がalready-を取り込むことができます:

long *myFunc() { 
    long *array = malloc(count * sizeof(long)); 

    // populate the array 

    return array; 
} 

とクライアントに

割り当てられた配列。これは、あなたのmallocをfreeにして、同じスコープでfreeを行うことで、コードをよりきれいにするという利点があります。また、配列が呼び出し関数を離れる必要がない場合、呼び出し関数は配列をスタックに割り当てて渡すことができるため、mallocとfreeを必要としません。

void populateArray(long *array, size_t arraySize) { 
    // populate array. Don't write more than arraySize objects 
    // or you'll cause a buffer overflow. 
} 
関連する問題