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

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

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

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

Q&A

解決済

3回答

2397閲覧

ポインタと配列について解説ください

taiga

総合スコア22

C

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

0グッド

0クリップ

投稿2015/10/17 16:26

文字を入力してそれを反転させる関数を作るという練習問題があって
出力だけならデクリメントで簡単にできたんですが配列の中身を反転させるのがわからなくて答えを見たんですが見てもよくわかりませんでした
この関数を詳しく解説してほしいです

c

1void rev(char *str) 2{ 3 char c, *p; 4 5 p = str + strlen(str) - 1; 6 7 while (str < p) { 8 c = *str; 9 *str++ = *p; 10 *p-- = c; 11 } 12 return; 13}

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

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

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

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

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

guest

回答3

0

質問への回答ではありませんが、stackoverflow のサイトにこんな QA がありました。

英語ですが、コードの部分だけを読めばよいです。
いろいろな方法が可能なことがわかるとおもいます。

これらのコードの意味も考えてみるとよいと思います。
配列、ポインターとその使い方について、より理解が深まるはずです。

投稿2015/10/17 23:02

katoy

総合スコア22324

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

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

0


C言語の文字列は一文字ずつ格納された配列である。
C言語の配列はイメージ的に正直に連続してメモリ上に存在している
ポインタはメモリ上のアドレスを格納する
「*str」はアドレス先に格納された値を参照し「str」はアドレス値そのものを参照する
格納されているものがアドレスなのに「int *str」や「char *str」のように宣言時に型を指定するのは、宣言した型に合わせた色々な処理に対応するため。
例えば「char *str」でstr+1とするだけで、一文字後ろのアドレスになる。
※intとcharではメモリ上に占める大きさが違うので、型指定が無いとstr+1のような書き方はできず、それぞれの大きさをプログラマが把握してstr+32bitのように記述するはめになる。

以上を前提にコードを見ていきます。

c

1p = str + strlen(str) - 1;

pには最後の文字のアドレスが格納される。
str: 文字列の先頭アドレス「abc」ならaの位置が格納されている
strlen(str): 文字列の長さ。「abc」なら3
※「abc」なら、aの位置から -> 3文字分後ろへ -> 1文字分前へで、「c」の位置

c

1while (str < p)

文字列を反転させる関数なので、
pを文字列最後尾から一文字ずつ先頭へ移動
strを文字列先頭から一文字ずつ最後尾へ移動させて
pとstrが交わるかすれ違うまでループします。

c

1c = *str; 2*str++ = *p; 3*p-- = c;

初回ループでは次のようになります。
1行目 cに先頭文字をバックアップ 「ABCDE」なら「A」
2行目 先頭文字を最後尾文字で上書きした後、strを1文字分進める
3行目 最後尾文字をバックアップしておいた先頭文字で上書きし、pを1文字分戻す
※「ABCDE」ならループ1回目で「EBCDA」になる
これがpとstrが交差するまで繰り返し実行されると、文字列が反転するはずです。

c

1*str++ = *p;

これは次の2行をまとめて書いたものです。参考
*str = *p;
str++;

投稿2015/10/17 17:24

編集2015/10/17 17:34
hirohiro

総合スコア2068

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

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

0

ベストアンサー

この関数は簡単に言いますと, 手で 「外側から内側へ, 前と後ろの文字を入れ替えて行くような作業」を行っています.

まず, 変数に関して言えば.
char cは文字をコピーして一時退避しておくもの.
*pは 入れ替えてstrの最終文字(最初"Hello"で言えば, "o"にあたるポインタの格納.)のポインタ

4行目で, pにはstrの最終文字が入り, 初期化されます.
つぎにwhileループの中に入ります.
インクリメント, デクリメントを考えないでいくと,

最初, 文字の一番目をcに 退避, ("H"がcへ格納)
つぎに, その退避したところに最終文字を入れる ("o"が"H"の位置へ格納)
最後に, 退避した文字を最終文字部分に格納. ("H"を"o"位置へ)

すると,"oellH"となることがわかると思います.
これをwhileループで変更した部分まで(strがpより大きくなったら評価済み)繰り返します.

インクリメント等については飛ばしましたが, 交換するときの作業には関わってはいません.
ループしたとき次のポインタ(変更した文字より内側)へ移したいから使われています.

一応試した, Cコードも記載しておきます.

C

1#include <stdio.h> 2#include <string.h> 3 4void rev(char *str) 5{ 6 char c, *p; 7 8 p = str + strlen(str) - 1; 9 printf("p :%c\n", *p); 10 11 while (str < p) { 12 c = *str; 13 printf("c: %c\n", c); 14 *str = *p; 15 *str++; 16 17 *p = c; 18 *p--; 19 printf("%s\n", str); 20 } 21 return; 22} 23 24int main(void){ 25 26 char str[] = "Hello"; 27 printf("before :%s\n", str); 28 29 rev(str); 30 31 printf("after : %s\n", str); 32 return 0; 33} 34

投稿2015/10/17 17:17

Junichi

総合スコア15

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問