この記事では、組み込みC言語、通称「生意気操作」の高度な知識をお伝えし、より高いレベルのスキルアップに役立てていきたいと思います!

編集元: https://mp.weixin.qq.com/s/42Fxs8rDf2rQ8YR8db74xw

教師の Yu Zhennan は、2005 年からすでに ACM (ACM ICPC Northeast China Division) と呼ばれる規模の国際プログラミング コンテストに参加し始め、非常に良い成績を収めていました。多くの人が C 言語を始めたばかりの時点で、すでに C 言語のレベルは比較的深いことがわかります。

以下は、オンライン記事「My University」シリーズのジェンナン先生の一節から引用したものです (Zhihu からの抜粋)。

ACMはまさに力と戦略の勝負であり、人生の原則がたくさん詰まっていますが、私が学んだ一番大切なことは「頑張れば勝てる」ということです!
私たちはこれまでと同様に一致団結し、ACMがさらに前進できるよう全力を尽くしていきます。これまで部大会や学校大会を開催してきましたが、近い将来、ACMを全省、全国、さらには世界へと広めていきたいと考えていますが、これには当然、数世代の協力が必要です。

ジェンナン先生の記事「私の大学」に対するオンラインのコメント(Zhihuから抜粋):

ホストは湖北省出身で、大学を6年卒業しています。大学を振り返ると、郭天祥氏と余振南氏が最も影響力のある人物です。私の大学生活を素晴らしいものにしてくれたのは、この2人の素晴らしい経験と学習指導です。 2010年のシーンを振り返ると、大きな感慨と感謝の気持ちが湧いてきます。また、私自身はうまくできませんでしたが、後者が大学で一生懸命勉強し、大学での楽しい時間を無駄にしないことを願っています。

教師の Yu Zhennan 氏と Guo Tianxiang 氏が、あらゆる人向けに多くの古典的なビデオ コースを録画し、多くの人々がマイクロコントローラーや組み込みシステムの分野を始めるきっかけになったことを私たちは知っています。しかし、長年にわたって、Yu Zhennan 教師が体系的に記録した C 言語コースを見たことがありません。

先生にこの質問をしたところ、「C言語を20年使ってきましたが、自分にはC言語の講座を教える資格がないとずっと思っていました。今まで勇気を出して記録しておきました」とのこと。一連のコース「組み込み C 言語の頂点への登頂 (マスター C)」は、皆様のお役に立ちたいと願っています。皆様の C 言語レベルをさらに別のレベルに引き上げるのに役立ちます

以下は、Yu Zhennan 先生の新刊『Zhennan Technology Records – Ten Years Past』の一章で、先生は C 言語の 26 の高度な知識とスキルを私たちに説明してくれました。(著作権はYu Zhennan先生から許可されています)

第2章「C言語のちょっとした“エッチな操作”とその深い理解」

1. 文字列の本質はポインタです

(35 を対応する 16 進文字列「0X23」に変換するにはどうすればよいですか?)

2. エスケープ文字\

(文字列の中に「スパイ」と入力します。)

3. 文字列定数の接続

(文字列定数は両面テープですよ?)

4. 長い文字列の分割テクニック

(GPS データ フレーム NMEA、シェル コマンド ライン、および AT コマンドの分析は、長い文字列分割の典型的なアプリケーションです。)

5. 数値を巧みに計算して得られる数字

(多桁デジタル管を演奏する場合には必須の操作です。)

6. printfの本質と活用術

(printf についてよく知っていると思いますか? 3 つの UART に印刷したことはありますか? または LCD 画面に印刷したことはありますか?)

7. 浮動小数点数の送信について

(浮動小数点は単なる幻想です。その本質を見てください。)

8. データの直接操作

(浮動小数点数の逆、-1.0 を掛ける方法をすばやく計算するにはどうすればよいでしょうか? もう一度考えてください。)

9. 浮動小数点の丸めと比較

(先生は浮動小数点は直接評価できないと言っていました。なぜですか?)

10. 素晴らしい for ループ

(for ループについてはご存知ですか? OK、Zhennan がいくつか質問しました。試してみましょう。)

11. 隠された無限ループ

(私たちは光の中にいますが、無限のサイクルは時には暗闇の中にあります。)

12. 一見冗長に見える空のループ

(無駄なこと?)

13. 独立した執行機関

(この概念を C 言語で学んだことがありませんか?そうです、私はよく使います。)

十四、多用途()害なし

(括弧で囲むこともできます。)

15. == の逆テスト

(間違って == と書くと、血を吐くようにプログラムを調整できます。)

十六、代入演算の本質

(数学教授を人生の半分混乱させた C 言語の代入操作)

17. 補完コードについて

(これは対決であり、CPU は実際には引き算を行いません。)

18.-1について

(-1 はすべて F であり、すべての F は -1 です。)

20. バイトファーストビット逆順

(時間と空間の相互変換 – コンピュータにおける相対性理論)

21. 揮発性について

(最適化できないものもあります。)

22. 変数交換について

(素晴らしいビット操作です。)

23.sizeofについて

(あまり注目されていない sizeof の問題について説明します。)

24. memcpyの効率

(小さな機能にも大きな背景があります)

25. []の本質

([] は単なる配列の添字だと思いますか?)

26、# および ## (シリアル化と接続)

(C言語の教科書には載ったことのない知識)

C 言語は、非常に柔軟で強力なプログラミング言語です。同じアルゴリズムや関数でも、公平な方法で書くこともできますし、曖昧な方法で書くこともできます。また、自分をプログラミングの達人だと思っている人の多くは、他人には理解できなくても正しい機能を実現できると考え、バイブルとしてプログラムを書くことを好みますが、これは優れたスキルの証です。人にはそれぞれ独自のスタイルと個性があるため、このアプローチが望ましいかどうかについてはコメントしません。彼の意志に反してプログラミングをさせると、プログラミングは退屈で楽しくなくなる可能性があります。私が言いたいのは、あるスタイルでプログラムを書くには資本と C 言語の深い理解が必要であるということです。多くの場合、理解するのが難しいプログラムを書きたいのではなく、他の人のプログラムを理解したいのです。この章では、Zhennan が私が見たり使用したりしたいくつかのプログラミング テクニックを列挙し、詳細な分析を提供します。

ご興味がございましたら、Web サイトに登録してチュートリアルをご覧ください。

[外部リンク画像の転送に失敗しました。ソース サイトにはリーチ防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-B0IypvpF-1693141960058)(https://mmbiz.qpic.cn/sz_mmbiz_jpg/2ibmcljDoyWT5FJVUVQdKSJ81Mia1ds4jzSIpSnJekAibvib08GIoEd) N8ZHr VeKQe7DzPWiaQJUcXAwVlDlyiagZs7EQ/640?wx_fmt=jpeg&wxfrom =5&wx_lazy=1&wx_co=1)]

1. 文字列の本質はポインタです

文字列は C 言語の最も基本的な概念であり、最も一般的に使用されます。組み込み開発では、プログラムの実行ステータスを理解できるように、情報プロンプトとしてシリアル ポートを介してシリアル ポート アシスタントまたはデバッグ端末に文字列を表示したり、一部の定数の値を変換したりする必要があることがよくあります。 LCD などの表示デバイスに表示される文字列。

では、C言語における文字列とは一体何なのでしょうか?実際、文字列自体はポインタであり、その値 (つまり、ポインタが指すアドレス) は文字列の最初の文字のアドレスです。

この問題を説明するために、私はよく例として、値を対応する 16 進文字列に変換する方法を示します。たとえば、100 を「0X64」に変換します。

次のような関数を書くことができます。

void Value2String(unsigned char value,char *str)

{

unsigned char temp=0;

str[0]='0';str[1]='X';str[4]=0;

temp=value>>4;

if(temp>=0 && temp<=9) str[2]='0'+temp;

else if(temp>=10 && temp<=15) str[2]='A'+temp-10;

temp=value&0X0F;

if(temp>=0 && temp<=9) str[3]='0'+temp;

else if(temp>=10 && temp<=15) str[3]='A'+temp-10;

}

問題ありません。機能は正常です。実装上、ASCII コードの値では 0 ~ 9 と A F が連続していないため (それぞれ0X30 0X39 と 0X41 0X46 )、プログラムは 9 を境界としてその都度処理を行います。

しかし、賢明なプログラマーは、この方法を使用して次のことを実現する可能性があります。

void Value2String(unsigned char value,char *str)

{

char Hex_Char_Table[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

str[0]='0';str[1]='X';str[4]=0;

str[2]=Hex_Char_Table[value>>4];

str[3]=Hex_Char_Table[value&0X0F];

}

はい、これはルックアップ テーブルを使用するというアイデアです。0 9 と A F は ASCII コード値では連続ではありませんが、これらを配列に入れて連続を作成できます。次に、その値を下付き文字として使用して、対応する文字を直接取得します。

Hex_Char_Table の定義が面倒で一文字ずつ入力する必要があると思う人もいるかもしれません。実際、次のようにすることができます。

void Value2String(unsigned char value,char *str)

{

char *Hex_Char_Table="0123456789ABCDEF";

str[0]='0';str[1]='X';str[4]=0;

str[2]=Hex_Char_Table[value>>4];

str[3]=Hex_Char_Table[value&0X0F];

}

文字配列を文字列定数に置き換えました。実際、メモリ内のそれらの表現はほぼ同じであり、その本質はメモリ内のバイトのシーケンスです。図 2.1 に示すように。

図 2.1 文字配列と文字列はどちらもメモリ内のバイト シーケンスです

違いは、文字配列では、定義時に配列のサイズ、つまり配列が保持できる文字 (バイト) 数を明確に指定する必要があることです。文字列の長さは、最初のバイトが 0 に等しいことに基づいています。したがって、文字列のバイト シーケンスには、値が 0 (文字列の終端文字) であるバイトが存在する必要があります。文字列の長さを計算するために通常使用する strlen 関数は、実際にはこの 0 を検出しています。そのため、strlen に 0 を含まない文字配列 (バイト列) を渡すと、最終結果が間違ったり、配列への範囲外アクセスによりプログラムがクラッシュしたりする可能性があります。

上で、Zhennan は「文字列自体がポインタである」と述べたので、この文の本当の意味を目撃する瞬間が来たので、引き続き上記のプログラムを単純化していきます。

void Value2String(unsigned char value,char *str)

{

str[0]='0';str[1]='X';str[4]=0;

str[2]="0123456789ABCDEF"[value>>4];

str[3]="0123456789ABCDEF"[value&0X0F];

}

ポインター変数 Hex_Char_Table は実際には冗長であり、「文字列自体がポインターである」ため、[] を添え字とともに直接使用して、その中の文字を抽出できます。本質的にポインター型である (つまり、アドレスの意味を表す) 変数または定数は、[] または * を直接使用して、それが指すデータ シーケンス内のデータ要素にアクセスできます。

[外部リンク画像の転送に失敗しました。ソース サイトには盗難防止リンク メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-DdGdEKH2-1693141960059) (https://mmbiz.qpic.cn/mmbiz_jpg/) 2ibmcljDoyWQfE7zRyFjibgmyqffdVPByhWwUz7zr8ibH2bcUQWzGwIJ3IHL vmxtWzYEiaahqzVpxCVdazYHmQcpjA/640?wx_fmt=jpeg&wxfrom =5&wx_lazy=1&wx_co=1)]

おすすめ

転載: blog.csdn.net/qq_41854911/article/details/132527909