sizeof
コンパイル時演算子として知られています。サイズが事前に決定できるオブジェクトのサイズのみをカウントできます。したがって、ポインターを渡すと (配列は関数の引数として渡されるとポインターに縮退します)、ポインターのサイズを取得するだけです。
典型的な取り決めは、NULL ポインターでリストを終了することです。このようなリストを使用すると、関数は次のように記述できます。
int indexof(char *aword, char *arrayofwords[]){
int i;
for (i=0 ; arrayofwords[i]!=NULL ;i++){
if (strcmp(aword,arrayofwords[i])==0){return i;}}
return -1;//not found
}
以下が機能するため、これは確かに驚くべきことに思えるかもしれません。
#include <stdlib.h>
#define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
int main() {
char *ta[]={"asdf","qwer","zxcv"};
char *aword="qwer";
int i; unsigned int ct=COUNT_OF(ta);
for (i=0 ; i<ct ;i++){
if (strcmp(aword,ta[i])==0){return i;}}
return -1;//not found
}
これは、配列ta
が適用されているのと同じスコープで定義されsizeof
ているためです。はコンパイル時sizeof
に計算を実行するため、コンパイラのシンボル テーブルを使用して、これらの各部分に割り当てられた正確なスペースを検出できます。
ただし、関数に渡すと、コンパイラに関する限り、配列ではなくなります。この関数内では配列ではなく単なるポインタ (char ** == char *[] == char [][]) であるため、渡された配列のサイズを検出するためにindexof
関数を使用することはできません。sizeof
COUNT_OF
マクロを利用する 1 つの方法はindexof
、長さパラメーターを受け入れるようにすることです。次に、呼び出しで使用できますCOUNT_OF
(関係する配列がスコープで定義されている限り)。
#include <stdlib.h>
#define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
int main() {
char *ta[]={"asdf","qwer","zxcv"};
char *word="qwer";
return indexof(word, ta, COUNT_OF(ta));
}
int indexof(char *aword, char *arrayofwords[], int length){
int i; unsigned int ct=length;
for (i=0 ; i<ct ;i++){
if (strcmp(aword,arrayofwords[i])==0){return i;}}
return -1;//not found
}