第13章:高度なポインタトピック
GitHub
リンク:ch13。高度なポインタトピック
ポインタは、C
エッセンス、ポインタ、メモリ接続のほとんどの言語であり、適切に比較可能なコンパイルを使用しています!!!
この章の内容は、繰り返し学習する価値があります。情報を確認し、読みを比較してください。
この章の要約と注意点
いくつかの放課後の演習への回答
13.9問題
-
非常に強い質問です。
d,e,g,i,j,l
脳が機能していないときにやっていたのは間違っていた...恐れ -
すべてのポインタ演算と同様に、値1は、ポインタが指すオブジェクトのサイズ(この場合は文字へのポインタ)にスケーリングされます。結果は
ptr
、配列内の次の要素、つまりptr+1=&array[1]
。実際、ptr
配列名array
は同等です。一次元配列のように、ptr+1
それだけarray[1]
です。を参照してくださいdemo01.c
。 -
3レベルのポインタのみ。参照回答を参照してください:
-
ローカル変数の預金
trans->product
が考えることができると宣言しますが、それはまた登録します...回答を参照してください: -
最初は質問の意味がわかりませんでした。それは正当性を判断することであることが判明しました。これは
e、f、h~k
、それは違法です。まず、それが構造体へのポインタでp
ある構造体であることを理解しa
ます。焦点はb
、構造体へのポインタではなく、内部メモリの構造体へのポインタへのポインタであり、a
アドレス指定されます。矢印を直接使用して構造体ポインタメンバーにアクセスすることはできません。それb
自体は構造体を指しておらず、*b
格納されているのは構造体へのポインタであるためですが、優先度の高い->
ものよりも注意が必要*
です。これに基づいて、上記のエラーオプションは非常に明確であり、サンプルコードを見ることができますdem02.c
。参照回答を参照してください: -
明らかに間違っています。前記
b
型が一致しない、a
ポインタがy
ありません。d
上記と同じ理由で、タイプの不一致もあります。 -
利点とトピックはすべて言及されています...コマンドラインパラメータのヘルプ。しかし、この機能が標準にないという事実は、その移植性が悪いことを意味します!
-
明らかに、文字列定数の値はどのように変更できますか?正しく
SE
ああ。文字配列を使用して実行する必要があります。 -
配列の初期値を保持し、さらに何かを追加するだけで、メモリオーバーフローが発生し、他の変数がカバーされ、
UB
動作が発生します。この状況を回避するために配列のサイズを拡張するか、事前に判断することしかできません。答えはまた、潜在的な問題はstrcat
、パス名プレフィックスをいくつかの異なるファイル名で使用する必要がある場合の使用でありstrcat
、次の追加でファイル名が望ましい結果を生成しないことにも言及しました。つまり、プレフィックスを直接変更し、共有しませんでした... -
まだオーバーフローの問題があります。場合は
filename
、文字列の長さが9つの文字を超える、配列がオーバーフローします。より大きなものに適用するか、動的にメモリに適用します。
13.10プログラミング演習
-
よく知られている問題は
P188 ch09 9.14
、最初の質問をプログラミングしてから、if-else
doを使用して文字分類関数を実行することです。この段階では、転送テーブルを使用して実行します。これは非常に良い習慣の問題です。この問題は大幅に拡大する可能性があります。テーブルの転送方法は非常にエレガントで簡潔です。関数ポインタの配列を転送テーブルとして初期化し、マクロ定義のサイズを見つけ、印刷可能な文字を使用して印刷不可能な文字を反転させて判断します。これは非常に良い質問です。printf()
出力関数%
Shiは%%
、エスケープする必要があることに注意してください。を参照してくださいdemo03.c
。 -
実際、コールバック関数を絡める必要はありません。直接呼び出すことはできませんか?コールバック関数は、関数ポインタを渡すだけで、関連するタイプを指定するだけです。参照回答:この関数は、リストを自分で反復するのが一般的な関数を呼び出すのとほぼ同じくらい簡単であるため、特に有用ではない場合があります。一方、この例には、この演習を正当化するのに十分な価値があります。関数はリンクがノード構造のどこにあるかを知る必要があるため、結局のところそれほど用途が広いわけではないことに注意してください。を参照してください
demo04.c
。 -
このフォントは本当に不快に見えます。参照回答を直接参照してください。直接機能する場合がいくつかあります。このコードは関数に移動する必要があります。ここでの主な難しさは、必要なすべての機能要件を満たすことができる一般的なプロトタイプを考え出すことです。これには、任意の関数で使用されるすべてのパラメーターが含まれている必要があります。新しい関数はパブリックプロトタイプを使用する必要があり、既存の関数はそれに一致するように変更する必要があります。ほとんどの関数は、必要のないパラメーターを少なくとも1つ持つことになります。
current
対応する関数を変更できるように、ポインタをに渡す必要がありますi
。このソリューションは、元のコードよりもはるかに長いことに注意してください。これは主に、コード行を実行するタスクの関数を作成するオーバーヘッドが原因です。ただし、トランザクション数の増加に伴い、個別のトランザクション結合を使用すると、関数ジャンプテーブルはswitch
より管理しやすいステートメントよりも大きくなります。を参照してくださいdemo05.c
。 -
sort()
並べ替え、主題の要件は、非常に美しい、任意のタイプに並べ替えることができます。InP344
にqsort()
は関数プロトタイプがあり、これには実質的に一致する必要があります。回答:この関数ANSI C
は、ライブラリqsort
関数で提供されている例に従います。唯一の2つのトリックは、各配列要素の開始位置を見つけて、2つの要素を交換することです。要素の長さは、これら2つのタスクに使用されます。しかし、その3番目のパラメーター:各配列要素の長さああ...
qsort()
プロトタイプに見えてオリジナルを使用するとはどういう意味sizeof(类型)
ですか?これもさまざまなタイプのデータとしてカウントできますか?この模擬質問はスキップすることをお勧めします。を参照してくださいdemo06.c
。 -
私はもう書きたくありません、これは何を言いますか。回答を参照してください。よくある間違いは
argv
、ポインターまたはパラメーター自体のリストを変更することです。このソリューションは、レジスタ宣言を使用して効率を向上させます。argtype
関数は1つの場所から呼び出され、わかりやすくするために、別の関数として記述されています。を参照してくださいdemo07.c
。
エッセイ
この時点でC
は、ポインタの半分以上ですが、明らかにこの本は単純なエントリレベルについて説明しています。十分な例がなく、例が少なく、コードが少なく、概念にとどまり、少量demo
です。しかし、残りは本当にあなた自身のビジネスであり、より多くの練習をタイプし、より多くのオープンソースプロジェクトを読み、それらのコードスタイルとプログラムデザインを観察します。一般的に使用されるマルチレベルポインタ、コールバック関数などを含みます。正直なところ、第2レベルのポインターやコールバック関数を使用することはめったにありません。一般に、コードの量は比較的少なく、それらのほとんどはブラッシングアルゴリズムの問題です。しかし、この執筆はエンジニアリングの実践における最優先事項です。
この章は一定期間後にレビューされ、詳細な要約が作成されます。この章では、関数ポインター、ポインター関数、配列ポインター、およびポインター配列の概念が対比されておらず、印象が十分に深くありません。
疑問に思う
-
P258-P260
の高レベルの宣言部分、特に間接アクセス演算子と関数呼び出し演算子および添え字表記。注意深く区別する必要があります。添え字の優先度は間接アクセスよりも高く、関数呼び出しは間接アクセスよりも高くなります。次のいくつかの例と説明を慎重に分けてください! -
関数ポインタ。関数名を使用すると、コンパイラーによって常に関数ポインターに変換されます。関数ポインタインタビューでテストされました!!!コールバック関数と転送テーブルに注意してください。コールバック関数はあまり使用されておらず、質問が多くなっています。転送テーブルは理解しやすいです。これは配列であり、そこに格納されているのはすべて関数ポインタです。関数ポインタの配列です。
-
問題のコマンドラインパラメーターと
main()
関数パラメーター。実際、標準main()
関数はすべてパラメーターであり、通常はパラメーターを渡しませんが、前のセクションで言及したように、C
言語の以前のバージョンでは、関数プロトタイプは正式なパラメーターを記述する必要がないため、あいまいになりました。したがって、一般的に言えば、正式なパラメータを渡すことができますvoid
。 -
文字列定数は式にあり、その値はポインタ定数です。これは非常に優れた知識です。以前に知乎で見た投稿:各数字の中央に「、」をインテリジェントに追加するにはどうすればよいですか?その中でも、高い評価の答えは、単にエレガントで美しいです!!!フォーマット文字列定数ポインタ+オフセット
printf(",%d" + !i, a[i]);
i
を使用してprintf()
、配列全体を0からトラバースし、非常にエレガントにこのタスクを完了します。!!完璧です。