詳細な説明:
uint8_t *rowoftext;
char *text[20] = {"string1","string2",.......,"srting20"};
uint8_t は (おそらく) ヘッダー ファイルのどこかに次のように定義されています。
typdef unsigned char uint8_t;
rowoftext はポインターとして宣言され、uint8_t へのポインターとしてファイル スコープで定義され、NULL の既定値が割り当てられます。
text は、signed char へのポインターの配列として宣言され、32 ビット システムでは 80、64 ビット システムでは 160 の 20*sizeof(char*) の配列として定義されます。
コード行、
rowoftext = (uint8_t *)text[textrow++];
このステートメントの前にrowoftextを見ると、NULLまたは以前に割り当てられたポインター値が格納されていました。これで、変数 rowoftext には、text[textrow] に格納されたポインター (アドレス) が含まれます。
textrow の事後インクリメントにより、変数 textrow の値がインクリメントされましたが、インクリメント前の textrow の値が使用されていました。このイディオムは、C および C++ では非常に一般的です。
次の 2 つの宣言には違いがあります。
uint8_t *rowoftext;
uint8_t rowoftext[ integer_expression ];
1 つ目は、rowoftext をポインターを保持する変数として宣言します。ポインターは、配列のベース アドレスを割り当てることができ、ポインターをインクリメントすることで配列をトラバースするために使用できます。2 番目は、uint8_t 要素の配列への定数ポインターを宣言します。どちらの例も、[] 演算子で uint8_t の配列をアドレス指定するために使用できる変数 (sic) を宣言します。
rowoftext[ integer ]
これはと同等です
*(rowoftext + integer)