2016-04-06 30 views
2

私は他の記事を読んだことがありますが、私の問題には完全には答えません。 私は本から配列から要素を削除し、そのコードを適用しようとしています。 私が理解できる限り、私は間違った配列を渡しているか、アドレスで整数を送信しています(その背後にある意味は分かりませんでした)。C++で配列から要素を削除する

#include <iostream> 
#include <cstdlib> 
using namespace std; 

void delete_element(double x[], int& n, int k); 

int main() 
{ 
    // example of a function 
    int mass[10]={1,2,3,45,12,87,100,101,999,999}; 
    int len = 10; 

    for(int i=0;i<10;i++) 
    { 
     cout<<mass[i]<<" "; 
    }; 

    delete_element(mass[10],10&,4); 

    for(int i=0;i<10;i++) 
     cout<<mass[i]<<" "; 

    return 0; 
} 

void delete_element(double x[], int& n, int k) 
{ 
    if(k<1 || k>n) 
    { 
     cout<<"Wrong index of k "<<k<<endl; 
     exit(1); // end program 
    } 

    for(int i = k-1;i<n-1;i++) 
     x[i]=x[i+1]; 

    n--; 
} 
+1

「int」と「double」は同じではないことに注意してください。このコードはコンパイルされません。また、C++コードではあまり一般的ではありません。 – unwind

+2

delete_element(質量、len、?);通常は変数で数値を送信しないでください –

+3

配列から要素を "削除"することはできません。配列の値を移動することしかできません。 '10 'は、定義されていない振る舞い(segfaultはせいぜい)を引き起こす、10サイズの配列の11番目の要素にアクセスします。' 10& 'は、半分です。' delete_element(mass [10]、10 &,4); ' (実際には削除することは実際にはできません。要素を削除するには実際には削除できません) – BeyelerStudios

答えて

1

コードにいくつかのエラーがあります。これは、この中に、このような大したことではありませんあなたはそれがC.から継承されますので、任意のオブジェクトの適切なクリーンアップを提供していないexitを呼び出す

  1. :私は、問題の主要な問題のいくつか1-3を強調しましたプログラムですがになります。
    throw std::runtime_error("invalid index");
    とどこかに処理する必要があります:あまりにも、このようなエラーを処理

    一つの適切な方法は、
    cout<<"Wrong index of k "<< k <<endl; exit(1);
    はこのようなものであるべき例外をスローすることです。
  2. あなたがint&を取るとして、関数のパラメータを宣言していますが、このような関数を呼び出す:delete_element(mass[10],10&,4);10&アドレス10を通過しています。代わりに値を渡してください。
  3. 生のC配列から関数を "削除"しています。これは本質的に意味をなさない。そのような配列の一部を実際には削除することはできません。これは、スタック上に作成された一定のコンパイル時間のサイズです。関数自体は削除を行いません。関数の名前をよりタスク指向にするようにしてください。
  4. C-アレイを使用しています。非常に良い理由がない限り、これをしないでください。 std::arrayまたはstd::vectorを使用してください。これらのコンテナは独自のサイズを認識し、ベクトルは自身のメモリを管理し、最小限の労力でサイズを変更できます。コンテナを使用すると、イテレータのサポートのためにSTLの全範囲にアクセスすることもできます。

私は、配列のサイズが固定されているので、あなたは、あなたが配列から要素を削除することはできませんSTLコンテナ

1

15行目:構文エラー あなたは同じように、あなたが参照渡ししたい場合は、最初の変数を作成する必要がある番号& を渡すことはできません。

であなたのdelete_element関数のシグネチャの競合あなたの宣言された配列。 double配列またはint配列を使用して、シグネチャが一致することを確認してください。

delete_element(mass, len , 4); 

あなたは括弧なしで、配列の名前を書くとき、それは&質量と同じです[0] すなわち。最初の要素へのポインタ。

完全な変更は次のようになります。

#include <iostream> 
#include <cstdlib> 
using namespace std; 


void delete_element(int x[], int& n, int k); 

int main(){ 
    // example of a function 
    int mass[10] = { 1, 2, 3, 45, 12, 87, 100, 101, 999, 999 }; 
    int len = 10; 

    for (int i = 0; i<10; i++){ cout << mass[i] << " "; }; 
    cout << endl; 

    delete_element(mass, len , 4); 

    for (int i = 0; i<10; i++)cout << mass[i] << " "; 
    cout << endl; 

    cin.ignore(); 
    return 0; 
} 

void delete_element(int x[], int& n, int k){ 
    if (k<1 || k>n){ 
     cout << "Wrong index of k " << k << endl; 
     exit(1); // end program 
    } 

    for (int i = k - 1; i<n - 1; i++) 
     x[i] = x[i + 1]; 
    n--; 
} 
0

プログラム中のミスがいくつかあります。 int配列をdouble配列を必要とする関数に渡そうとする構文上の問題以外に、

intリテラルの左辺参照を渡すことはできません。あなたが望むのは、int配列の長さの参照を渡すことです。 http://en.cppreference.com/w/cpp/language/referenceも参照してください。

ここには、プログラムのアップデート版があります。

#include <iostream> 
#include <cstdlib> 

using namespace std; 

void delete_element(int x[], int& n, int k); 

int main() { 
    // example of a function 
    int mass[10] = { 1,2,3,45,12,87,100,101,999,999 }; 
    int len = 10; 

    for (int i = 0;i < len;i++) 
    cout << mass[i] << " "; ; 
    cout << endl; 

    delete_element(mass, len, 4); 

    for (int i = 0;i < len;i++) // len is 9 now 
    cout << mass[i] << " "; 
    cout << endl; 

    return 0; 
} 

void delete_element(int x[], int& n, int k) { 
    if (k<1 || k>n) { 
    cout << "Wrong index of k " << k << endl; 
    exit(1); // end program 
    } 

    for (int i = k - 1;i<n - 1;i++) 
    x[i] = x[i + 1]; 
    n--; 
} 
0

あなたの質問に直接答えはしませんが、C++を使って簡単に問題を解決する方法をお見せしたいと思います。

#include <vector> 
#include <iostream> 

void delete_element(std::vector<int>& v, const unsigned i) 
{ 
    if (i < v.size()) 
     v.erase(v.begin() + i); 
    else 
     std::cout << "Index " << i << " out of bounds" << std::endl; 
} 

int main() 
{ 
    std::vector<int> v = {1, 2, 3, 4, 5, 6, 7}; 
    delete_element(v, 4); 

    for (int i : v) 
     std::cout << i << std::endl; 

    return 0; 
} 
+0

@BeyelerStudiosのために調整されているので間違いはありません。それはもちろん良い議論ですが、私は新しいプログラマーに、C++ではなくC++で作業していることを直ちに認識させることを非常に支持しています。しかし、あなたは正しいです、私はあなたのコメントを満たすために私の答えを編集しています。 – Chiel

0

のいくつかの種類を実装し、コードを書き換える示唆しています。これを考えると、delete_elementの実装は、適切なアルゴリズム関数std::copyを1回呼び出すだけで実行できます。

さらに、1ベースの値ではなく、0ベースの値を削除することを強くお勧めします。

別の注記:don't call exit() in the middle of a function call

#include <algorithm> 
//... 
void delete_element(int x[], int& n, int k) 
{ 
    if (k < 0 || k > n-1) 
    { 
     cout << "Wrong index of k " << k << endl; 
     return; 
    } 

    std::copy(x + k + 1, x + n, x + k); 
    n--; 
} 

Live Example removing first element

std::copy呼が宛先範囲(kの要素)に(k後素子とnで表さ最後の項目()によって定義される)ソース範囲から要素を移動させます。宛先がソース範囲内にないため、std::copyコールは正しく機能します。

関連する問題