トップページ⇒tech
1001コメント282KB

C言語なら俺に聞け<35>

■ このスレッドは過去ログ倉庫に格納されています
0001未定義?ということにしたいのですね? :)NGNG

マターリ未定義論争でもしましょうか。
もちろん質問も受け付けますよ。それがメインですし。
課題丸投げ?それは別スレでやってください。


・C FAQ 日本語訳
http://www.catnet.ne.jp/kouno/c_faq/c_faq.html
・comp.lang.c FAQ(英語の原文)
http://www.eskimo.com/~scs/C-faq/top.html
Cプログラマ必読 ・プログラミング言語C(通称 K&R)
http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/
推薦図書/必読書のためのスレッド PART6
http://pc3.2ch.net/test/read.cgi/tech/1033207156/

・前スレ <34>
http://pc3.2ch.net/test/read.cgi/tech/1033240509/

コンパイラ、過去ログなどのリンクは>>2-5 あたり
0153152NGNG
long *だと渡せるのは2番だけだな。
0154デフォルトの名無しさんNGNG
>>151
さっさとその先輩のことは忘れて他の先輩に付いてください
0155デフォルトの名無しさんNGNG
151の救いはプロのプログラマーってわけじゃなくて、趣味でやっているってことだね。
0156デフォルトの名無しさんNGNG
>>151
ソース上での意味は違うけど、結局はほとんどの処理系で
どれも同じになるんじゃないの?
(キャストしないと警告は出るだろうけど)
0157デフォルトの名無しさんNGNG
>>155
脳内にお告げでもあったのですか?
0158151NGNG
>>152=153
いや、関数の大元は別会社から指定されてて・・つまりライブラリね。
void func( long * ); 、long型のポインタで与えてくださいって言われています。

で、2番しか渡せないはずなのだが先輩曰く

「どちらもアドレスの先頭を渡すことになるだろ。
 data という変数の [0] 個目、 & でアドレス渡しだ。
 だから、&data[0] は data[0][0] のアドレスを渡す、という意味になるから
 &data[0] も &data[0][0] も同じ意味だ。確かにお前の &data[0][0] のほうが見る者にとっては
 親切な書式になるが、結果は同じだから特に気にすることはない。
 あと、C言語では 配列数を省略してかくとポインタになるのは知っているだろ?
 だから、data[0][0] を data だけで書いても、コンパイル結果はまったく同じになる。
 どうでもいいような知識かもしれないけど、知っておいて損はないぞ。」

という話なんですね。1の場合、確かに意味的には通りそうなんだけど、C言語の基本から考えると
違うような。1の場合、いったいどういった情報が渡っているのでしょうか?

>>154
今のプロジェクト、その先輩と同期3名だけなんです・・・

>>155
思い切り仕事です・・・
0159デフォルトの名無しさんNGNG
ちょっと質問だけど関数ポインタで

struct st1{
int n
void (*func)(int n);
}ST1;

void func1(int n) {
.
.
return;
}

void func2(int n) {
ST1 st;

st.func = func1;
(func)(n);
return;
}

こういうのってありですか?
0160デフォルトの名無しさんNGNG
>>159
(func)(n)のfuncはどこからもってきたんだ?
st.func(n)や(*st.func)(n)ならわかるが。
0161デフォルトの名無しさんNGNG
>>158
data = &data[0] = &data[0][0] だ。
いずれにせよ、関数に渡るのはアドレスだけ。それ以上の情報は渡らない。

二次元配列を渡すときに 配列名だけを渡すのはそんなにおかしくは無いと思う。
0162デフォルトの名無しさんNGNG
>>158
long data[20][13];
long *p = &data[0][0]; // OK
long *q = data[0]; // OK
long *r = data; // 文法上ダメ。意味的にはOK
long *s = &data[0]; // 文法上ダメ。「data」と同じ。
data[0][0] = 123456789;
printf ("data[0][0]=%d *p=%d *q=%d *r=%d *s=%d\n", data[0][0], *p, *q, *r, *s);
0163デフォルトの名無しさんNGNG
>>160
ああそっか。関数ポインタって言っても構造体のメンバだもんね。
ちなみに159のは構造体の定義をtypedefしている物として読んでください。
そしてまた新たな質問なんだけど(*st.func)(n)
ってのはどういう意味になるのですか?
メンバにセットしたアドレスの実態を現しているのですか?
0164デフォルトの名無しさんNGNG
>>158
二次元配列のサイズを変える気がないなら、
ちゃんと引数の型を適合させて long (*)[13] にすればいいし、
一次元配列に解釈しなおして渡すなら、
ちゃんと (long *)data とキャストすればいい。
0165デフォルトの名無しさんNGNG
getopt()ってLinuxとかUnix特有の関数ですか?
標準関数ではないですよね?
0166デフォルトの名無しさんNGNG
>>163
st.func(n)と同じ。
0167デフォルトの名無しさんNGNG
>>165に便乗質問。

色んなソース見てると、大抵自作のgetopt.cが入ってるんだけど、何故?
0168デフォルトの名無しさんNGNG
>>165
google

>>167
標準関数ではない=他の環境でもコンパイル出来るように。
既存の(標準的な動作をする)実装とは違う動作を求めていたので。
glibcの実装がメジャーどころだけど、GPLは嫌なので。

思い当たるのはこんなところです。
0169デフォルトの名無しさんNGNG
だれかたすけて・・・
#if defined(WIN32)
#include <windows.h>
#endif

#include <stdlib.h>/* @@@@ */

typedef struct _node Node;
int i=0;
/* セルの構造体 */
struct _node {
Node *next; /* 次の要素へのポインタ */
int value; /* 値 */
};

/*
セルの挿入関数
*/
void insert( Node *header, int a )
{
Node *p, *q, *new;

/* リストの最後のノードまで移動する */
p = header->next;
q = header;

0170デフォルトの名無しさんNGNG
>>169
ハァ?
0171デフォルトの名無しさんNGNG
void delete(Node *header ,int b)
{
Node *p ,*q;
p=header->next;

while ( p != NULL )
{
printf(":%d:",b);
printf("[%d]",p->value);
if (p->value==b)
{
header->next=p->next;

free(p);
//p の領域の解放;
printf("/%d/",b);
return;
}
p = p->next;
}
return;
}
0172デフォルトの名無しさんNGNG
線形リストの
delete関数なんですけど
うまくいきません
どこがちがうのでしょう??
0173デフォルトの名無しさんNGNG
何をしたいのか、まず、図にしてみる。
0174デフォルトの名無しさんNGNG
バカに何を言っても
ムダ
0175通りすがりの仕事中NGNG
>>169
ツッコミどころがイパーイあります。
0176デフォルトの名無しさんNGNG
これは無視してください
0177デフォルトの名無しさんNGNG
コードは読んでないけど、
ちゃんと「消したいノードの直前のノード」のポインタは保持してる?
0178デフォルトの名無しさんNGNG
>> 実は穴があくほどソースを読んだ、に1000clock
0179177NGNG
>>178
よんでねぇっす。
つーか、listのdelete操作でのはまりポイントってそこしかないでしょ。

せめてインデントしてあれば、読んだんだがな。
0180デフォルトの名無しさんNGNG
そうですたぶんそれです。
けしたノードのまえのノードが消えてるような気がするんです。
0181デフォルトの名無しさんNGNG
std::list使え

0182デフォルトの名無しさんNGNG
でも具体的に何をすればいいか・・・
0183デフォルトの名無しさんNGNG
std::listですね
0184デフォルトの名無しさんNGNG
boost::graph使え
0185デフォルトの名無しさんNGNG
>header->next=p->next;
最初のほう全部消えないか?
0186デフォルトの名無しさんNGNG
きえちゃいます。。。
0187デフォルトの名無しさんNGNG
動作的にはvalueがbになるノードを一つ消したいの?
0188デフォルトの名無しさんNGNG
そうです!!!
0189デフォルトの名無しさんNGNG
わかった。今から書いてみる。
0190デフォルトの名無しさんNGNG
もう下らんバグを作れなくていいようにこつを教えてあげるよ。

君の目の前に君よりさらにできの悪いやつがいると思いなよ。
そいつに対して君のコードを1行1行何をどうしてどうやってるのか説明してやるんだ、
すんなり説明できなきゃそのコードはどこかおかしい。

# しかし、すんなり説明できないコードを書いてる時点でどこか頭おかしいんだが。
0191デフォルトの名無しさんNGNG
わかりました。。
0192デフォルトの名無しさんNGNG
こうかな。でもp=header->next;っておかしくない?
void delete(Node *header ,int b)
{
Node *p ,*q;
p=header->next;

while ( p != NULL )
{
printf(":%d:",b);
printf("[%d]",p->value);
q = p->next;
if (q != NULL && q->value==b)
{
p->next=p->next;

free(p);
//p の領域の解放;
printf("/%d/",b);
return;
}
p = p->next;
}
return;
}
0193デフォルトの名無しさんNGNG
p->next=p->next;は
p->next=q->next;で。
0194デフォルトの名無しさんNGNG
free(p);も
free(q);で。
0195デフォルトの名無しさんNGNG
わかりました
ためしてみます。
0196デフォルトの名無しさんNGNG
できました!!!!!

0197デフォルトの名無しさんNGNG
ほんとにありがとうございます!!!

あのお聞きしたいのですが
あなたはプログラム暦
何年ぐらいなんですか??
0198デフォルトの名無しさんNGNG
ほんとに192でいいの?
一番目と2番目のノード消せる?
0199デフォルトの名無しさんNGNG
はいこれで良いです。
valueがbのノードだけが消えているので
問題はありません。
あとp=headerでもよかったみたいです。
0200通りすがりの仕事中NGNG
>>169
void delete(
Node **header, // ポインターのポインター!!(純カラになったときのため)
int b)
{
Node *p ,*q,
Node *nxtcel = NULL; // pの次のセル
Node *prvcel = NULL; // pの前に存在するセル
while ( p != NULL ) {
printf(":%d:",b);
printf("[%d]",p->value);

nxtcel = p->next; // 消去する前に次のセルをセット!!!

if( p->value == b ) {
if( p == *header ) { // 消したいセルが一番先頭のときの処理
*header = (*header)->next;
} else if( p->next == NULL ) { // 消したいセルが一番最後のときの処理
prvcel->next = NULL;
} else { // 中間のセル
prvcel->next = p->next;
}
free(p);
printf("/%d/",b); //p の領域の解放;
return;
}
prvcel = p;
p = p->next;
}
return;
}
0201通りすがりの仕事中NGNG
んがっ!前のスペースが消えてもぉたー
0202デフォルトの名無しさんNGNG
おおすごい
0203デフォルトの名無しさんNGNG
リスト処理か。何度書いたことだろう。。
0204デフォルトの名無しさんNGNG
すごいです。
2chの人たちは。。。
ちょっと感動しました・・・
0205通りすがりの仕事中NGNG
スレを汚してスンマソ、こっちでヨロ
void delete(
Node **header, // ポインターのポインター!!(純カラになったときのため)
int b )// 消したいナンバー
{
 Node *p;
 Node *nxtcel = NULL;// pの次のセル
 Node *prvcel = NULL;// pの前に存在するセル
 
 for( p = *header; p != NULL; p = nxtcel) {
  printf(":%d:",b);
  printf("[%d]",p->value);
  nxtcel = p->next; // 消去する前に次のセルをセット!!!

  if( p->value == b ) {
   if( p == *header ) { // 消したいセルが一番先頭のときの処理
    *header = (*header)->next;
   } else if( p->next == NULL ) { // 消したいセルが一番最後のときの処理
    prvcel->next = NULL;
   } else { // 中間のセル
prvcel->next = p->next;
 }

   free(p);
   printf("/%d/",b); //p の領域の解放;
   return;
  }
  prvcel = p;
}
 return;
}
0206デフォルトの名無しさんNGNG
>>204
それは馬鹿にしているとしか思えない発言なのだが。

タテマエ:すごいです。
ホンネ:こんな誰でもわかることよく自慢げにかけるよな。
0207デフォルトの名無しさんNGNG
・・・
そういうつもりでかいたわけじゃないのですが・・・
0208デフォルトの名無しさんNGNG
まあここ2ちゃんだし
0209デフォルトの名無しさんNGNG
素直じゃないね
0210デフォルトの名無しさんNGNG
>>206
ひねくれ屋さんだな。

素直に「お前の技術が低いだけだよ、2ちゃんだからじゃないんだよ」
と教育してやれよ
0211デフォルトの名無しさんNGNG
あのー
ポインタに浮動小数点の値を持たせることはできるのですか?
0212デフォルトの名無しさんNGNG
double x;
double *y;
y = &x;
ってことか?
0213デフォルトの名無しさんNGNG
>>211
もしかして 0.25 番目のアドレスを保持したいとかですか?
0214デフォルトの名無しさんNGNG
そうじゃなくて
配列をポインタで実現したときに
小数を持たせることができるかということなんですが。
0215デフォルトの名無しさんNGNG
>>214
ネタは下げてくれ
ネタじゃないなら自分以外にもわかる言葉でお願い
0216デフォルトの名無しさんNGNG
>>214
意味不明だが、できないと言っておく
0217デフォルトの名無しさんNGNG
>>214
こうですね?
unsigned int a[2] = { 0, 0xFFFFFFFF }; /* int は 32bit と仮定する */
unsigned int b = *(a+0.5); /* b = 0xFFFF0000 のはず!! */
0218デフォルトの名無しさんNGNG
ポインタに小数を足せるのか・・・・


いつの間にクッキー強制になったんだ。うぜーーー!!
0219デフォルトの名無しさんNGNG
質問です
int main(void)
{
int x = 10;
funcA(&x);
return 0;
}

void funcA(const int *a) //この関数では*aは変更しない、ということをconstで示したい
{
funcB((int *)a); //funcB()では変更するのでキャスト
}

vod funcB(int *b);
{
*b = 20;
}

というconstの使い方はアリですか?
0220デフォルトの名無しさんNGNG
scanfで読みこんだ数字を大きい順に並び替えたりするのって
どうやればいいですか?
0221デフォルトの名無しさんNGNG
>>219
漏れ的にはダメ

>>220
配列に格納してソート
0222デフォルトの名無しさんNGNG
宿題なら宿題スレがあるけど。
0223デフォルトの名無しさんNGNG
>>219
なんのためのconstだよ。

>>220
配列にいれてqsortライブラリ関数
0224デフォルトの名無しさんNGNG
>>219
全然駄目じゃん

> void funcA(const int *a) //この関数では*aは変更しない、ということをconstで示したい

とかいいながら

> funcB((int *)a); //funcB()では変更するのでキャスト

変更してるし・・・
0225デフォルトの名無しさんNGNG
ソートソート!!

ソートソート!!
0226220NGNG
>>221
その配列に格納するって言うのがわからないのですが。。
0227デフォルトの名無しさんNGNG
>>226

int array[5];

scanf("%d",array);
中略
scanf("%d",array+4);
0228220NGNG
なるほど。a[20]とかは使ってましたが、ソートなんてのがあるのは
知りませんでした。ちょっと調べてきます。
0229デフォルトの名無しさんNGNG
C/C++の宿題なら俺にやらせろ!

http://pc3.2ch.net/test/read.cgi/tech/1021862587/l50
0230デフォルトの名無しさんNGNG
>>228
何か、ソートについて勘違いしてないか?
0231デフォルトの名無しさんNGNG
線形リストの操作は大学の1年生のときにやった。
プログラムなんて全く知らない奴らも理解できたくらいだから、
>>197の質問は「3ヶ月以上なら大抵出来る」だろ。
0232デフォルトの名無しさんNGNG
大学じゃなくても専門ドキュソの俺でもわかる。
0233デフォルトの名無しさんNGNG
大学どころか専門でもない俺でもわかる。
0234manko_chinko ◆GLc2rpKRNM NGNG
中学生の俺でもわかる
0235デフォルトの名無しさんNGNG
猫である我輩でもわかる
0236デフォルトの名無しさんNGNG
小学生のときに自力で実装した。
0237デフォルトの名無しさんNGNG
1の母ですが分かります。
0238デフォルトの名無しさんNGNG
自作して使ってたがこれが線形リストと呼ばれる代物だと
知ったのはつい最近のこと。高卒ですから。
0239デフォルトの名無しさんNGNG
>>238
それを車輪の再発明と言う。
0240デフォルトの名無しさんNGNG
再開発だろ。
0241デフォルトの名無しさんNGNG
>>238
よくあるよね。これ名前ついてるじゃん!とか言うの。

まぁ、名前知ってても実装できないライブラリ厨はいくらでもいるんで心配しなくてもいいかと。
むしろ、プログラムを作るという面ではあなたの方が強いと思われ。
0242238NGNG
>>239
車輪の再発明という言葉を知ったのも
つい最近のことだったりする。
0243デフォルトの名無しさんNGNG
リストなんて再発明も何もかなり基本的な構造じゃん
たとえ名前知らなくても何気なく使うもんだと
0244デフォルトの名無しさんNGNG
>>243
逆に配列の限界に気づかないでPGやってる奴とかって恐ろしいな・・・
0245238NGNG
>>241
ありがとう。

> よくあるよね。これ名前ついてるじゃん!とか言うの。
そうそう。たとえば文字列の比較など、ごく単純なものでも
立派なアルゴリズムの名前がついてるのを知って
ビックリした覚えがある。
0246デフォルトの名無しさんNGNG
> これ名前ついてるじゃん!
あるある。みんな経験あるんだな。
0247220NGNG
220ですが
int a[10];
int i,j,k,m,l;

for(i=0;i<10;i++){
printf("a[%d]=",i);
scanf("%d",&a[i]);
}

for(j=0;j<10;j++){
for(k=j;k<10;k++){
m=a[j]-a[k];
if(m<0){
l=a[k];
a[k]=a[j];
a[j]=l;
}
}
}
みなさんのいっているソートっていうのは、
こーゆーのを、勝手にやってくれる言語があるっていうことですか?
0248デフォルトの名無しさんNGNG
>>247
勝手にと言うか結局はそう言う個としてると思われ。
単に誰かが汎用的に使えるように関数化なりクラス化なりしてくれてるだけで。
0249デフォルトの名無しさんNGNG
>>247
言語じゃなくて関数(^_^;)
stdlib.hにqsortってのがあるでしょ。
0250デフォルトの名無しさんNGNG
あっても使いこなせない罠。
比較用の関数作んなきゃいけないし。
0251デフォルトの名無しさんNGNG
>>247
バブルソートか。
0252デフォルトの名無しさんNGNG
>>247
ちなみに、
ある一定の規則に従って、
並べ替えることをソートという
■ このスレッドは過去ログ倉庫に格納されています