構造体のアライメント
締め切りが 2017/09/08 10:00 AM なので,その 1 分後に投稿されるように予約
【概要】
構造体の中に、いくつかの要素が入っています。
最後の要素の先頭アドレスが、構造体の先頭から何バイトあとにあるのかを計算して下さい。
ただし、構造体の先頭アドレスは(幸運なことに)16の倍数になっています。
【入出力】
入力は
SDIL
のようになっています。
構造体の中にある要素を示す記号が、アドレス順に区切り文字なしで並んでいます。
各記号の意味は、下表のとおりです:
記号 サイズ(バイト数) 先頭アドレスの制限
C 1 なし
S 2 偶数アドレス
I 4 4の倍数アドレス
L 8 4の倍数アドレス
D 8 8の倍数アドレス
M 16 16の倍数アドレス
例えば、CMの様になっていた場合、先頭のアドレスにはCが示す要素が入っています。
その後には 15byte のパディング(変数としては使われない詰め物)が入っていて、Mが示す要素はその後に続くことになります。
出力は、SDIL の示す構造体の先頭アドレスから 20 バイト先に末尾の要素があるので
20
のような感じです。
構造体のサイズではなく、最後の要素の先頭アドレスであることに注意して下さい。
【例】
入力 出力 メモリイメージ(.はパディング )
SDIL 20 SS......DDDDDDDDIIIILLLLLLLL
CM 16 C...............MMMMMMMMMMMMMMMM
CSILDC 24 C.SSIIIILLLLLLLLDDDDDDDDC
【補足】
• 不正な入力に対処する必要はありません。
• Lのアライメントは 4 の倍数です。8 の倍数ではありません。
• データのリオーダーはないものとします。
• 入力文字列の長さは、1 文字以上 16 文字以下です。
• 実際のアライメントについてはWikipedia の記事が参考になるかもしれません。
===============================================
f = function(s) {
item = c("C", "S", "I", "L", "D", "M")
size = c(1, 2, 4, 8, 8, 16)
position = c(1, 2, 4, 4, 8, 16)
address = 0
for (i in 1:nchar(s)) {
what = grep(substr(s, i, i), item)
fill = address %% position[what]
if (fill != 0) {
address = address + (position[what] - fill)
}
address = address + (i != nchar(s))*size[what]
}
cat(address)
}
# f(readLines(file("stdin", "r")))
f("SDIL") # 20
f("CM") # 16
f("CSILDC") # 24
f("M") # 0
f("C") # 0
f("IMCSCS") # 38
f("CSMSISLD") # 56
f("IMCSCS") # 38
f("CSMSISLD") # 56
f("LDCDCLLMD") # 80
f("CDCSSMMDIL") # 76
f("LCSMCLIMCDL") # 80
f("MISIMLCMDLLL") # 104
f("SCSSSLCDILLCI") # 56
f("CLIMSCMDLILISI") # 100