[セットトップ]C言語のポインタタイプ学習の強化
2773 ワード
仕事のためにubootのpciスキャンコードを自分のプロジェクトに移植するには、もともとできていましたが、ubootのいくつかの私たちのプロジェクトのために使用されているファイルを少し修正する必要があります.
つまりubootがエクスポートした関数は、プロジェクトで使用されますが、現在ubootはリリースされているバージョンであり、これ以上変更できないことが知られています.
どうしようかな?実はpciシステムはubootが起きる時すでに初期化して、コードの中で必要なのはその中のいくつかの変数のアドレスで、これらのアドレスがあって、適切なポインタに変換して、それでは操作することができます.
ここでは主にタイプ問題を研究する.
例えば、簡単から難しいまで:
では、aという変数、すなわちaを読み書きできるようにしたいのですが、ADDR_しか知られていません.OF_A
みんなそう思う
そして、pに対する参照は、*p=6などの操作aに相当する.aの値を6に変更する.
なぜこんなことができるのか、針を理解するのに役立つと思ったことはありませんか.
aのタイプが整数である場合、そのアドレスを表す整数ポインタが必要である.
このように、aがどのタイプなのか、どのタイプのポインタがそのアドレスを指す必要があるのか.
次に例を挙げます
#define ADDR_OF_PTR 0 xffff 0000 ptrのアドレス(&ptr)を今知っていたら、どうやって表示しますか?
ptrはポインタです.明らかにポインタを指すポインタが必要です.
このように*tempを行う場合はptr操作に相当する.
たとえば
これによりptrが変化し、ptr=&cに相当する.
はい、上記はすべて基本タイプです.次に、本プロジェクトで遭遇したタイプを分析します.
これはubootコードで定義されていますが、アドレス(&pci_info_list)がわかりました.
参照するには、次のタイプをよく分析する必要があります.
まず、pci_info_Listは、構造体ポインタstruct fsl_のタイプの5つの要素を含む配列です.pci_info *
はい、上記の分析によると、ポインタのタイプは5つの要素を含む配列を指し、配列を指すポインタであることは明らかです.
以下のように定義すべきである
どうですか.複雑ですか.
実は分析さえすれば、そんなに複雑ではありません.解析タイプ
struct fsl_pci_info * (*)[5];
演算子の優先度によって、()内が最も高いので、ポインタが1つ、後に[5]ついているので、ポインタが1つの配列を指していることを説明し、前のタイプは配列要素のタイプです!
次に使用する部分ですが、本当に必要なのはこの配列の要素を取り出すことです.
ptrタイプは配列を指すポインタですが、*ptrのタイプは配列タイプです!
ここでは主にC言語におけるポインタのタイプについて述べる.C言語のデータ型の唯一の役割は、コンパイラに変数がメモリにどのように格納されているかを教え、使用するときはタイプサイズに従ってください.
例えばchar ch;
文字型は、データを取るときにint interに及ばない = ch; &chアドレスから1バイトのみ取得します.
int aであれば;int b = a;
&aから始まるsizeof(a)つまり4バイトを取る必要があります.
また、1つのポインタのタイプは、ポインタがインクリメンタルを行うときのステップ長を決定します.
たとえば
ptr++はptrを次のバイトに向けた.
もしそうなら
ptrは次のInt型データ、すなわちステップ長sizeof(a)を指す.
構造体のポインタであれば、同じ理屈でsizeof(struct XXX)になる.
他のタイプはこのように推定されます.
つまりubootがエクスポートした関数は、プロジェクトで使用されますが、現在ubootはリリースされているバージョンであり、これ以上変更できないことが知られています.
どうしようかな?実はpciシステムはubootが起きる時すでに初期化して、コードの中で必要なのはその中のいくつかの変数のアドレスで、これらのアドレスがあって、適切なポインタに変換して、それでは操作することができます.
ここでは主にタイプ問題を研究する.
例えば、簡単から難しいまで:
int a = 5;
a 0xffff0000;
&a == 0xffff0000
#define ADDR_OF_A 0xffff0000
では、aという変数、すなわちaを読み書きできるようにしたいのですが、ADDR_しか知られていません.OF_A
みんなそう思う
int *p = (int *)ADDR_OF_A
そして、pに対する参照は、*p=6などの操作aに相当する.aの値を6に変更する.
なぜこんなことができるのか、針を理解するのに役立つと思ったことはありませんか.
aのタイプが整数である場合、そのアドレスを表す整数ポインタが必要である.
このように、aがどのタイプなのか、どのタイプのポインタがそのアドレスを指す必要があるのか.
次に例を挙げます
int b = 1;
int *ptr = &b;
#define ADDR_OF_PTR 0 xffff 0000 ptrのアドレス(&ptr)を今知っていたら、どうやって表示しますか?
ptrはポインタです.明らかにポインタを指すポインタが必要です.
int **temp;
temp = (int **)ADDR_OF_PTR;
このように*tempを行う場合はptr操作に相当する.
たとえば
int c = 3;
*temp = &c;
これによりptrが変化し、ptr=&cに相当する.
はい、上記はすべて基本タイプです.次に、本プロジェクトで遭遇したタイプを分析します.
struct fsl_pci_info *pci_info_list[5] = { NULL, NULL, NULL, NULL, NULL} ;
これはubootコードで定義されていますが、アドレス(&pci_info_list)がわかりました.
#define PCI_INFO_LIST_ARRAY 0x7fff0b6c
参照するには、次のタイプをよく分析する必要があります.
まず、pci_info_Listは、構造体ポインタstruct fsl_のタイプの5つの要素を含む配列です.pci_info *
はい、上記の分析によると、ポインタのタイプは5つの要素を含む配列を指し、配列を指すポインタであることは明らかです.
以下のように定義すべきである
struct fsl_pci_info *(*ptr)[5];
ptr = (struct fsl_pci_info * (*)[5])PCI_INFO_LIST_ARRAY;
どうですか.複雑ですか.
実は分析さえすれば、そんなに複雑ではありません.解析タイプ
struct fsl_pci_info * (*)[5];
演算子の優先度によって、()内が最も高いので、ポインタが1つ、後に[5]ついているので、ポインタが1つの配列を指していることを説明し、前のタイプは配列要素のタイプです!
次に使用する部分ですが、本当に必要なのはこの配列の要素を取り出すことです.
struct fsl_pci_info *pci_info;
pci_info = (*ptr)[i];
ptrタイプは配列を指すポインタですが、*ptrのタイプは配列タイプです!
ここでは主にC言語におけるポインタのタイプについて述べる.C言語のデータ型の唯一の役割は、コンパイラに変数がメモリにどのように格納されているかを教え、使用するときはタイプサイズに従ってください.
例えばchar ch;
文字型は、データを取るときにint interに及ばない = ch; &chアドレスから1バイトのみ取得します.
int aであれば;int b = a;
&aから始まるsizeof(a)つまり4バイトを取る必要があります.
また、1つのポインタのタイプは、ポインタがインクリメンタルを行うときのステップ長を決定します.
たとえば
char a;
char *ptr = &a;
ptr++;
ptr++はptrを次のバイトに向けた.
もしそうなら
int a;
int *ptr =&a;
ptr++;
ptrは次のInt型データ、すなわちステップ長sizeof(a)を指す.
構造体のポインタであれば、同じ理屈でsizeof(struct XXX)になる.
他のタイプはこのように推定されます.