2016-08-27 20 views
1

なぜこのプログラムはpqを出力として生成しますか?配列をポインタとして渡す場合と配列として渡す場合の違いは何ですか?配列とポインタC

#include<stdio.h> 

    void fun(char i[]){ 
    printf("%c,%c", i[1],i[2]); 
    } 
    void fun2(char *i){ 
    printf("\n%c,%c", i,i+1); 
    } 
    int main(){ 
    char ar[] = {"Aba"}; 
    fun(ar); 
    fun2(ar); 
    return 0; 
    } 

出力:

b,a 
    p,q 
+0

'p、q'(連続した文字)を見るには32ビットコンパイラを使用しなければなりません。印刷された値が文字であると「幸運」です。 64ビットシステムを使用していた場合、印刷された文字はそれほど相関がないでしょう。 –

答えて

3

あなたは第二の機能でポインタアドレスのASCII変換を印刷しています。ポインタは*i*(i+1)で逆参照する必要があります。

+0

私はあなたが言ったように、出力は私にAとBを与えます、なぜBの資本も同様ですか? – Tanvi

+0

私は彼の答えを*(i + 1)と*(i + 2)に変更しました。それを変更すれば正しい出力が得られます:) – d3r1ck

+0

@ d3r1ckありがとう! – Tanvi

0

ポインタを配列として渡す方法と の配列を渡す方法の違いは何ですか?

両方の機能、funおよびfun2は、シグネチャが同等です。だから、実際にはfun()という配列を持っていないと思います。 これはC言語で関数に配列を渡すと、最初の要素へのポインタに変換されるためです。

ので、fun2()

printf("\n%c,%c", i,i+1); 

でこの文は文字が、アドレスii+1を印刷しません。そしてあなたが持っている書式に合っていないので、それは正しくありません。私はgccで、あなたのコードをコンパイルすると

、それは警告している:

In function ‘fun2’: 
warning: format ‘%c’ expects argument of type ‘int’, but argument 2 has type ‘char *’ [-Wformat=] 
    printf("\n%c,%c", i,i+1); 
      ^
warning: format ‘%c’ expects argument of type ‘int’, but argument 3 has type ‘char *’ [-Wformat=] 

あなたが見ることができるように、フォーマット指定子とあなたが渡す引数が一致していません。

int fun2(char *i){ 
    printf("\n%c,%c", i[1],i[2]); 
} 
0

あなたは両方の機能に*i*(i+1)またはi[0]i[1]のいずれかを使用する必要があります値を印刷するには:、あなたはちょうどあなたがfun()で行う方法のようにそれを印刷することができますするii+1 ポイントの値を印刷します。 iには、渡した配列の最初のアドレスセルが入ります。どちらの場合も、どちらも住所を渡します。

-1

私の長い答えはここに役立ちますように!

私は整数をとっている、という概念は、任意のデータ型と同じまま:、

オーケーなど、など、配列とポインタのクイック短いレッスン、文字浮かびます。

Thumbルール1:ほとんどの場合、配列とポインタは入れ替え可能ですが、例外があります。 1-Dアレイをとる

、我々はこのようにそれを宣言することができる: -

int arr[10]; 

これは10個の整数要素を保持することができるarrという名前の変数を宣言する。

ポインタ変数を使用して、または配列名(arr)を使用して、この配列を表すためにポインタ表記を同様に使用できます。

Thumbルール2:配列名(1D 2D 3D 4Dの場合)は常にポインタまたはアドレスに崩壊します。

printf ("%lu", arr) //will print out the base address of the array, i.e address of the first element 

ポインタを使用して値を印刷するにはどうすればよいですか?単に、*演算子を使用して逆参照してください。

printf("%d", *arr) //Pointer notation - will print the first value 

別の変数を使用して配列を参照する方法はありますか?

int *ptr = arr; //Pointer notation - just simply write the array name as it decays into an address 

printf("%d", *ptr); //Pointer notation - prints the first element 

多くの人がのint * ptrがは、配列へのポインタであると言います。

実際はそうではありません。実際には、配列ではなく整数へのポインタです。どうして?

まず最初に配列の最初の整数のアドレスを格納しているので、ポインタをインクリメントしてそれをトラバースすることができます。したがって、実際のポインタには整数のアドレス(第1の整数)が格納されています。

次に、2Dアレイに来る: -

宣言: -

int arr[2][3]; // arrays of 2 rows and 3 columns, total 6 elements 

同上ルールが意味: -

printf("%d", arr[0][1]); //prints the second element of the first row. 

printf("%lu", arr) //prints the base address of the 2D array 

ポインタ表記に来る: -

printf("%d", *(*(arr + 0) + 1); // how this works? 

arr cアドレスを保持します。整数を追加すると、その行にジャンプすることができます。

arr + 1 // gives the second row, i.e. arr is currently pointing to the first element of second row. 

さらに整数を追加すると、特定の行の指定された列にスキップされます。

これは、配列名をポインタとして扱うことを選択したときに、言語が与える暗黙のポインタ表記法です。明示的なポインタの表記: - - :今、あなたの問題に来て

をあなたが達成するために何をしようとしているが、ポインタでの2D配列のベースアドレスを格納しています。

これを正しく行うにはどうすればよいですか?

int (*ptr)[3]; //reading it goes like this - ptr is a pointer to a 1D array of 3 ints 

ここで3は、2D配列に含まれる列の数を指定します。

それでは、基本アドレスの最初のの2次元配列(0番目の基本アドレスを意味します)の1D配列をポインタに格納しようとしています。

残りは同じです。

int (*ptr)[3] = arr; // storing the 2D array in ptr 

さて、あなたは通常のポインタとして使用することができます

(ptr + 1) //now ptr is pointer to the Second 1D array of that 2D array or you can say to the second row's first element. 

あなたが関数内の配列をキャッチすることができます別の方法は、このようなものです(ポインタ表記は、それに適用されます): -

私はそれを非常に少なく使用します。

int main() 
{ 
    int arr[2][2]; 
    fun(arr); 
} 

void fun(int catch[][]) 
{ 


} 


// This is simple to understand and as well as to relate. Now, again catch can be used as pointer or as an array. It depends on you :) 

void fun1(int (*ptr)[2]) 
{ 
     //my way 
printf("%d", ptr[1][1]); 
printf("%d", *(*(ptr + 1) + 1)); 

//answer will be the same 
} 

//Ptr now contains that 2D array base address, again can be used as an array or a pointer :)