質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

4回答

1682閲覧

C言語の文字列がわかりません

JhonDoe

総合スコア36

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2015/09/04 01:40

この p1 = str1 + strlen(str1) - 1;ていうのがわかりません
最初の文字に足していって最後の文字を示していますが、それだったら
p1 = strlen(str1) - 1; これだけだとエラーが出ます

lang

1int main(int agc, char *agv[]) 2{ 3 char str1[] = "Helo"; 4 char str2[80], *p1, *p2; 5 6 p1 = str1 + strlen(str1) - 1; 7 p2 = str2; 8 9 while (p1 >= str1) 10 *p2++ = *p1--; 11 *p2 = '\0'; 12 13 printf("%s %s", str1, str2); 14 15 return 0; 16}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

変数の定義部分を分解すれば、分かりやすいのですが、
下記の2番目の定義は、char型のポインタ変数です。
char str2[80];
char *p1;
char *p2;

下記は、str1のデータ長を取り出し、1を減じた値です。
計算結果は数値の3になり、ポインタとして扱えません。
strlen(str1) - 1

なので、数値の3を変数に代入したい場合は、下記の様に
int型の変数を定義すれば、代入出来ます。
int i;
i = strlen(str1) - 1;

アドレスstr1にiを加算して、ポインタp1に格納する事も
出来ます。
p1 = str1 + i; // p1 = &str1[0] + i ・・・同じ意味

だだし、str1を先に記述しないと、ポインタとして計算
されないので、下記の記述だとエラーになります。
p1 = i + str1;

以上

投稿2015/09/04 17:14

編集2015/09/04 17:16
t2oando

総合スコア55

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

以下のコードは、配列およびポインタ指定で同じ値を表示するコードです。

C

1char buf[] = "1234567890"; 2char *ptr = buf; 3int i; 4 5for(i=0;i<10;i++) 6{ 7 printf("%c, ", buf[i]); 8 printf("%c\n", *(ptr+i)); 9}

配列の場合に要素指定がインデックス指定(=buf[要素のインデックス])なのは当然ですが、
ポインタの場合はというと、これもいわばインデックス指定です。
配列とポインタでなにが異なるかというと、上記例の場合記述様式だけです。

計算的にはどちらも「配列先頭からいくつ目の要素の値であるか」を表します。
※表現としては、以下のように記述しています。

配 列 :配列変数名[インデックス値]
ポインタ:*(ポインタ変数名+インデックス値)

突然ですが、ちょっとここで配列の記述だけでポインタを得ることを考えてみます。
以下は、配列にインデックス指定をした変数から値が入っているアドレスを得るものです。

C

1char buf[] = "1234567890"; 2char *ptr; 3int i; 4 5for(i=0;i<10;i++) 6{ 7 ptr = &buf[i]; 8 printf("%c, ", buf[i]); 9 printf("%c\n", *ptr); 10}

&buf[i] と記述すると、「buf[i] の値が入っているアドレス」を取得できます。
これは ptr + i と記述するのと同じアドレスを得られる書き方です。

[補足]-------------
もし & や * の意味がわからない場合は、アドレス演算子と間接演算子についてちょっと勉強が必要です。

ここで質問者さんの疑問を見てみます。

C

1p1 = str1 + strlen(str1) - 1;

これは基本的に、文字列の長さを -1 した値をインデックス値としてアドレス計算しています。
この書き方を、配列表記で考えてみると以下のようになります。

C

1p1 = &str1[strlen(str1) - 1];

でも、質問者さんのもう1つの書き方だと必要な情報が足らなくなることが分かります。

C

1p1 = strlen(str1) - 1; 2 3p1 = & (ここが足りない) [strlen(str1) - 1];

ポインタ計算をする場合に起点になるアドレスは、この場合 str1 が持っています。
そのことを忘れて位置だけ計算しても、どこからデータを取り出すかを指定しなければデータは取り出せない。ということになります。

投稿2015/09/04 12:04

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

このプログラムは、
str1 と、この文字列を
ひっくり返した
文字列を表示します。

まず、p1 は、ポインタですので、
値を代入しても用途がありません。
p1 にはアドレスを代入しなければ
いけません。まず、このことを
きちんと理解してください。

p1 は、str1 の最後の文字を指したい
ので、文字列の先頭のアドレスを
表す str1 に str1 の文字列の長さを
足しています。

しかし、先頭の文字は
str1 + 1 ではなくて、
str1 から格納されます。
つまり、ゼロから始まりますので、
str1 + 0 となります。

では、先頭から 5 番目の文字は、
どう表せるでしょうか?

答えは、str1 + 4 です。
str1 + 5 ではないことに
注意してください。

では、さらに一般化してみます。
先頭から n 番目の文字は、
どう表せるでしょうか?

答えは、str1 + n - 1 です。

さて、str1 の最後の文字の位置を
ポインタにセットするためには、
str1 に str1 の文字数を足して、
1 を引けば良いことがわかります。

というわけでコードで書くと、

str1 + strlen(str1) - 1

となるわけです。

慣れないうちは、ポインタは
難しいかも知れません。
頑張ってください。

投稿2015/09/04 11:21

umeaji

総合スコア101

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

str1はアドレスで、strlen(str1)は整数です(もちろん1も整数です)。
アドレスに整数を足したり引いたりすると、その数だけプラスなら後ろに、マイナスなら前に移動したアドレスを意味します。

c

1p1 = str1 + strlen(str1) - 1

これで、文字列先頭のアドレスから長さ-1の分だけ後ろに移動した、つまり文字列末尾のアドレスを算出しているわけです。

投稿2015/09/04 01:44

yuba

総合スコア5568

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問