HOME»基本情報技術者試験掲示板»平成21年春期 午後問9について
投稿する

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

 勉強中さん(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さん(No.2) 
FE シルバーマイスター

#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さん(No.4) 
FE シルバーマイスター
この投稿は投稿者により削除されました。(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さん(No.6) 
FE シルバーマイスター
この投稿は投稿者により削除されました。(2021.05.16 20:12)
2021.05.16 20:12
GinSanaさん(No.7) 
FE シルバーマイスター
ああ、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さん(No.8) 
FE シルバーマイスター
だから、char配列のポインタの場合、数値を足し込んだらhoge[値]の文字が返ってくるってことです。char[7(length)]はnull終端だから\000が返ってきた。
2021.05.16 20:12
GinSanaさん(No.9) 
FE シルバーマイスター
それで、if分岐でchar[length - 1](最終文字)にスラがありますか?ってきいてるわけで、あったらパスとして最後にスラがあるとおかしいね、というので参照をデクリメントで巻き戻しているわけですよね。
2021.05.16 20:16
GinSanaさん(No.10) 
FE シルバーマイスター
実際にデクリメントするとこうなります。
(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日経過したスレッドへの投稿はできません。
© 2010- 基本情報技術者試験ドットコム All Rights Reserved.

Pagetop