人に聞けない痔の悩み、これでスッキリ >>

こんにちわ

C言語初心者です。

C言語の教科書を見ていたら
双方向リストへの挿入というところで
struct CELL{
struct CELL *prev;
struct CELL *next;
int value;
}
x->prev=p;
x->next=p->next;
p->next->prev=x;
p->next=x;
という記述がありました。

質問はこの部分で
p->next->prev=x;
アロー演算子が2個つくとどうなるんですか?

出来ればこの双方向リストの例でたとえてもらえるとうれしいです。

よろしくお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (2件)

複数の演算子が使われている式を計算する場合、


例1) A # B $ C

どの順番で計算を行うかは、演算子の優先順位と結合規則を元に決まります
例2) 優先順位が # < $ なら A # (B $ C)
例3) 優先順位が # > $ なら (A # B) $ C
例4) 優先順位が同じ、結合規則が「右から左」なら A # (B $ C)
例5) 優先順位が同じ、結合規則が「左から右」なら (A # B) $ C
参考) http://msdn.microsoft.com/ja-jp/library/2bxt6kc4 …

ご質問のケースですが、
アロー演算子どうし → 優先順位が同じ、結合規則が「左から右」
ついでにアローと代入 → 優先順位が アロー > 代入
なので、
p->next->prev = x;

(p->next) -> prev = x; // アローは「左から右」

((p->next)->prev) = x; // アロー > 代入

struct CELL* q = p->next;
(q->prev) = x;

意味合い的には、双方向リストの要素 p の次に x を挿入するため、
1. p の次の要素にて
2. 前への参照を
3. x に書き換る
と思われます
    • good
    • 0
この回答へのお礼

お返事ありがとうございました。

丁寧な説明でバッチシ理解できました。
ずっともやもや考えていたのでたすかりました。

お礼日時:2014/06/13 20:27

>アロー演算子が2個つくとどうなるんですか?



a+b がわかれば a+b+c もわかるのと同じ理屈です。

>p->next->prev=x;
は、
struct CELL *work;
work = p->next;
work->prev = x;
と同じだと言えばわかりますか?
    • good
    • 0
この回答へのお礼

お返事ありがとうございました。

とても参考になり理解できました。

お礼日時:2014/06/13 20:30

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QC言語 アロー演算子

このようなプログラムを作りたいのですが上手くいきません。
(入力と出力は必ずアロー演算子を使う。)
<実行例>
番号を入力:1
名前を入力:taro

番号:1
名前:taro
どなたかよろしくお願い致します

#include <stdio.h>
#include <string.h>

typedef struct{
int no;
char name[21];
}student;

void in(student *std){
char namae[21];
int bango,i=0;

scanf("%d", &bango);
std->no = bango;

while(1){
namae[i] = getchar();
if((i >= 20 ) || (namae[i] == '\n'))
break;
i++;
}
i++; namae[i] ='\0';
strcpy(std->name,namae);

}

void out(student *std){
printf("%d\n", std->no);
printf("%s\n", std->name);
}

main(){
student person;
in(&person);
out(&person);

return 0;
}

このようなプログラムを作りたいのですが上手くいきません。
(入力と出力は必ずアロー演算子を使う。)
<実行例>
番号を入力:1
名前を入力:taro

番号:1
名前:taro
どなたかよろしくお願い致します

#include <stdio.h>
#include <string.h>

typedef struct{
int no;
char name[21];
}student;

void in(student *std){
char namae[21];
int bango,i=0;

scanf("%d", &bango);
std->no = bango;

while(1){
namae[i] = getchar();
if((i >= 20 ) || (...続きを読む

Aベストアンサー

★ほぼ出来ていますが…。
・『in』関数の『while』の次にある『i++』は不要です。
・『while』ブロックの中で『i++』を行っているため必要ありません。
・場所分かりますか?→『in』関数の下から3行目の『i++』です。
・また、『namae[i] = getchar();』の行は、『namae[i] = (char)getchar();』と
 (char)キャストします。
・『while(1){}』は『for(;;){}』とすると警告メッセージが出ません。
・そして、一番重要なのが『scanf』関数の後(std->noの次など)に『fflush』の
 関数で標準入力をフラッシュさせます。
・こうしないとバッファに数字の『1』が溜まったままになってしまいます。

●修正(in関数のみ→他はあっています)
void in( student *std )
{
 char namae[ 21 ];
 int bango, i;
 
 scanf( "%d", &bango );
 std->no = bango;
 fflush( stdin ); ←ここがポイント
 
 for ( i = 0 ; ; i++ ){ ←この方が分かりやすいよ(初期化 ; 条件式 ; 増減式)
  namae[ i ] = (char)getchar();
  
  if( (i >= 20) || (namae[i] == '\n') ){
   break;
  }
 }
 ←ここにあった『i++』は不要です。
 namae[ i ] ='\0';
 strcpy( std->name, namae );
}

最後に:
・『for』文の2つ目の条件式を省略すると無限ループを構成します。
・『while(1)』でもループできますが、警告メッセージなどが出ます。
・よって、無限ループのときは『for(;;){}』という風にすれば良い。→3つ省略可能なのです。
・以上。おわり。

参考URL:http://www.bohyoh.com/CandCPP/C/Library/fflush.html

★ほぼ出来ていますが…。
・『in』関数の『while』の次にある『i++』は不要です。
・『while』ブロックの中で『i++』を行っているため必要ありません。
・場所分かりますか?→『in』関数の下から3行目の『i++』です。
・また、『namae[i] = getchar();』の行は、『namae[i] = (char)getchar();』と
 (char)キャストします。
・『while(1){}』は『for(;;){}』とすると警告メッセージが出ません。
・そして、一番重要なのが『scanf』関数の後(std->noの次など)に『fflush』の
 関数で標準入力をフラッシュ...続きを読む

QLNK2019: 未解決の外部シンボルのエラーが出る

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自キャラのデータ
Point2D g_jikipos = {40, 400};//自キャラの座標

//画像ハンドル
int g_jikiimage[11];

//色々なファイルの読み込み
int LoadFiles(){
//画像ファイル読み込み
if(LoadDivGraph("media\\player01.bmp",
11,11,1,64,64,g_jikiimage) == -1) return -1;

return 1;
}


 mymain.h
//他から呼び出させるMyMainの関数
void MyMain();
int LoadFiles();


 myhelper.h(サンプルなので打ちミスはない)
#include "DxLib.h"
#include <limits.h>
#include <math.h>

//構造体宣言
//座標またはベクトルを記録する構造体
struct Vector{
float x,y;
};
typedef Vector Point2D;
//線を記録する構造体
struct Line2D{
Point2D startpos, endpos;
float katamuki;//傾きをラジアン値で記録
Vector speed;//移動している場合は速度をセット
};
//球体を記録する構造体
struct Ball2D{
Point2D position;
float hankei;//半径
};
//四角形を記録する構造体
struct Rect2D{
Point2D lefttop;
Point2D rightbottom;
float width;
float height;
};


//ライブラリ関数
Point2D PosInView(Point2D in);
int XInView(float inx);
int YInView(float iny);
void ScrollToLeft(float jikiposx);
void ScrollToRight(float jikiposx);
void ScrollToUp(float jikiposy);
void ScrollToDown(float jikiposy);
void DrawLineInView(float x1, float y1, float x2, float y2, int Color, int Thickness);
void DrawCircleInView(float x, float y, float r, int Color, int FillFlag);
void DrawAnimation(float x, float y, double ExtRate, double Angle,int TurnFlag,
int *imgarray, int allframe, float fps);
//ベクトル関数
Vector CreateVector(Vector in, float veclen);
Vector AddVector(Vector v1, Vector v2);
Vector SubVector(Vector v1, Vector v2);
Vector AddVectorInFrameTime(Vector pos, Vector speed);
Vector AddVectorInFrameTime2(Vector pos, Vector speed, Vector accel);
Vector Normalize(Vector in);
Vector RotateVector(Vector in, float radian);
float VectorLengthSquare(Vector in);
float DotProduct(Vector v1, Vector v2);
float CrossProduct(Vector v1, Vector v2);
void SetLine2DKatamuki(Line2D *in);
void DrawLine2D(Line2D in, int Color, int Thickness);
void DrawBall2D(Ball2D in, int Color, int Fill);
//当たり判定関数
bool HitTestLineAndBall(Line2D linein, Ball2D ballin);
bool IsPointAtLineFace(Line2D linein, Point2D ptin);
bool HitTestLineAndLine(Line2D line1, Line2D line2);
bool HitTestBallAndBall(Ball2D a, Ball2D b);
bool HitTestPointAndBox(Rect2D rect, Point2D pt);
//タイマー関数
void SetSimpleTimer(int idx, int time);
int GetPassedTime(int idx);


//グローバル変数
extern float g_frametime;
extern Rect2D g_framerect;//画面領域(当たり判定)
extern Point2D g_current_field_pos;//現在の左上座標
extern Rect2D g_stagesize;//ステージサイズ

//定数宣言
const float ZEROVALUE = 1e-10f;
const float PIE = 3.1415926f;
const int SCROLL_LIMIT = 200;
----------------------------------------------------------------
 エラー内容
1>myhelper.obj : error LNK2019: 未解決の外部シンボル "void __cdecl MyMain(void)" (?MyMain@@YAXXZ) が関数 _WinMain@16 で参照されました
1>C:\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\my\Debug\my.exe : fatal error LNK1120: 外部参照 1 が未解決です
1>my - エラー 2、警告 0
ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ
----------------------------------------------------------------
画像を貼り付けときます
(見えにくい場合→http://www.dotup.org/uploda/www.dotup.org154142.jpg.html)
初心者なのでわかりやすくお願いします

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自...続きを読む

Aベストアンサー

ファイル構成から推測するに
mymain.cpp というファイルに
void MyMain(void) {
// ここに処理を書く
}
という関数が必要なようです。

Q「memcpy」と「strcpy」について

C言語の初心者です。
先日、課題として以下のようなことを言われました。

「memcpyとstrcpyについて、メモリ破壊が起こるとしたら
どんな場合が考えられるか、簡単にまとめて報告してみて下さい。」
と言われました。

私にはメモリ破壊というニュアンスが分からないのですが、
どちらの関数も必要以上にコピーを行ったときに
起こるメモリ破壊ということなのでしょうか?
それとも、何か特別な意味があるのでしょうか?

C言語に詳しい方がいましたら、是非、教えて下さい。
宜しくお願いします。

Aベストアンサー

 メモリ破壊とは、「当然そこに入っているべき値」を、不用意に上書きしてしまうことです。

 たとえば、char a[100]; という宣言をしたとします。

 memcpy( a, 0, 200 );

 すると、このような実行を行った場合、変数 a の後ろにどんなメモリが存在しているのかプログラマは知ることができないのに、変数 a の後ろの未定メモリ100バイトを上書きしてしまいます。

 この未定メモリには、もしかしたら別の変数があるかもしれませんし、プログラムの一部があるかもしれません。あるいはOSのシステム領域かもしれません。
 どのみちプログラムは正常に動かなくなります。
 通常はメモリエラーが出て停止しますが、最悪の場合、メモリ上のOSを破壊してリセットするしかなくなったりもします。

 これがメモリ破壊です。

Q引数 戻り値 return文について

今、C言語を初めて勉強してます。

勉強していて、引数と戻り値、return文

についてよくわかりません。

どなたか詳しく素人にもわかるように教えて

頂けないでしょうか?よろしくお願いします。

Aベストアンサー

まず、関数とは何らかの処理をして結果を返してくれるものです。わざとらしい例ですが二つの数を足してその結果を返す関数を見てみましょう。

#include <stdio.h>

int add( int hoge, int piyo ){
return hoge + piyo;
}

int main(void){
int data;

data = add( 253, 434 );
printf( "%d", data );

return 0;
}

見てわかると思いますが、引数とは関数内の処理に使うデータです。
このデータは関数を呼び出すときに与えます。

add( 253, 434 )

すると与えられたデータは関数に渡され仮引数と言うものに格納されます。
この例では hoge に 253、piyo に 434 が格納されます。

int add( int hoge, int piyo ){

この仮引数は普通の変数のように使うことが可能なのです。

hoge + piyo

そしてこの結果を戻り値として return 文で返してやります。

return hoge + piyo;

返すとは具体的にどこへ返すのかと言うと呼び出したところへです。
ここでは main 関数内の呼び出し元です。

data = add( 253, 434 );

data と言う変数へは関数によって返された戻り値(関数値とか返却値とかとも言ったりします)が格納されます。つまり 253 と 434 を足した数です。

引数も戻り値も結局はデータです。処理させたいデータが引数で、処理した結果であるデータが戻り値です。

return は呼び出し元へ結果を返すためのものです。


C言語の関数にはいろいろな種類があります。

引数も戻り値もあるもの。

int add( int hoge, int piyo ){
return hoge + piyo;
}

引数はあるが戻り値のないもの。

void add( int hoge, int piyo ){
printf( "%d", hoge + piyo );
}

戻り値はあるが引数のないもの。

#include <stdlib.h>
#include <time.h>

int getRandNum(void){
srand( time( NULL ) );
return rand() % 500;
}

戻り値も引数もないもの。

void print(void){
printf( "%d + %d = %d", 253, 434, 253 + 434 );
}

これらの使い分けはデータの内容や型、処理の内容により適宜必要なものを使ってください。

まず、関数とは何らかの処理をして結果を返してくれるものです。わざとらしい例ですが二つの数を足してその結果を返す関数を見てみましょう。

#include <stdio.h>

int add( int hoge, int piyo ){
return hoge + piyo;
}

int main(void){
int data;

data = add( 253, 434 );
printf( "%d", data );

return 0;
}

見てわかると思いますが、引数とは関数内の処理に使うデータです。
このデータは関数を呼び出すときに与えます。

add( 253, 434 )

すると与...続きを読む

Qint型からchar型への変換

タイトル通り、int型からchar型への変換の仕方がわかりません!><
どうしたらいいのでしょうか?

Aベストアンサー

#include <stdio.h>


char buf[5];
int no;

no = 10;
sprintf(buf, "%d", no);

Q->記号って?

超初心者の質問です。
サンプルプログラムを見ていて
free(pexdata->data);
という記述がありました。

ここでの"->"ってどういう呼び方で何なのでしょう?
機能の呼び名がわかれば調べ方がわかりますので、そこからは調べようかと思っている次第です。

聞きたい物の例としてずばり、「関数」とか「クラス」とか呼び名を教えてください。ちょっとした説明も入れていただけると尚Goodですが。

どなたかご教授ください。お願いします。

Aベストアンサー

そうですね…

pexdataが正しい構造体または共用体のポインタ式であるとした場合、

1.pexdata->data
2.(*pexdata).data

上記の二つは同じ意味です。

つまり、構造体または共用体を指すポインタから直接その構造体または共用体のメンバにアクセスするための演算子です。

->演算子の->の部分の読み方は#3の回答どおり、特に定義されてはいません。

いくつか解説ページをあたってみると
演算子 ->
http://www.wakuhoku.ac.jp/~kanayama/C/03/node135.html

間接参照「->」
http://www.komonet.ne.jp/~c/chap33.htm

アロー演算子
http://wisdom.sakura.ne.jp/programming/c/c36.html
http://www9.plala.or.jp/sgwr-t/c/sec15-3.html

矢印記号(->)
http://www.kumei.ne.jp/c_lang/intro/no_28.htm

…みごとにばらばらですね。

そうですね…

pexdataが正しい構造体または共用体のポインタ式であるとした場合、

1.pexdata->data
2.(*pexdata).data

上記の二つは同じ意味です。

つまり、構造体または共用体を指すポインタから直接その構造体または共用体のメンバにアクセスするための演算子です。

->演算子の->の部分の読み方は#3の回答どおり、特に定義されてはいません。

いくつか解説ページをあたってみると
演算子 ->
http://www.wakuhoku.ac.jp/~kanayama/C/03/node135.html

間接参照「->」
http://www.komo...続きを読む

QC言語の enum の使い方

インターネットのサイトなどを利用してC言語を勉強しています。 いま一通り基本的な勉強が済んだところですが、enum というユーザー定義変数をどんな風に使えばよいのか、今ひとつわかりません。サンプルコードなどを見ても、 enum でなくても配列を使えば出来そうなものが多いのですが、この型の変数はどう使えば効果的なのでしょうか。
詳しい方、どうかよろしく教えてください。

Aベストアンサー

>enum というユーザー定義変数を

変数ではないでしょう。
むしろ定数かと。

>enum でなくても配列を使えば出来そうなものが多いのですが

具体的になにがあります?
ちなみに配列ではありませんので誤解なきよう。

http://homepage2.nifty.com/well/enum.html
とか、いい感じに説明されていますかね。
defineだとただの置き換えなので何でも設定できてしまう。とか型チェックができない。とかの問題があります。

私自身、最近使ったやり方では…テーブルのインデックス用に使いましたね。

Qバッファとは何ですか

C言語を使用してるとバッファという言葉がよく出てきますがバッファとは何ですか
メモリとは違うものですか
訳をみても緩衝材とか一時的に蓄える場所という意味でよく分かりません
一時的でない使い方も多い気がしますが実際はどういうものですか

Aベストアンサー

#1です

寝ぼけて適当に書いたので修正。

すぐ見つけることができたもので正確なものは英語版ですがこちらくらいかも。
Data buffer - Wikipedia (en.)
http://en.wikipedia.org/wiki/Data_buffer

一応簡単なものはこちらです。
バッファとは - e-Wrods
http://e-words.jp/w/E38390E38383E38395E382A1.html

「複数の機器やソフトウェアの間でデータをやり取りするときに、処理速度や転送速度の差を補うためにデータを一時的に保存しておく記憶装置や記憶領域のこと。」
が現在の基本定義です。処理速度・転送速度の差のための緩衝材的な意味です。

昔はソフトウェアとハードウェア間に使うデータでソフトウェア側がデータを受け取るか、整形して送信するときに使うメモリ領域が基本的にバッファでした。
マルチプロセッサ・マルチタスクの時代になってくると、ソフトウェア間の処理速度の違いを吸収するために使うメモリ領域にもバッファという言葉が使われるようになりました。ソフトウェア間で逐次(FIFO)処理されるデータのためのメモリ領域がこちらの使われ方の主戦場といったところでしょうか。

ソフトウェア間でただ一括転送されるデータならバッファという言葉は誤用ということになるのですが、よく誤用されます。

#1です

寝ぼけて適当に書いたので修正。

すぐ見つけることができたもので正確なものは英語版ですがこちらくらいかも。
Data buffer - Wikipedia (en.)
http://en.wikipedia.org/wiki/Data_buffer

一応簡単なものはこちらです。
バッファとは - e-Wrods
http://e-words.jp/w/E38390E38383E38395E382A1.html

「複数の機器やソフトウェアの間でデータをやり取りするときに、処理速度や転送速度の差を補うためにデータを一時的に保存しておく記憶装置や記憶領域のこと。」
が現在の基本定義です。処理速度・転送速...続きを読む

Q文字列がNULLか空文字列かの判定

Visual C++で、Cのプログラムを作成しているものです。(OS:WinNT 4.0)
文字列の扱いについて、質問します。

関数 int func(char *str) があると仮定します。
パラメータとして、strは以下のような状態あるとします。
(strは関数が呼ばれる前にcalloc()で領域確保済み)
 シンボル名 値
 str      0x00000001 ""
上記の状態で、strがNULLか空文字列("")であることを条件式にしたいのですが、str == NULL は偽となり、strcmp(str, "") を使用すると異常終了します。
どうしたらよいのでしょうか。アドバイスをお願いします。

Aベストアンサー

No1の方の回答にあるように、calloc()で取れた領域のアドレスを正しく渡せてないように思えますが...

#defineERROR(-1)

int func(char *str)
{
  if( (!str) || (!strlen(str)) ) return ERROR;
  return strlen(str);
}

void main()
{
  char *p=(char*)calloc(10,10);
  printf("%d\n",func(p));
}

Q関数とメソッドの違い

初歩的な質問なのですが、
関数とメソッドの違いが分からず悩んでいます。
書籍や人によって、
関数とメソッドは同じ物として書いている物もあれば、
メソッドはクラスに関連付いた関数としていたり、
クラスでもpublic関数だけとか、
引数のある物がメソッド、
逆に無い物がメソッド等々…で、
どれが正しいのか良く分からないのです。

関数とメソッドの違いを教えていただけますよう、
お願いいたします。

Aベストアンサー

正解だけ先に言っておきましょう。オブジェクト指向での定義は
「メソッドとは、オブジェクトに送られてきたメッセージを処理するモノ」
「関数とは、メソッドの実装」
ついでに、
「メッセージとは、オブジェクトに何かしらお願いするために送られるモノ」
です。メッセージとメソッドと関数は明確に違うのですよ。


上記の通りなんですが、質問の文について、なにが正しいか、という解答は「文脈による」としか言いよ
うが無いんです。
解説書の一部分だけ抜き出して考えるのは非常に危険な行為です。
文脈を色々変えてみます。例えばオブジェクト指向の話をしているとしたら、

>1. 関数とメソッドは同じ物として書いている物もあれば、
バツ。意味的に全く異なります。
'\0'と""とNULLと0くらい違います。等価なんていってしまったら石が飛びます。(私が投げます:-p)

> 2.メソッドはクラスに関連付いた関数としていたり、
サンカク。C++での実装はそうでしょうが、オブジェクト指向を考える上で、その考え方は危険です。

> 3.クラスでもpublic関数だけとか、
> 引数のある物がメソッド、
> 逆に無い物がメソッド等々…で、
バツ。引数の数でメソッドで無くなる?そんなバカな!
例えprivateでもメソッドですよ。


オブジェクト指向言語C++のことを考えよう!という文脈ならば、
1.サンカク。実装は確かにそうなってます。ですが、上記の通り意味的に違うんです。
2.○。C++において、メソッドは「クラスに関連ついた関数」として実装されてます。
3.そんなわけないでしょう。

オブジェクト指向?なにそれ?構造体に関数がくっついただけでしょ?と乱暴極まりない文脈なら、
1.○。当然!
2.なにいってるの?
3.サブルーチンとファンクションの違いだ!


と、文脈で全然変わるんですよ。これに関しては、本一冊だけだとなかなか気付きにくいです。
是非とも多数の本を読み比べることをお勧めします。

正解だけ先に言っておきましょう。オブジェクト指向での定義は
「メソッドとは、オブジェクトに送られてきたメッセージを処理するモノ」
「関数とは、メソッドの実装」
ついでに、
「メッセージとは、オブジェクトに何かしらお願いするために送られるモノ」
です。メッセージとメソッドと関数は明確に違うのですよ。


上記の通りなんですが、質問の文について、なにが正しいか、という解答は「文脈による」としか言いよ
うが無いんです。
解説書の一部分だけ抜き出して考えるのは非常に危険な行為です...続きを読む


人気Q&Aランキング