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

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

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

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

Q&A

解決済

2回答

26626閲覧

C言語構造体のtmpを使ったソート方法

dec5798

総合スコア74

ポインタ

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

0グッド

0クリップ

投稿2016/10/22 05:39

編集2016/10/22 05:57

###前提・実現したいこと
【C言語構造体のtmpを使ったソート方法】

研究課題が学校から出されまして
c言語の構造体のソートを行うプログラムを提出する必要が有ります。

具体的には構造体のデータで並び替えを行い(ソート方法は自由)
新しく並び替えた構造体の内容を表示するプログラムが書きたいです。

以下にプログラムを記載します。

c

1/* 2*c言語課題問題文 3* 4* 構造体を配列化(要素数3)し、初期値を入れて表示させた後 5* 国語の点数の高い順に並び替えて表示するプログラムを完成させる 6*/ 7 8#include <stdio.h> 9 10struct seiseki { 11 int no; /* 学生番号 */ 12 char name[128]; /* 氏名 */ 13 int kokugo; /* 国語点数 */ 14 15}; 16 17/* 現在の配列の状態を表示する */ 18void printOut(int len, struct seiseki *pt) 19{ 20 int i = 0; 21 22 for(i = 0;i < len; i++){ 23 printf("%d %s %d\n", (pt + i)->no, (pt + i)->name, (pt + i)->kokugo); 24 } 25 26} 27 28 29/* 配列を降順に並べ替える */ 30void sortDesc(int len, struct seiseki *pt) 31{ 32 int i, j; 33 struct seiseki *tmp; 34 35 for(i = 0; i < len-1; i++){ 36 37 for(j = len-1; j > i; j--){ 38 39 if((pt + j)->kokugo > (pt + j - 1)->kokugo){ 40 41 tmp = (pt + j); 42 (pt + j) = (pt + j - 1); 43 (pt + j - 1) = tmp; 44 45 } 46 47 } 48 49 } 50 51} 52 53 54 55int main() 56{ 57 int i; 58 int len; 59 struct seiseki *pt; 60 61 struct seiseki seito[3] = { 62 { 1, "KASAHARA", 83 }, 63 { 2, "NAGANO", 57 }, 64 { 3, "TAKESHITA", 66 }, 65 }; 66 67 len = sizeof(seito) / sizeof(seito[0]); /* 配列の長さを算出 */ 68 pt = seito; /* ポインタに指定 */ 69 70 printOut(len, pt); 71 72 printf("\n国語の点数の高い順に並び替えます\n\n"); 73 sortDesc(len, pt); 74 75 printOut(len, pt); 76 77 78 return 0; 79} 80```c ``` 81---------------------------------------------------------- 82 83 84###発生している問題・エラーメッセージ 85エラーメッセージを確認すると 86 87 tmp = (pt + j); 88 (pt + j) = (pt + j - 1); 89 (pt + j - 1) = tmp; 90 91値を入れ替えているこの場所で 92何かがおかしく動かないと思いますが 93調べてもいまいち理由が判別できませんでした。 94御存知の方がいらっしゃれば修正方法をご教授下さい、 95 96宜しくお願い致します。

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

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

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

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

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

mpyw

2016/10/22 05:42

読みにくいのでコードは「```c」「```」で括ってください。
guest

回答2

0

ベストアンサー

(pt + j)は,そこに演算結果として(たとえば (1 + 2) だとすれば 3)が存在するだけです。代入は変数もしくは*(値)に対してできるだけであって,に対しての代入はできません。

【左辺にあるとき】
pt + j: そもそも左辺にこれない
*(pt + j): pt + jの演算結果の値に対応する番地

【右辺にあるとき】
pt + jpt + jの演算結果の値
*(pt + j): pt + jの演算結果の値に対応する番地にある値

c

1/* 配列を降順に並べ替える */ 2void sortDesc(int len, struct seiseki *pt) 3{ 4 int i, j; 5 struct seiseki *tmp; 6 for(i = 0; i < len-1; i++){ 7 for(j = len-1; j > i; j--){ 8 if((pt + j)->kokugo > (pt + j - 1)->kokugo){ 9 *tmp = *(pt + j); 10 *(pt + j) = *(pt + j - 1); 11 *(pt + j - 1) = *tmp; 12 } 13 } 14 } 15}

さて,一見これで解決するように見えるんですが,これではセグメンテーション違反が起こってしまいます。なぜなら

c

1struct seiseki *tmp;

と宣言しても,用意されるのは『「seiseki を格納する番地」を入れるための変数』にすぎず,実際に「seiseki を格納する場所」がどこにも存在しないからです。なので,

c

1struct seiseki tmp;

として seiseki そのものを格納する場所を用意してあげなければなりません。最終的にコードはこうなります。

c

1/* 配列を降順に並べ替える */ 2void sortDesc(int len, struct seiseki *pt) 3{ 4 int i, j; 5 struct seiseki tmp; 6 for(i = 0; i < len-1; i++){ 7 for(j = len-1; j > i; j--){ 8 if((pt + j)->kokugo > (pt + j - 1)->kokugo){ 9 tmp = *(pt + j); 10 *(pt + j) = *(pt + j - 1); 11 *(pt + j - 1) = tmp; 12 } 13 } 14 } 15}

投稿2016/10/22 06:11

編集2016/10/22 06:26
mpyw

総合スコア5223

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

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

dec5798

2016/10/22 06:23

御解答ありがとうございます。 大変勉強になりました。 感謝しています。
mpyw

2016/10/22 06:27

C言語は代入式の左辺と右辺で * の扱いに違いがあったので訂正入れました,すみません
dec5798

2016/10/22 06:36

ありがとうございます。 確認させて頂きました。
guest

0

エラーメッセージは

c

1(pt + j) = (pt + j - 1); 2(pt + j - 1) = tmp;

の2行に出ているのではないでしょうか? (pt+j) や (pt+j-1) は演算結果なので、左辺値にはできず、代入することはできません。int a,b; a+b = 3;とはできないのと同じです。
このプログラムでは構造体の中身を入れ替えたいので、tmpの宣言を

C

1struct seiseki tmp;

に変更した上で、

C

1tmp = *(pt + j); 2*(pt + j) = *(pt + j - 1); 3*(pt + j - 1) = tmp;

のように変更する必要があります。

投稿2016/10/22 06:06

編集2016/10/22 06:13
mit0223

総合スコア3401

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問