平成21年春期 午後問9について

午前試験免除制度対応!基本情報技術者試験のeラーニング【独習ゼミ】
勉強中さん  
(No.1)
質問させていただきます。
平成21年春期 午後問9のプログラム
void convert内の処理について、

bp = base + length; /* bpは文字列baseの終端を指す。 */

上記の部分は具体的にどのような値が格納されるのでしょうか。
たとえばbaseに"/a/d/e/"が格納されていた場合、
lengthにはその文字数である"7"が入るかと思っていますが、
それだと
bp = /a/d/e/ + 7
となってしまい、変ですよね…?

よろしくお願いいたします。
2021.05.16 15:46
GinSanaさん 
FE シルバーマイスター
(No.2)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
char OrgMessage[] = "/a/d/e/";
char *base = NULL;
char *bp = NULL;
int length;
base = (char*)malloc(sizeof(char) * sizeof(OrgMessage));
if(base == NULL){
printf("failed malloc\r\n");
exit(EXIT_FAILURE);
}
strcpy(base, OrgMessage);
printf("%s\r\n", base);
length = strlen(base);
bp = base + length;
free(base);
return 0;
}


で、gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04)でコンパイルして
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2でデバッグしたらこうなりました。

Breakpoint 1, main (argc=1, argv=0x7fffffffe1d8) at test.c:18
18              char OrgMessage[] = "/a/d/e/";
(gdb) n
19              char *base = NULL;
(gdb) n
20              char *bp = NULL;
(gdb) n
22              base = (char*)malloc(sizeof(char) * sizeof(OrgMessage));
(gdb) n
23              if(base == NULL){
(gdb) n
27              strcpy(base, OrgMessage);
(gdb) n
28              printf("%s\r\n", base);
(gdb) n
/a/d/e/
29              length = strlen(base);
(gdb) p base
$1 = 0x5555555592a0 "/a/d/e/"
(gdb) n
30              bp = base + length;
(gdb) p length
$2 = 7
(gdb) n
31              free(base);
(gdb) p bp
$3 = 0x5555555592a7 ""
(gdb)


まあ、ふつう違うもの足し込んでどうすんだ?とは思いますけどね・・・。
2021.05.16 17:38
勉強中さん  
(No.3)
bpに/a/d/e/ + 7が格納されるという認識がそもそも間違いかと思っていたのですが
それで合ってたのですね。
ひとまず疑問は解決しました。
ありがとうございます。
2021.05.16 19:29
GinSanaさん 
FE シルバーマイスター
(No.4)
この投稿は投稿者により削除されました。(2021.05.16 21:47)
2021.05.16 21:47
勉強中さん  
(No.5)
すみません、しっかり理解できていないようなので教えてください。

問題文に
bp = base + length; /* bpは文字列baseの終端を指す。 */
とあることから、bpは文字列のポインタの役割があると認識しています。
bpがNULLのままだと、ポインタとしては使用できませんよね…??
この設問9でのbpの正しい役割というか、働きはどういったものなのでしょうか。。
2021.05.16 19:47
GinSanaさん 
FE シルバーマイスター
(No.6)
この投稿は投稿者により削除されました。(2021.05.16 20:12)
2021.05.16 20:12
GinSanaさん 
FE シルバーマイスター
(No.7)
ああ、gdbのきき方を間違えてました。

Breakpoint 1, main (argc=1, argv=0x7fffffffe1d8) at test.c:19
19              bp = base + length;
(gdb) n
20              if(*(bp - 1) == '/'){
(gdb) n
21                      --bp;
(gdb) p bp
$1 = 0x5555555592a7 ""
(gdb) p *bp
$2 = 0 '\000'
(gdb) p *bp - 1
$3 = -1
(gdb) p *(bp - 1)
$4 = 47 '/'
(gdb)

こんな風にポインタの中身は聞かないといけなかった
2021.05.16 20:09
GinSanaさん 
FE シルバーマイスター
(No.8)
だから、char配列のポインタの場合、数値を足し込んだらhoge[値]の文字が返ってくるってことです。char[7(length)]はnull終端だから\000が返ってきた。
2021.05.16 20:12
GinSanaさん 
FE シルバーマイスター
(No.9)
それで、if分岐でchar[length - 1](最終文字)にスラがありますか?ってきいてるわけで、あったらパスとして最後にスラがあるとおかしいね、というので参照をデクリメントで巻き戻しているわけですよね。
2021.05.16 20:16
GinSanaさん 
FE シルバーマイスター
(No.10)
実際にデクリメントするとこうなります。
(gdb) p *bp
$5 = 47 '/'
(gdb) p *(bp - 1)
$6 = 101 'e'
(gdb)
2021.05.16 20:21
勉強中さん  
(No.11)
詳細にありがとうございます。
やっとbpの目的が理解できました…。
2021.05.16 21:38

返信投稿用フォーム

スパム防止のためにスレッド作成日から30日経過したスレッドへの書込みはできません。

その他のスレッド


Pagetop