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

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

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

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

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

Q&A

解決済

2回答

991閲覧

c言語 ポインタについて

toyo_69

総合スコア20

C

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

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

0グッド

0クリップ

投稿2019/05/15 11:01

編集2019/05/16 13:19

下記に記述したプログラムのポインタ部分についての疑問なのですが
このプログラムの構造でfull_adder関数においてsとcoutのポインタを使わなければ機能しない理由が分かりません。
自分自身c言語の初学者でポインタについてあまりわかっていないこともあると思います。
宣言時以外で変数にを付けたポインタ変数は数を格納できる箱として扱う、と覚えたので意味的には同じかと思うのですが、下記のプログラム内のを全て外して実行してみると出力されるs0〜s7の値がそれぞれ大きな値になる(s0〜s7のアドレス?)ので混乱してしまいました。
質問の書き方に関しては謝らせていただきます。見辛くて本当に申し訳ないです。
どうしても行き詰まってしまい、理解に苦しんでいます。どうかご教示お願い致します。

ソースコード↓

C

1#include <stdio.h> 2int and(int, int);//論理積を計算する関数 3int or(int, int);//論理和を計算する関数 4int xor(int, int);//排他的論理和を計算する関数 5int bin_to_int(int n0, int n1, int n2, int n3, int n4, int n5, int n6, int n7); 6//2進数から10進数に変換する関数 7void full_adder(int a, int b, int cin, int *s, int *cout); 8//2進数の和を計算する関数(全加算器) 9 10int main() { 11 int a0, a1, a2, a3, a4, a5, a6, a7; 12 int b0, b1, b2, b3, b4, b5, b6, b7; 13 int c0 = 0, c1 = 0, c2 = 0, c3 = 0, c4 = 0, c5 = 0, c6 = 0, c7 = 0; 14 int s0, s1, s2, s3, s4, s5, s6, s7; 15 int k, l, m; 16 17 printf("8桁の2進数を2つ入力せよ\n"); 18 printf("1つ目:"); 19 scanf("%d %d %d %d %d %d %d %d", &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7); 20 printf("2つ目:"); 21 scanf("%d %d %d %d %d %d %d %d", &b0, &b1, &b2, &b3, &b4, &b5, &b6, &b7); 22 23 k = bin_to_int(a0, a1, a2, a3, a4, a5, a6, a7); 24 l = bin_to_int(b0, b1, b2, b3, b4, b5, b6, b7); 25 printf("入力した1つ目の10進数表現は:"); 26 printf("%d\n", k); 27 printf("入力した2つ目の10進数表現は:"); 28 printf("%d\n", l); 29 30 full_adder(a7, b7, 0, &s7, &c0); 31 full_adder(a6, b6, c0, &s6, &c1); 32 full_adder(a5, b5, c1, &s5, &c2); 33 full_adder(a4, b4, c2, &s4, &c3); 34 full_adder(a3, b3, c3, &s3, &c4); 35 full_adder(a2, b2, c4, &s2, &c5); 36 full_adder(a1, b1, c5, &s1, &c6); 37 full_adder(a0, b0, c6, &s0, &c7); 38 39 m = bin_to_int(s0, s1, s2, s3, s4, s5, s6, s7); 40 printf("入力した2つの2進数の和は:%d %d %d %d %d %d %d %d\n", s0, s1, s2, s3, s4, s5, s6, s7); 41 printf("入力された2つの2進数の和の10進数表現は:"); 42 printf("%d\n", m); 43 44 return 0; 45} 46 47int and(int a, int b) { 48 if ((a == 1) && (b == 1)) 49 return 1; 50 else 51 return 0; 52} 53 54int or(int a, int b) { 55 if ((a == 1) || (b == 1)) 56 return 1; 57 else 58 return 0; 59} 60 61int xor(int a, int b) { 62 if (a != b) 63 return 1; 64 else 65 return 0; 66} 67 68int bin_to_int(int n0, int n1, int n2, int n3, int n4, int n5, int n6, int n7) { 69 int b; 70 b = 128 * n0 + 64 * n1 + 32 * n2 + 16 * n3 + 8 * n4 + 4 * n5 + 2 * n6 + n7; 71 return b; 72} 73 74void full_adder(int a, int b, int cin, int *s, int *cout) 75{ 76 *s = xor(a, xor(b, cin));//2進数の和を計算する式 77 *cout = or (and (a, b), and (xor (a, b), cin));//和の繰り上げを計算する式 78}

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

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

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

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

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

hayataka2049

2019/05/15 11:27 編集

このサイトではコードは以下のように書くことをおすすめします。 ```c ここにコード ``` こう書かないとインデントが消えたりマークダウンとして解釈されたり、いろいろヘンになります。 質問は編集できるので直しておいてください。成功すればちゃんと枠の中に入るので、プレビュー見ながらやってくださいね。 コード部分を選択してから<code>ボタンを押しても挿入できます。
toyo_69

2019/05/16 13:21

恥ずかしながら失礼しました。 直させていただきました。有難うございます。
guest

回答2

0

ベストアンサー

関数の中での変数の値の変化は、ポインタを使うか、戻り値(returnで返される値)を使わないと、関数の外では影響を与えません。
例えば、
void full_adder(int a, int b, int cin, int s, int cout)
{
s = xor(a, xor(b, cin));//2進数の和を計算する式
cout = or (and (a, b), and (xor (a, b), cin));//和の繰り上げを計算する式
}
full_adder(a, b, cin, s, cout)とか、適当な数を入れて実行しても、sとcoutの値は変動しません。

あるいはグローバル変数を使う方法もありますが、これも使われる機会は少ないです。

s0などの値が大きくなってしまった原因は&などポインタ的な指示がどこかに残っていたのかもしれません。

投稿2019/05/15 11:32

aoies

総合スコア331

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

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

toyo_69

2019/05/16 13:30

成程、ただ単にローカル変数を関数外に渡そうとしていたからおかしくなってしまっていたのですね。 ポインタ型変数はグローバル変数のようなものなのですね。恥ずかしながら存じ上げませんでした。 これでスッキリしました。分かりやすい解説、本当に有難うございました。
hayataka2049

2019/05/16 13:55

>ポインタ型変数はグローバル変数のようなもの 誤解がありそう・・・アドレス渡しにすると、呼び出し元と呼び出し先でアドレスを介して同じメモリ領域を参照できるというのがミソです。 ただの引数だと値のコピーが別のメモリ領域に格納されるので、書き換えても意味がない・・・
toyo_69

2019/05/18 08:42

確かに似たようなものとは言っても今回の例のような関数間でデータを渡す際にはグローバル変数を用いたところでmain関数内から渡す引数がその時その時によって違いますしポインタでないと実現しませんね。ご指摘有難うございました。
guest

0

渡し元に、数値を返すためにポインタを使ってます。
ここを単純にデータを渡してしまうと、渡し元は変更されません

full_adder(a7, b7, 0, &s7, &c0);

s7 と c0 のデータはfull_adderの関数内で変更されます

#戻り値にして値を返す、というテもありますが、それはまたべつのおはなし

投稿2019/05/15 11:14

y_waiwai

総合スコア87719

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

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

toyo_69

2019/05/16 13:32

ローカル変数とグローバル変数についての知識が不十分でした。 分かりやすい回答、有難うございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問