2017-06-14 30 views
1

たとえば、配列があり、指定された値を新しい配列としてこの配列の要素を抽出したいとします。私は、次のとおりにした。Cでポインタを使用して配列の一部を抽出する

int a[10] = { 1, 2, 1, 3, 2, 3, 4, 1, 2, 6 }; 
int i, k; 

int count = 0; 
for (i = 0; i < 10; i++) { 
    if (a[i] == 1) { 
     count = count + 1; 
    } 
} 

int b[count]; 
k = 0; 
for (i = 0; i < 10; i++) { 
    if (a[i] == 1) { 
     b[k] = a[i]; 
     k = k + 1; 
    } 
} 

ので、配列のために「」私は、値1のすべての要素を抽出し、新しい配列「B」としてそれらを作ります。ポインタを使って同じことを達成する方法はありますか?この方法よりもコンシェントになるのだろうか?可能であれば、他の利点はありますか?

+2

あなたは、カウントを知っていれば、特定の指標のうち、抽出する必要はありません。 for(i = 0; i

+0

@EastonBornemeierああ、そうです。ご意見ありがとうございます。 – Syoung

+0

あなたの問題は何ですか?わかりません。 – Stargateur

答えて

3

あなたはすでに、1を数回書く必要があることに気付いたと思います。私はあなたがそれが任意の条件のために働くことを望むと思う。

「ポインタを使用する」とは、可変長配列ではなく動的メモリ割り当てを意味します。ただ、ポインタを使用することのために、あなたがして書くことができます:

int *b = malloc(count * sizeof(int)); 
k = 0; 
for (i = 0; i < 10; i++) { 
    if (a[i] == 1) { 
     b[k] = a[i]; 
     k = k + 1; 
    } 
} 

場合は、あまりにも、書き込み処理のためにポインタを使用するために、次のようにプログラムを適応させることができます:

int *b = malloc(count * sizeof(int)); 
int *bPtr = b; 
for (i = 0; i < 10; i++) { 
    if (a[i] == 1) { 
     *bPtr++ = a[i]; 
    } 
} 

少し助けてくれることを願っています。

3

並べ替えられていない配列全体を特定の値で検索している場合のように、配列のどの部分がターゲット値になるかわからない場合は、ポインタを使用する利点はありません線形検索よりも配列の要素を見つけることができます。

場合は、しかし、あなたは、あなたは物事を単純化するために、ポインタを使用することができ、配列で知られたインデックスで始まる要素の連続したセットにアクセスまたはコピーしようとしています。例えば、私はcharの配列で最後のいくつかの要素の後だ場合は、この作品:

#include <stdio.h> 
int main() 
{ 
    char str[100] = "I don\'t want anyone to think I hate the Calgary Flames"; 
    char *c = (str + 29); 
    printf("%s\n", c); 
    return 0; 
} 

出力:この場合

I hate the Calgary Flames 
2

を、いや、利点はありません。 a[i]は既に基本的にa + (sizeof(int) * i)です。ポインタを使用したとしても、配列の末尾から離れないようにするには、やはりすべてのカウントを行う必要があります。

多くの場合、長さがわからない文字列などのポインタのヌル終端配列が便利です。しかし、実際にはパフォーマンスに関するものではありません。以下に見られるように、彼らはおおよそ同じことをしなければなりません。

char string[] = "foo bar"; 

// Allocate and initialize i. 
// `string + i` twice, compare, increment. 
for(int i = 0; string[i] != '\0'; i++) { 
    printf("%c", string[i]); 
} 
puts(""); 

// Allocate and initialize s. 
// Dereference s twice, compare, increment. 
for(char *s = string; *s != '\0'; s++) { 
    printf("%c", *s); 
} 
puts(""); 

ポインタによる繰り返し処理は、複数の手順で配列を反復処理する必要がある場合に便利です。元の配列のポインタと最後のインデックスを渡す代わりに、関数のシグネチャをすべて変更して、インクリメントされたポインタを渡し、インクリメントされたポインタを返すだけです。これにより、文字列の途中で標準の文字列関数を使用することができます。

#include <stdio.h> 

char *findVal(char *string, char delim) { 
    char *val = string; 
    for(; *val != '\0' && *val != delim; val++) { 
    } 

    if(val == '\0') { 
     return NULL; 
    } 
    else { 
     // val is sitting on the ':' 
     return val+1; 
    } 
} 

int main() { 
    char string[] = "this:that"; 

    char *val = findVal(string, ':'); 
    if(val != NULL) { 
     // Just use val, not string[valIdx]. 
     printf("%s\n", val); 
    } 
} 

これはまた安全です。オフセットには、同期していなければならない2つのもの、つまりポインタとオフセットがあります。誤ったオフセットが誤ったポインタとともに使用される可能性があります。インクリメントされたポインタはそのオフセットを持ちます。


コメントで指摘したように、あなたがそうのような第二のループを引き締めることができます。

int b[count]; 
for (i = 0; i < count; i++) { 
    b[i] = 1; 
} 
関連する問題