Cのパート2の中のポインター


導入


何も言うよりも👋,
ケースでは、バナーでは、この男は、アルゴリズムの概念のKhwarizmiの人である疑問に思います.
今後はもっと高度なシリーズをスタートさせてください.

文字配列とポインタ


char定数を宣言することができます
char a[] = "omar";
char *p  = "omar";
オマルはこのような記憶を見ます
0
1
2
3
4
o
エム
エー
r
\0
\0文字列の終端であるNULL文字です.
**( p + 3 ) <=> p [ 3 ] <=> a [ 3 ]
間の主な違いa and p そのPはその中の値を変えることができません.これがそれらの主な違いです.文字列定数であるため、アクセスできません.
/* strcpy : copy t to s */
void strcpy(char *s , char *t){
    while(*s++ = *t++);
}
この行は、配列をコピーすることができる1行で、驚くべきことです.このような作業は、TからSまでのすべての内容をコピーします.

例1


//what does the following fragment of c-program print
char c[] = "coding";
char *p = c;
printf("%s" , p+p[2]-p[0]);
//output will be : oding
p [ 3 ] - p [ 1 ] = ' d '- ' c ' = ASCIIの違いd and c = 100 - 99 = 1であるので、それはP + 1要素です
0
1
2
3
4
5
6
c
o
ディー

n
ジー
\0

例2


#include <stdio.h>
int main() {
    char a[6] = "world";
    int i,j;
    for(i=0,j=5;i<j;a[i++]=a[j--]);
    printf("%s\n" , a);
}
// output : Null String
配列がこのようなのでNULLです
0
1
2
3
4
5
W
o
r
エル
ディー
\0
それで、配列A [ 0 ] = A [ 5 ]がストリングになるとき
0
1
2
3
4
5
\0
o
r
エル
ディー
\0
私はすでにプログラムが印刷されていることを知っているので、ここで停止することができます.それで、直接出力が停止するので、出力はNULL文字列です.

ポインタと多次元配列の配列


char *name[] = {"omar" , "khatib" , "omarkhatib"};
これは文字へのポインタの配列であることを意味します.

名前の開始アドレスが100であると仮定してください、そして、「Omar」は200です
名前+1は「カティーブ」を指し示すセルである102の外側に立っているようです、そして、*(名前+ 1)は私が値より何もない細胞の中にあるようです.
printf("%s" , *(name+1)); //output : khatib
さあ、このコードの平和を見ましょう
printf("%s" , *name+1); // output : mar
その結果を得る* 会長就任+ それで、それは最初の細胞の中を指します.Then +1 手紙に移るm
printf("%s" , (*(name+2)+7)); //output : tib
また、8番目の要素にアクセスすることができます( 0から始まるのでインデックスは7です).
printf("%c" , name[2][7]); //output : t
このような配列と実装のこの実装の重要な違い
char[3][11] = {"omar" , "khatib" , "omarkhatib"}
0
1
2
3
4
5
6
7
8
9
10
0
o
エム
エー
r
\0
1
ケイ
H
エー
t

b
\0
2
o
エム
エー
r
ケイ
H
エー
t

b
\0
最後の重要な違いは、配列が2 D配列のメモリを占有することです
ポインタの実装は、メモリを無駄にしないので、より多くのメモリを占有します.また、配列ではなくポインタを使ってアクセスするほうが簡単です.
そして、各々の列は、異なるサイズでありえます.

多次元配列、ポインタ、関数


fun(int a[5]);
fun(int a[]);
fun(int *a);

int b[5];
fun(b);
実際にはポインタとして考慮するので、これらの3つは有効です.したがって、配列のサイズを渡さない場合でも、ポインタであるので有効です.
2 Dアレイを通過している場合
fun(int a[5][6]);
fun(int a[][6]);
fun(int *(a)[6])

int b[5][6];
fun(b);
このポインタはこのポインタのように読まれるので有効ですa 6要素の配列を指します.
int (*a)[6];
int *a[6];
それらの2つは、最初の6ポイントへの配列ポイントとして読み込まれます同じです.もう一方は、整数を指すポインタの配列です.

関数へのポインター


これはよく使われるテクニックではなく、このメソッドを使用する良いライブラリはありません.しかし、それはまだCで利用可能です.また、コードを読むことが困難になります.
int sum(int , int);
int *fp(int , int);
( 会長就任* , したがって、2行目はこのように読み込まれます.これは整数へのポインタを返す関数です.
int(*fp)(int , int);
演算子テーブルからc これは右の連想ですので、これを読んでください.*fp は整数としてパラメータとして受け取る関数を指し、整数を返すポインタです.だから、合計のような任意の関数を指すことができます.
int s;
*fp = sum;
s = sum(2,5); // output : 7
s = (*fp)(2,5); // output : 7
別の複雑なもの
void* (*gp)(void * , void *);
int* sum(int* , int*);
gp = (void*(void* , void*))sum;
タイプAポインタを別のポインタにキャストすると、情報が失われることはありません.なぜなら、以前に述べたように、メモリのサイズが同じであるからです.

いくつかの複雑な宣言


a) char **argv
b) int (*daytag)[13]
c) int *daytag[13]
d) void *comp()
e) char (*comp)()
f) char (*(*f()))[])()
g) char (*(*f[3])())[5]
argvは別のポインタを指すポインタである.
daytag 13要素の配列へのポインタ.
c ) daytag整数を指す13要素の配列.
d ) compはvoidポインタを返す関数です.
compはcharを返す関数へのポインタである
f )はcharを返す関数へのポインタの配列へのポインタを返す関数である
fは5文字のポインタを返す関数のポインタとポインタの配列です.