文字列リテラルへのポインタの配列が与えられた場合:
char *textMessages[] = {
"Small text message",
"Slightly larger text message",
"A really large text message that "
"is spread over multiple lines"
}
特定の文字列リテラルの長さをどのように決定しますか?3番目の文字列を言いますか? sizeofコマンドを次のように使用してみました。
int size = sizeof(textMessages[2]);
しかし、結果は、文字列リテラルの長さではなく、配列内のポインタの数のようです。
コンパイル時で数値を計算する場合(実行時にstrlen
を使用するのではなく)、次のような式を使用してもまったく問題ありません。
sizeof "A really large text message that "
"is spread over multiple lines";
ただし、長いリテラルの繰り返しを避けるために、マクロを使用することをお勧めします。
#define LONGLITERAL "A really large text message that " \
"is spread over multiple lines"
sizeof
によって返される値には、終了NULが含まれているため、strlen
より1つ多いことに注意してください。
私の提案は使用することです strlen コンパイラの最適化をオンにします。
たとえば、x86のgcc4.7では次のようになります。
#include <string.h>
static const char *textMessages[3] = {
"Small text message",
"Slightly larger text message",
"A really large text message that "
"is spread over multiple lines"
};
size_t longmessagelen(void)
{
return strlen(textMessages[2]);
}
実行後make CFLAGS="-ggdb -O3" example.o
:
$ gdb example.o
(gdb) disassemble longmessagelen
0x00000000 <+0>: mov $0x3e,%eax
0x00000005 <+5>: ret
つまりコンパイラは、strlen
の呼び出しを定数値0x3e = 62に置き換えました。
コンパイラーが実行できる最適化の実行に時間を無駄にしないでください。
strlen
多分?
size_t size = strlen(textMessages[2]);
文字列の長さを取得するには、strlen()
ライブラリメソッドを使用する必要があります。 sizeof
は、ポインタであるtextMessages[2]
のサイズを示します。これは、マシンに依存します(4バイトまたは8バイト)。
配列内の値が連続しているという事実を利用できます。
const char *messages[] = {
"footer",
"barter",
"banger"
};
size_t sizeOfMessage1 = (messages[1] - messages[0]) / sizeof(char); // 7 (6 chars + '\0')
サイズは、要素の境界を使用して決定されます。最初の要素の先頭と2番目の要素の先頭の間のスペースは、最初の要素のサイズです。
これには、終了する\0
が含まれます。もちろん、このソリューションは定数文字列でのみ適切に機能します。文字列がポインタである場合、文字列の長さではなく、ポインタのサイズを取得します。
これが機能することは保証されていません。フィールドが整列している場合、これは間違ったサイズをもたらす可能性があり、同一の文字列をマージするなど、コンパイラによって導入される他の警告がある可能性があります。また、配列には少なくとも2つの要素が必要です。