[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 801- 901- 2chのread.cgiへ]
Update time : 06/24 02:11 / Filesize : 245 KB / Number-of Response : 928
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

C言語なら俺に聞け(入門編)Part 63



1 名前:デフォルトの名無しさん [2010/04/10(土) 23:30:23 BE:454421186-S★(520172)]
C言語の*入門者*向け解説スレッドです。
★前スレ
C言語なら俺に聞け(入門編)Part 62
pc12.2ch.net/test/read.cgi/tech/1269517734/
★過去スレ
makimo.to:8000/cgi-bin/search/search.cgi?q=%82b%8C%BE%8C%EA%82%C8%82%E7%89%B4%82%C9%95%B7%82%AF&andor=AND&sf=0&H=&view=table&D=tech&shw=5000
★初心者、初級者の方は他の質問スレのほうが良いかもしれません。
例えば
【初心者歓迎】C/C++室 Ver.72【環境依存OK】
pc12.2ch.net/test/read.cgi/tech/1267775473/
とか
★教えて欲しいのではなく宿題を丸投げしたいだけなら
↓宿題スレ↓へ行ってください。
C/C++の宿題片付けます 135代目
pc12.2ch.net/test/read.cgi/tech/1269438098/
★C++言語についてはなるべく聞かないでください。C++対応明記スレへどうぞ
★分からない事をなるべく詳しく書いて下さい。
★ソースコードを晒すと答えやすくなるかもしれません。
  # 抜粋/整形厳禁、コンパイラに渡したソースをそのまま貼ること
  # サイズが大きい場合は宿題スレのアップローダ等を利用してください
★開発環境や動作環境も晒すと答えが早いかもしれません。
★質問者は最初にその質問をした時のレス番号を名前欄に書いて下さい。

314 名前:デフォルトの名無しさん [2010/04/23(金) 14:25:37 ]
intの2次元配列を使いたいのですが、int hoge [作りたい数]「ここ」←ここはなにを表してるのですか?
charならバイト数だと思うのですが、intはバイト数が決まってたと思うのですが
作りたい数までの各番号に対応したintを取り出したいのです

315 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 15:03:35 ]
>>314
お前がいうところの2次元配列ってなんだ?

世間では要素が n 個の配列(1次元配列)は hoge[n] であり、
要素が n x m 個の配列(2次元配列)を hoge[n][m] で表す。

1次元で足りるなら1次元配列を使え。

316 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 15:03:44 ]
それなら1次元配列でよくね?

317 名前:デフォルトの名無しさん [2010/04/23(金) 15:05:53 ]
つまりint hoge[作りたい数]でいけるってことですか。
そういう使い方を全然知りませんでした。ありがとうございました

318 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 15:06:33 ]
>>314
int hoge[3]; はintが3個並んでる。
int hoge[3][4]; はintが4個並んだものが3個並んでる。
hoge[0][0], hoge[0][1], hoge[0][2], hoge[0][3], hoge[1][0], hoge[1][1], ... の順で。

intのバイト数は規格で固定されてはいない。
実際にコンパイルする時にその環境で何バイトになるのかはそりゃ決まってるけど。
今はPCの環境だとほとんど4バイト。

319 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 15:16:51 ]
charでバイト数を指定して2次元配列、か。
それはたぶん文字列の配列を作ろうとしていたんじゃないかな。

320 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 18:05:22 ]
C言語でシーザー暗号の解読プログラムを作っています。
手順としては、暗号化された文字列を入力して1つずつ文字列をずらして
26通りの文字列を出力するプログラムです。

#include<stdio.h>
int main(void)
{
char ang[8]; //今回は最大8文字の文字列
int i,j;

for(i=0;i<26;i++){
for(j=0;j<8;j++){
printf("%c",ang[j]+i);
}
}

初めはASCIIコードのZとaが繋がっているものと思いこう組んだら
Zの後には記号が入っていて詰まってしまいました。
A-Zまでの配列を作ってその中で回す、とかASCIIコードでもZの次をAにする
とか色々考えましたが、どうしていいのかが分からないです…。

ご指導お願いします。

321 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 18:10:44 ]
(ang[j] - 'A' + i) % 26 + 'A'

322 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 18:28:17 ]
>>320
isalpha()



323 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 18:37:27 ]
>>320
本題とは関係ないが、
>char ang[8]; //今回は最大8文字の文字列
ang[8]だと最大7文字の文字列な

324 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 18:41:29 ]
NUL終端文字列とは言ってないので、間違っていない
それにprintf("%c",ang[j]+i);だから、NULは必要としていないと読める

325 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 18:50:38 ]
ポインタ無隋って聞いたけど
C言語の入門書とかに書いてるような小さいサンプルコードだと
全然難しくなくて何が難しいのかわからなかった。

ポインタってなんかむずかしい部分あるの?

326 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 18:51:26 ]
NUL終端w

327 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 18:53:34 ]
分かる人には難しくない、分からない人には難しい。
慣れればどうってことはない。

328 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 19:00:50 ]
>>325
入門編が難しいはずない。

329 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 19:04:05 ]
初心者は、LinkedListを自前で実装してみ?って言われて初めて、
自分がポインタを理解していないことに気づくもの。

330 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 19:07:33 ]
>>325
人によるんじゃない?
俺は関数ポインタの理解が遅かったけど、いざ理解したらなにが難しかったのか分からなくなったな

331 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 19:11:03 ]
何も有益な情報は残さずに読むものを不快にさせるだけのレスをするやつは死ねばいいのにな

332 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 19:12:48 ]
int (*(*foo)(int (*(*)(void))(void)))(int (*)(void))



333 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 19:13:21 ]
俺は死ねばいいとか思わないけど、なんで>>331は自殺しないの?

334 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 19:20:08 ]
ポインタと配列がごっちゃになってしまうところ
ある配列の実要素が ポインタである(ポインタ配列)場合 配列である(2次元配列)場合
各それぞれで、記憶領域の配置が本質的に違うのに理解できるまでの敷居が高い。

既に書かれている記述を読むのは可能でも
やりたいことを実装するのに、どちらが適切かを選択できるか がキーポイント

335 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 19:21:54 ]
関数の引数や戻り値にポインタ変数が使われる場合なんかも初心者は混乱しやすいな

336 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 19:24:36 ]
次元配列って

□□□□□□□□□
□□□□□□□□□
□□□□□□□□□
□□□□□□□□□
□□□□□□□□□

こんな感じで
配列の実要素がポインタってのは

□→□□□□□□□□□
□→□□□□□□□□□
□→□□□□□□□□□
□→□□□□□□□□□
□→□□□□□□□□□

こういうこと?

337 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 19:30:14 ]
>>336
おおよそ yes
指している先がどれだけの大きさの器があるか未確定 & ほとんど知る術は無い
(さらに、不正な場所を指している可能性もあるん)

□→□□□□
□→□□□□□□□
□→□
□→ぬるぽ!
□→鼻から悪魔

こういうことがあり得る

338 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 19:34:43 ]
>>321
割った余りで考えるという思考がありませんでした…。
ありがとうございました!

>>322
真偽でif文作るってのがあるのを知りませんでした。
勉強になりました!

339 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 21:27:13 ]
>>332
これ関数ポインタ?

DLLの関数を動的に呼ぶときに、
GetProcAdress()で関数ポインタ取ってくるくらいしか使い道が分からん。

340 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 21:38:28 ]
分かりやすそうなところを選ぶとしたらイベントハンドラとかかな。

341 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 22:14:53 ]
>>339
引数を取らず引数を取らずintを返す関数へのポインタを返す関数へのポインタを取り、
引数を取らずintを返す関数へのポインタを取りintを返す関数へのポインタを返す関数
へのポインタだね。

342 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 22:27:42 ]
ええい、いいから黙ってtypedefしろ



343 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 22:35:09 ]
typedefしまくりで夢がひろがりんぐ

344 名前:デフォルトの名無しさん [2010/04/23(金) 23:21:31 ]
kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10575.c

番号と名前がランダムに記入されたテキストを読み込んで、数字と名前に分けて配列に格納し、番号昇り順で並べかえてテキストファイルで出力したいのですが
並べかえがうまくいきません
とりあえず作ってみたのですが…
アドバイスください

345 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 23:26:57 ]
>>344
tmp はいらない
ソートができていない
ソートが終わってから出力すればいい

誰かに写させてもらったの?

346 名前:344 mailto:sage [2010/04/23(金) 23:33:00 ]
過去に作ったやつを何個か組み合わせて作ってたらこうなりました…

347 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 23:33:07 ]
>>344
番号、名前、テキストの定義をすると話が早いと思う。

例:
番号は、'0'から'9'の文字からなる文字列
名前は、ひらがな、かたかな、漢字からなる文字列
テキストは、番号と名前をスペースからなる文字列で、最後以外の番号および名前の後には必ずスペースが来る。

11113 3333 5892739 山田 12128384 高橋 32939 8883 細川 32932399

とか。

348 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 23:37:36 ]
>>344
ヒント
for
    fscanf

for
    for
        if

for
    fprintf

349 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 23:41:59 ]
>>344

まず

 1.ファイルを全部読む
 2.並び替えを行う
 3.並び替えたデータをファイルに書く

っていう流れに書き換えて
2.の部分をじっくり考えてみてください。

350 名前:349 mailto:sage [2010/04/23(金) 23:43:51 ]
>>348
もろかぶったスマンw

351 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 00:47:16 ]
関数から構造体を返す必要がある場合、何か基準や定石はありますか?
こういう時にはこうすれば良いという指針があれば知りたいです。

//構造体の例
struct my_struct {
 int size;
 void *ptr;
 int data[];
};

//(1)create関数の中で構造体をmallocして、delete関数の中でfreeする。
struct my_struct* create_my_struct(int param);
void delete_my_struct(struct my_struct* md);

//(2)呼び出し元で構造体を確保して、init関数の中でメンバーをmallocして、release関数の中でメンバーをfreeする。
// 構造体そのものは呼び出し元でどうにかする。
int init_my_struct(struct my_struct* md, int param);
void release_my_struct(struct my_struct* md);

それぞれ下記のデメリットがあると思います。

(1)のデメリットは呼び出し元で入れたいメモリー領域がある場合、createした構造体をコピーする必要がある。
(2)のデメリットは呼び出し元でinitを呼ぶ前に構造体の大きさを知っていなければいけない。

352 名前:344 mailto:sage [2010/04/24(土) 00:55:12 ]
皆さんのアドバイス通りに流れを考えて、いちからやり直したら無事成功しました。
ありがとうございました。



353 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 01:20:37 ]
>>351
(1)のデメリットがよくわからんな
そのメモリ領域ってのは create で確保するんじゃないの?
あとコピーうんぬんはコピー用の関数でOK?


354 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 01:51:37 ]
>>353
実装はこんな感じです。

struct my_struct* create_my_struct(int param)
{
 struct my_struct* md = (struct my_struct*)malloc(sizeof(struct my_struct) + sizeof(int)*param);
 md->size = param;
 md->ptr = malloc(param);
 return md;
}

void delete_my_struct(struct my_struct* md)
{
 free(md->ptr);
 free(md);
}

デメリットは、下記のような場合、memcpyが必要なことです。

int get_data(char* buf, int size)
{
 struct my_struct* md = create_my_struct(size);  //←ここでbufを渡せたら
 int ret = memcpy(buf, md->ptr, size);         //←ここでコピーしなくていい
 delete_my_struct(md);
 return ret;
}

355 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 02:02:09 ]
なんか違和感があるな。どういう思想なんだろ

356 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 02:49:32 ]
>>354
*ptrの使い道はなんだろ。つーか、メンテしやすさ重視ならこうじゃね?


typedef struct {
 int size;
 int chinko;
 int unko;
 int data[];
} unko_t ;

unko_t *create_unko( unko_t *md, char *buf, size_t size )
{
 md = malloc( sizeof(unko_t) + sizeof(int)*size );
 if(md){
  md->size=size;
  memcpy(md->data,buf,size);
 }
 return md;
}

int get_data(char *buf, int size)
{
 unko_t *md;
 if( create_unko( md, buf, size )==NULL ) perror("unko");


357 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 02:50:30 ]
途中で送信しちゃったよもうどうでもいいや

358 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 02:58:38 ]
>>354
まぁよくわからないんだけど、こんな感じにすればOK?

struct my_struct* create_my_struct(int param, char *buf)
{
 struct my_struct* md = (struct my_struct*)malloc(sizeof(struct my_struct) + sizeof(int)*param);
 md->size = param;
 md->ptr = malloc(param);
 if (buf)
  memcpy(md->ptr, buf, size);
 return md;
}


なんにせよ、構造体のサイズが不定って段階で create/delete 方式だね。
後でもっとよい実装を思いついたときにも直しやすそうだ。


359 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 02:59:04 ]
いや、全然ダメだろ
create_unko()の第一引数が冗長だし、リソース開放できなくなってるし
どうでもいいけど、いまどきvoid *の代わりにchar *使わなくても
あと、変更しない変数にはconstを明示的に付けた方が幸せになれる

360 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 03:00:37 ]
豪快にかぶったけどまあどうでもいいな

361 名前:351 mailto:sage [2010/04/24(土) 03:04:33 ]
分かりにくかったので、>>354に追加します。

int do_some_process_to_my_struct(struct my_struct* md, int param)
{
 for(int i = 0; i < md->size; i++){
  ((int*)md->ptr)[i] = param+i;
 }
 return param+i;
}

int get_data2(char* buf, int size)
{
 struct my_struct* md = create_my_struct(size);  //←ここでbufを渡せたら
 do_some_process_to_my_struct(md, 12345);
 int ret = memcpy(buf, md->ptr, size);         //←ここでコピーしなくていい
 delete_my_struct(md);
 return ret;
}

362 名前:351 mailto:sage [2010/04/24(土) 03:12:28 ]
>>358
いいえ。OKではないです。
memcpyするのはあくまでも例ですので、createの中にmemcpyを入れてしまうのは話が違ってしまいます。

知りたいことは、>>351に書いたとおり、関数から構造体を返す場合に
(1)と(2)あるいはその他の方法で良いやり方があるのか、ということです。



363 名前:351 mailto:sage [2010/04/24(土) 03:19:32 ]
>>361
int do_some_process_to_my_struct(struct my_struct* md, int param)
{
 int i;
 for(i = 0; i < md->size; i++){
  ((char*)md->ptr)[i] = (char)(param+i);
 }
 return param+i;
}

あくまでも例ですが、間違っていたので訂正します。

364 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 03:23:36 ]
やりたいことがまったく分からなくなってきたので
もう少し簡潔にわかりやすく実例込みで説明頼む

365 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 04:35:09 ]
マクロでsubstituteする良い方法無い?
#define substitute_ptr(a) ??
#define fn_typedef(a,b) typedef a(*fn##substitute_ptr(a)##substitute_ptr(b))(b);

fn_typedef(ANYSTRUCT*const,int); → typedef ANYSTRUCT*const (*fnANYSTRUCTconstint)(int);

366 名前:デフォルトの名無しさん [2010/04/24(土) 06:47:19 ]
printf( "sin(π) = %g \n" ,sin(M_PI) );

sinπが0にならないんだけど?

367 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 07:04:50 ]
そんくらいの誤差は出るだろ

368 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 07:47:45 ]
>>351
struct my_struct {
 int size;
 struct {
  char param;  /* malloc からchar型を想定 */
  int data;
 } elem[];
};

こういうふうにペアにしたらダメ?
型の異なる(しかし要素数の等しい)可変長サイズを持つ構造体を取り扱いたいようだが…

369 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 09:17:20 ]
>351

元々の質問は、一般的にはその2通りのやりかただろう、と答える。
しかし(1)のデメリットが理解できない。
(1)のデメリットは呼び出し元で「入れたいメモリー領域がある場合」、createした構造体をコピーする必要がある。

とくに「入れたいメモリ領域がある場合」という部分が不明。
ポインタがメンバになっているときに、その実体が欲しいってこと?

>354 >361を見てると、あってんだか違うんだか。creat関数の中でメンバを取得しようとしているのかワケワカ。

もしメンバがの実体が欲しいなら、そういう機能を実現した関数を作ればよい。

こんな感じじゃないか。

void get_data(struct my_struct* pMyData, void *pData)
{
 pData = malloc(pMyData->size);
 memmove(pData, pMyData->ptr);
}

370 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 09:55:27 ]
関数ポインタの配列について教えてください。

void func1( );
void func2( );
void main()
{
int i;
void (*func_ptr[2])( )= { func1, func2};
for(i=0; i<2; ++i)
{
(*func_ptr[i])( ); /* ★★★★ */
}
}
void func1( )
{
printf("func1\n");
}
void func2( )
{
printf("func2\n");
}


上記のプログラムでfunc1とfunc2が実行できたんですが、
★★★★のところを(func_ptr[i])( ); としても、func1とfunc2が実行できました。
関数ポインタの配列に*を付けた場合と付けない場合は何が違うのでしょうか?

371 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 10:00:40 ]
281 名前:デフォルトの名無しさん[sage] 投稿日:2007/11/08(木) 00:27:05
関数ポインタって代入時の&と実行時の*ってなくても動作変わらないよね?
もともとはどっちが正しいの?

282 名前:デフォルトの名無しさん[sage] 投稿日:2007/11/08(木) 01:06:42
元々必要だったらしいが、gccがなんか理論武装して独自拡張として省略しても良くしたら、
世間に受け入れられたなんて話を聞いたことがある。

372 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 10:10:25 ]
a[3]と*(a+3)は何が違う
ってきくようなもの
書き方が違うだけでまったく同じ



373 名前:351 mailto:sage [2010/04/24(土) 10:42:37 ]
>>368
struct my_struct はあくまでも構造体の一例です。
今回の質問ではstruct my_struct の中身を工夫することはあまり重要ではありません。

一般的な話として、関数から構造体を返す場合の、関数プロトタイプの設計に定石があるかどうかを知りたいのです。
こういう時にはこうすれば良いという指針があれば知りたいです。

>>369
>ポインタがメンバになっているときに、その実体が欲しいってこと?

いいえ。今、具体的な構造体あって、その構造体を扱う関数の作り方を知りたいということではありません。

質問の意図は、
構造体を初期化あるいは生成する関数を設計するときの一般論として、
例えば
「ポインタがメンバーになっている構造体の場合は(1)が良くて、そうでない構造体は(2)が良い」(←これは例です。)
というような定石があれば知りたい、ということです。

ですので、get_dataの作り方は質問の対象ではありません。
質問の対象は>>351の(1)(2)の関数プロトタイプについてです。

374 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 11:43:19 ]
>>351
趣旨が良く分からんのだが、要するに、
構造体の中身を動的にメモリを確保しなくちゃならん時に、
構造体自身も動的に確保したい場合、
一緒に確保した方が良いのか、別々に確保した方が良いのかって話?


375 名前:370 mailto:sage [2010/04/24(土) 11:43:48 ]
>>371-371
回答ありがとうございます。
*を付けると、func1という関数名になり最終的には、
関数名だけ書いた場合はアドレスになるというルールでアドレスになる。

*を付けないと、func1のアドレスになる

どちらでも同じようにfunc1が実行されるということで合ってますでしょうか?

376 名前:351 mailto:sage [2010/04/24(土) 11:46:36 ]
>>374
そうですね。
どういう場合には一緒に確保したほうが良くて、どういう場合には別々に確保したほうが良いという指針があれば知りたいです。
他にもっと良いやり方があればそれも知りたいです。

377 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 12:59:50 ]
>>376
その構造体の隠蔽具合や生命期間との相談かな

FILE ぐらい がちがちに隠蔽する
  関数利用側は基本的にメンバアクセスしない: 操作関数(群) とセットになる
気なのか (この場合は create/delete で完結すべき)

リスト的用途に近く、親struct の生命期間とは生きている必要がある時間が
違う場合は、メンバは alloc せず NULL のまま


378 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 13:23:31 ]
>>351
あぁ〜、やっぱり、趣旨がいまいち良く分からんな…。

>>354のget_data()の使い方を見るとcreate_my_struct()した時に、
領域の確保だけでなく、実際に必要なデータが作成されて、
その内容をget_data()で引っ張るって仕組みって認識したんだが、
ってことは、(1)でのcreate_my_struct()は、
メモリの確保だけでなく、データまで作成するって認識であってる?
で、(2)ではinit_my_struct()でデータだけ作成するってこと?
※ここでのデータ作成は、メモリの動的確保を含む

と言う事であれば、そのinit_my_struct()で作成すべきデータは
それだけで、一つの構造ってことになるから、
それぞれ用のcreateを作るが正しいと思うのだが?

仮にinit_my_struct()をcreate_my_struct2()とすると
create_my_struct()の中でcreate_my_struct2()を呼び出すイメージ。
で、その時々で必要なcreate()を呼ぶ。

379 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 14:04:10 ]
>>376
俺も概ね>>377と同意見。
他のやり方としては、構造体なら関数の戻り値として
構造体の実体を返す方法もあるよ。
エラーを返しづらかったり、癖の強いやり方だけど。

380 名前:デフォルトの名無しさん [2010/04/24(土) 14:34:29 ]
板違いだったらすみません。。。
C言語(WinAPIを含む)でグローバルIPアドレスを無理やり変えることはできますか?

381 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 14:42:44 ]
通信できなくなるでしょ

382 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 14:47:21 ]
>>380
C言語(WinAPIを含む)を使って、何の機器のグローバルIPを
どんな意味で変えたいのによるな
何もしても、このスレないことは確か。



383 名前:351 mailto:sage [2010/04/24(土) 14:59:48 ]
>>377
>その構造体の隠蔽具合や生命期間との相談かな

なるほど。この指標は考える上での参考になりそうです。

ただちょっと初めの質問の意図と違ってきたので、ちょっと考え直します。

384 名前:デフォルトの名無しさん [2010/04/24(土) 15:06:31 ]
>>381-382
無理ってことでしょうか?

たとえば掲示板などに書き込むと管理者には
グローバルIPがわかる($_SERVER["REMOTE_ADDR"])と思うのですが、
それをルータ、パソコンをシャットダウンしなくても
ソフトで簡単に変えられたら便利かな?って思ったので・・・

もっと深く突っ込むと
IP斬られてしまったりした場合にすぐに変更できれば
またレスできるぢゃないですかw

それをしたいんです・・・

385 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 15:09:03 ]
>>384 板違い。

386 名前:デフォルトの名無しさん [2010/04/24(土) 15:10:44 ]
>>385
板違いですか?
WinAPIだと思ったので・・・

387 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 15:11:55 ]
>>384
IP変えるとか、それ以前の問題だな
ネットワークの知識とか、モラルとか、1からやり直せ

388 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 15:12:27 ]
>>386 pc11.2ch.net/pcqa/

389 名前:351 mailto:sage [2010/04/24(土) 15:36:11 ]
標準ライブラリにstrdupがあります。strdupは内部でmallocします。(>>351の(1)に相当)

char *strdup(const char *s);

char* str = strdup("hogehoge"); //←確保するメモリー領域のサイズはstrdupのおまかせ!○
printf("%s\n", str); //処理の例
free(str); //freeが必要×

同等のことを行うmy_strdupを作ることもできます。my_strdupは内部でmallocしません。(>>351の(2)に相当)

void my_strdup(const char* src, char* dst, int size);

char str[100]; //←コピーする文字列より大きなサイズのメモリーが必要×
my_strdup("hogehoge", str, sizeof(str));
printf("%s\n", str); //処理の例
//freeは必要ない!○

(次に続く)

390 名前:351 mailto:sage [2010/04/24(土) 15:37:17 ]
>>389の続き)

【my_strdupのメリット】
strdupは、内部でmallocをするため、呼び出した後、必ずfreeが必要になります。
一方、my_strdupなら、自動変数を引数に渡せるので、必ずしもfreeは必要ありません。
この点では、my_strdupの方が便利です。これがmy_strdupのメリットです。

【strdupのメリット】
しかし、my_strdupでは、文字列全体をコピーしたい場合、
元の文字列よりも大きなサイズのメモリー領域を渡さなければ、文字列全体をコピーすることが出来ません。
このため、my_srtdupを呼び出す前に、strlenを使うなどして元の文字列のサイズを知る必要があります。
一方、strdupは内部で必要なサイズの領域をmallocするので呼び出す前に元の文字列のサイズを知る必要はありません。
この点では、strdupの方が便利です。これがstrdupのメリットです。

以上は文字列での例でしたが、
構造体や他のデータ領域を扱う関数を考えるときにも
呼び出し元でメモリーを確保して渡すか、あるいは関数の内部でmallocするか、
についてどういう時にどうしたらいいのか、を考えることができるかと思います。

一般的な指針があれば知りたいです。

391 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 16:12:35 ]
strdup()のデメリットがfree()を必要とすることでは無い
オブジェクトを生成したら破棄するのは当然のことである(create/destroyの対が大切)

my_strdup()のメリットが自動変数を引数に渡せるとかなんとか言っているが
自動変数の領域が足りない場合や書き換えが必要な場合、結局メモリ確保が必要となり自動変数が渡せることはデメリットでしかない

たとえば、標準ライブラリのf*()について考えてみよう
FILEがクラスでfopen()がコンストラクタ、fclose()がデストラクタ、その他のf*()関数がFILEインスタンスに対するメッセージと考えれば、f*()群は低級なオブジェクト指向をしているとか意釈できる

ここで、一つの指針を示そう
あるオブジェクトを生成しメッセージを送り破棄せよ
foo_t *foo;
foo = create_foo();
do_something_foo(foo);
destroy_foo(foo);
呼出元が生成と破棄を対にして行うのが良い

この関係は、strupでもmy_strdupでも同じことになる
char *s = strdup(foo); /* create */
(void)s; /* do something */
free(s); /* destory */

char *t = malloc(bar); /* create */
my_strdup(foo, t, bar); /* do something */
free(t); /* destory */
my_strdup()がソースとデストが逆のmemcpy()みたいで気持ちが悪いと言っておくテスト

392 名前:351 mailto:sage [2010/04/24(土) 16:38:53 ]
>>391
> strdup()のデメリットがfree()を必要とすることでは無い
> オブジェクトを生成したら破棄するのは当然のことである(create/destroyの対が大切)

確かに当然のことです。当然のことですので、その当然のことを忘れた場合、深刻なバグになるという大きなデメリットがあります。

> my_strdup()のメリットが自動変数を引数に渡せるとかなんとか言っているが
> 自動変数の領域が足りない場合や書き換えが必要な場合、結局メモリ確保が必要となり自動変数が渡せることはデメリットでしかない

自動変数で問題がいない場面では、上記の深刻なバグを避けられるという点で十分メリットがあります。
仰りたいことはわかりますが、一概に決められるものではないと思います。

例えば、>>391の主張では、memcpyはデメリットしか無いことになってしまいますよね?

> 呼出元が生成と破棄を対にして行うのが良い

良いのはわかります。つまり、それがstrdupや、>>351の(1)の場合ですよね。
my_strdupにmallocで確保したメモリー領域を与え、使用後freeするのも良いと思います。

ですが、my_strdupに自動変数を渡してはいけないということにはならないですよね?下記のようなコードは普通に書かれると思います。

void func(const char* str) //strは99文字以下の文字列
{
 char buf[100];
 strncpy(buf, str, sizeof(buf));
 /*strに対する処理*/
 printf("%s\n", str);
}

これは、若干恣意的な例ですが、これに限らず、自動変数の構造体や配列へのポインターを関数に渡すことは一般的に行われることですよね。



393 名前:351 mailto:sage [2010/04/24(土) 16:43:53 ]
>>392の訂正です。すいません。

void func(const char* str) //strは99文字以下の文字列
{
 char buf[100];
 strncpy(buf, str, sizeof(buf));
 /*bufに対する処理*/
 printf("%s\n", buf);
}


394 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 17:20:21 ]
>392
バグ(メモリリーク)になるから自動変数使うとかどれだけ舐めてるんだよ
C言語はプログラマ任せだからそんなこと言うようになったら、もうC言語に触れない方が幸せになれるよ

別にmemcpy()がデメリットしかないダメダメ関数とは言っていない
一般化したいと言っているのに自動変数マンセーとか言っているからだよ
自動変数(オブジェクト)に対してmempcy()(メッセージ)を送っているが、領域不足やコピーが必要になったときに結局メモリ(新しいオブジェクト)が必要になるのなら最初からメモリ使っておけばいいだろ
つまり、一般的にあるオブジェクトに対するメッセージの引数に自動変数が渡せるからって嬉しいことは無いだろと
memcpy()は抽象し過ぎているから混乱しているんだろう

別に、my_strdup()に自動変数を渡してはいけないとは言っていない
少なくとも自動変数が渡せることがメリットにはならないし、一般的に考えれば自動変数を使うことはデメリットになると言及しただけのこと

確かに、自動変数で領域や生存期間が足りるのであれば自動変数でも構わない
しかし、一般化してオブジェクトがN個必要なときに困ったことになる
ある場面ではi個必要で、自動変数をi個用意しなければならない、またある場面ではj個必要で、自動変数をj個用意しなければならない
じゃあ、i <= jだから、j個用意しとけばいいやとするのか、iが遥かにjより小さい場合無駄が多いからすべきでは無い
そんなことしないで、必要な時に必要なだけ用意してやれば済むこと


一般化したいのか具体化したいのかどちらかにしてもらえないだろうか

395 名前:351 mailto:sage [2010/04/24(土) 17:40:07 ]
>>394
構造体や配列を返す関数を設計する場合の一般的な指針を求めています。

>C言語はプログラマ任せだからそんなこと言うようになったら、もうC言語に触れない方が幸せになれるよ

C言語はプログラマ任せだからこそ、プログラマーが、その時々に適切に、自動変数を渡すか、mallocで確保したメモリーを渡すかを選べるようにしておく方が幸せでしょう。
ですので、自動変数をマンセーしているわけではありませんが、自動変数を一切渡せないよりは、渡せた方がメリットがあると考えます。

つまり、自動変数を一切渡せなければ、自動変数を使いたいプログラマーには使えませんが
自動変数を一切渡せれば、自動変数を使いたいプログラマーにも、使いたくないプログラマーにも使えるからです。
これは十分メリットです。

ともかく、自動変数を渡せるかどうかは、今回の質問の本質ではなく、
構造体や配列を返す関数を設計する場合の一般的な指針として、
(1)関数内部でmallocするのと、(2)呼び出し側で確保したメモリー領域を受け取るのと、(3)それ以外の方法(があれば)と、で
どういう時にどうするのが良いのかという指針があれば知りたいと思っています。

396 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 17:56:48 ]
>どういう時にどうするのが良いのかという指針があれば知りたいと思っています。

ないよ。問題が無い限り好きにしてよしヽ( ´ー`)ノ

397 名前:351 mailto:sage [2010/04/24(土) 18:05:31 ]
「好きにしてよい」というのは、特に基準がないのでその日の気分でどちらかに決めるということですよね。
そういう方針の方もいるということはわかりました。ありがとうございます。

それでは引き続き、>>389-390について何か方針をお持ちの方がいましたら、ぜひ教えてください。お願いします。

398 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 18:24:44 ]
WindowsのAPIは、my_strdup()みたいに格納領域のアドレスとサイズを
渡すインタフェースが多いね
で、Windows系のプログラマはそういう関数をつくることが多いね
無難だけど美しくないよね
パラメタは少ない方がいい

399 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 18:38:23 ]
>>389
とりあえず、strdupは例として適当じゃないわな。目的が違うから。
単に(最大の)長さが分かっている文字列のコピーは
strcpyなりstrncpyなりを使う。

一般論で言って、必然性がない場合、mallocはしない。
する場合は、旧来では
・確保すべきサイズがかわる
・スコープを越える必要がある

他のケースはプログラマの腕次第で
コードをシンプルにするために使う。
・引数を減らす
・必要な変数を減らす
・インターフェイスの一般化
などなど。

メモリ管理に自信がないならやめとき。

ただイマドキ、そこに自信が持てないなら
Cなんて使わない。
逆に言えば、その程度は必須なわけで、
だから「好きにすれば良い」って意見が出てくる。

400 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 19:25:00 ]
>351

生成と解放を対にしろってのは、基本方針としてもよいと思う。
よって、strdupのような関数は、できれば使いたくない派。
strdupは生成と解放の数が合わなくなる。

>392
>> 呼出元が生成と破棄を対にして行うのが良い

>良いのはわかります。つまり、それがstrdupや、>>351の(1)の場合ですよね。

これ逆だよね。strdupを使うとmallocが見えないのにfreeしなくちゃならない。

strdupは標準関数だからましだけど、func0, func2, func4が返すポインタは
freeしてね、とかだとやってられない。


やけにstrdupが「サイズを気にしなくてよい」ことがお気に入りのようだが、あくまでも実引数がCstringである場合だけ。
これは自動変数か、ヒープ領域か、静的変数かには無関係。

str系関数は、終端文字がある前提という制限がある。

呼び出し側が領域を用意する場合は、当然呼び出し側でサイズがわかっているはずなので、
そのときに無駄に領域を用意しなければよいだけでしょ。


401 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 19:32:16 ]
急に流れが加速してて吹いた。

402 名前:351 mailto:sage [2010/04/24(土) 19:32:36 ]
>>399
> 一般論で言って、必然性がない場合、mallocはしない。
> する場合は、旧来では
> ・確保すべきサイズがかわる
> ・スコープを越える必要がある

これには同意です。
個人的には自動変数で済む場合はmallocは使わないようにしています。

> コードをシンプルにするために使う。
> ・引数を減らす
> ・必要な変数を減らす
> ・インターフェイスの一般化

これは、シンプルになるのであれば、シンプルにしたほうがいいということですね。
つまり、>>351の(1)が可能であれば、常に(1)にしろということですね。
方針の一つとして参考にさせていただきます。



403 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 19:34:03 ]
・サイズが巨大な場合
が抜けてるな

404 名前:351 mailto:sage [2010/04/24(土) 19:45:44 ]
>>400
>生成と解放を対にしろってのは、基本方針としてもよいと思う。
>よって、strdupのような関数は、できれば使いたくない派。

個人的にはstrdupは使いませんが、
strdupもstrdup-freeで生成と解放の対になっているので問題ないと思います。
(n対1の対応なので若干違和感はありますが。)

>これ逆だよね。strdupを使うとmallocが見えないのにfreeしなくちゃならない。

いいえ、関数の中でmallocを行うという点で、strdupと>>351の(1)は同じです。
create_my_struct()に対するdelete_my_struct()は、strdup()に対するfree()です。

405 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 19:52:13 ]
strdupって名前が気に入らないんじゃないの
"alloc" を含んでないから
俺は別にどうでもいいと思うけど

406 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 20:00:01 ]
関数の実体が書いてないから、何とも言えないね

407 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 21:35:25 ]
>>398
上位互換を維持しつつ ver 違いを吸収する苦肉の策な面もあるね

APIを実装する際「渡されたサイズからどのver なのか類推・分岐できる」

408 名前:デフォルトの名無しさん [2010/04/24(土) 21:57:07 ]
GDI+を使うためにはどうすればいいですか?
VC2008です。

409 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 21:57:40 ]
上位互換を持するということは、元の関数から引数は変化がないということだろ。
元の関数から変化が変化がないということは、元の関数もアドレスとサイズを持っていたということであって
つまり元々あるのだから苦肉の策では無いんじゃないの。

410 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 22:07:16 ]
>>408
#include <gdiplus.h>
#pragma comment(lib, "gdiplus")

411 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 22:10:20 ]
>>410
VC++の他に特に何もいらないということですね。
質問にこたえていただきありがとうございます。

412 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 22:11:41 ]
VC++EE使ってるならPlatformSDKがいるんじゃ



413 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 22:14:01 ]
例がたまたまかもしれないけど、my_strdupを使うくらいならstrncpyを使うよね。

話を戻すと、allocとfreeは同じレイヤーにあるのが分かりやすいと思うよ。

414 名前:351 mailto:sage [2010/04/24(土) 22:26:58 ]
>>413
> 話を戻すと、allocとfreeは同じレイヤーにあるのが分かりやすいと思うよ。

それはそのとおりだと思います。
>>351の(1)(2)ともにその方針に基づいています。
(1)の場合は自前でalloc-freeを行い、(2)の場合は前処理・後処理として必要な場合のみalloc-freeを行います。

今回の質問の趣旨はそこではなく、
構造体や配列を返す関数を設計する場合の一般的な指針を知りたいのです。

415 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 22:42:53 ]
>>351
俺は、is-aと考えた方が自然なのかhas-aと考えた方が自然なのかで分ける。
分かるとは思うが(1)はis-aの場合で、(2)はhas-aの場合。
あと、自動変数を使用するか、アロケートするかは、
プログラマが使いたいか使いたくないかで考えるのではなく、使用用途で考えるべき。

416 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 22:45:55 ]
> (1)のデメリットは呼び出し元で入れたいメモリー領域がある場合、createした構造体をコピーする必要がある。
入れたいメモリ領域がある場合はinitのパラメータにもたせれば良いのでは?

> (2)のデメリットは呼び出し元でinitを呼ぶ前に構造体の大きさを知っていなければいけない。
my_struct *p = (my_struct *)malloc(sizeof(my_struct));
ではだめだということ?

常に呼ばなければならないreleaseを作成するのであれば、常にinitの中でallocすればいいと思う。
そうでないのなら、構造体本体は利用者がalloc-freeすればいいと思う。というか、そうしてる。

417 名前:351 mailto:sage [2010/04/24(土) 23:00:41 ]
>>415
なるほど。その指針は明快ですね。納得です。
ありがとうございます。

>>416
>> (1)のデメリットは呼び出し元で入れたいメモリー領域がある場合、createした構造体をコピーする必要がある。
>入れたいメモリ領域がある場合はinitのパラメータにもたせれば良いのでは?

つまり、常に>>351の(2)にするのが良いということでしょうか?

>> (2)のデメリットは呼び出し元でinitを呼ぶ前に構造体の大きさを知っていなければいけない。
>my_struct *p = (my_struct *)malloc(sizeof(my_struct));
>ではだめだということ?

はい、ダメです。
struct my_structは可変長配列のメンバーdataを持っているのでそのサイズ分多めにメモリーを確保しなくてはいけません。

418 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 23:19:22 ]
入れたいメモリ領域を渡したいことについて
(2)のinitのパラメータに持たせてもいいし、(1)のcreateのパラメータに持たせてもいい。

可変部のサイズを常にパラメータで渡すのであれば、呼び元でそのサイズを確保することは
十分可能なんじゃないの?

419 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 23:28:12 ]
>>409
いや パラメータが一括で纏まった構造体 ってパターンがほとんどさね
ListView とか IEのVER違いで、パラメータ構造体のサイズが違う
だが API(要素の追加とか)のインターフェースは不変
(さらに、APIの実装体は外部リンケージなDLL内)
こういうこと

この例でない話だったらスマン

420 名前:351 mailto:sage [2010/04/24(土) 23:42:33 ]
>>418
入れたいメモリ領域を渡すのが(2)で、入れたいメモリ領域を渡さず関数内部でメモリ領域を確保するのが(1)です。これが定義です。
ですので、入れたいメモリ領域を渡すのであれば、(2)になります。

また、(1)の場合は、可変部の情報を含めサイズ情報を渡しません。
ですので、(1)の場合、呼び出し元は可変部の情報を含めサイズ情報を呼び出す前に知る必要はありませんし、
前述のとおり関数内部でメモリー領域を確保するので、そのサイズを知ることが出来なくても問題ありません。

421 名前:デフォルトの名無しさん mailto:sage [2010/04/24(土) 23:58:42 ]
>>420
入れたいメモリ領域云々を別で考えることはできないの?
そうなればそれは一般的に構造体を扱う時の指針とかそういうのとは別で、特殊化された話になってこないか?

422 名前:351 mailto:sage [2010/04/25(日) 00:14:29 ]
>>421
> 入れたいメモリ領域云々を別で考えることはできないの?

これはどう言うことでしょうか?
少なくともどこか(関数内あるいは関数外)で、malloc(sizeof(struct my_struct)+data_size)のように構造体のメモリーを確保しなければならないと考えていました。

もしこれを別で考える方法があるならば、ぜひご教示ください。



423 名前:デフォルトの名無しさん mailto:sage [2010/04/25(日) 00:33:19 ]
入れたいメモリ領域ってptrじゃないの?
サイズを可変にするためのものとは別だよね。

このptrを同じ関数で確保すべきか、外から渡せるようにするかという話が混ざっているように見える。

424 名前:351 mailto:sage [2010/04/25(日) 00:41:35 ]
>>423
>入れたいメモリ領域ってptrじゃないの?

入れたいメモリ領域とは、構造体そのものを入れたい領域のことです。

425 名前:400 mailto:sage [2010/04/25(日) 00:42:10 ]
>351 >420

あなたの言う1)と2)の違いを、把握できていなかったから、議論がぐるぐる回っていたぞ。

議論の焦点は
>入れたいメモリ領域を渡すのが(2)で、入れたいメモリ領域を渡さず関数内部でメモリ領域を確保するのが(1)です。これが定義です。
ということだね。

そうでであるならば
>(1)の場合は、可変部の情報を含めサイズ情報を渡しません。
これは無理。

1)の実現例としてstrdupを挙げているのなら、str系は終端文字列付きという制限を与えることで、
間接的にサイズ情報を与えている。

>404
>いいえ、関数の中でmallocを行うという点で、strdupと>>351の(1)は同じです。
私には同じには見えないな。
malloc-free, new-delete, new[]-delete, create_my_struct-delete_my_struct
は対に見える。

だけど関数内部でmallocするhogeがあるとしてhoge-freeは対には見えない。
そういうことに注意してコーディングしたくない。

だからstrdup使うくらいなら、mallocしてstrcpyして、freeする。

426 名前:351 mailto:sage [2010/04/25(日) 00:56:57 ]
>>425
> >(1)の場合は、可変部の情報を含めサイズ情報を渡しません。
> これは無理。

いいえ。無理ではありません。
例えば、関数内でrecv()を使ってネットワークからデータを受信する場合など、処理を完了して初めてデータのサイズが確定することがあります。
そのような場合、関数を呼び出す前にはそのサイズは分かりませんが、関数内ではreallocするなりして適切なサイズのメモリーを確保することができます。
したがって、可能です。

>私には同じには見えないな。

これは関数名が適切ではないとうことでしょうか?
そうであれば特に異論はありません。人の感覚なのでそう見えない人がいることは仕方が無いと思います。
そういう点では、私も、new-deleteという組み合わせが名称としてあまり適切でないと思っています。

私が同じだといったのは、機能としての対応からです。

427 名前:デフォルトの名無しさん mailto:sage [2010/04/25(日) 01:52:31 ]
>>426
> 例えば、関数内でrecv()を使ってネットワークからデータを受信する場合など、
> 処理を完了して初めてデータのサイズが確定することがあります。
>そのような場合、関数を呼び出す前にはそのサイズは分かりませんが、
>関数内ではreallocするなりして適切なサイズのメモリーを確保することができます。

なぜ recv() がそういう造りになっていないのか? を想像してくれ
上記の構造だと、生成/消滅の入れ子構造が維持し難いんだよね 

428 名前:351 mailto:sage [2010/04/25(日) 01:59:41 ]
>>427
> なぜ recv() がそういう造りになっていないのか? を想像してくれ

何のためにその想像をする必要があるのでしょうか?
目的がよくわかりません。

429 名前:デフォルトの名無しさん mailto:sage [2010/04/25(日) 03:25:24 ]
>>424
ならぬるぽのときだけ確保するようにしたらいいんでないかな。

430 名前:デフォルトの名無しさん mailto:sage [2010/04/25(日) 03:27:29 ]
>>425
うーん、strdup-freeも対に見えないよ
その論調ならstrdupの存在を否定していいと思うんだ。そしてそれはアリだと俺は思う。

431 名前:デフォルトの名無しさん mailto:sage [2010/04/25(日) 03:33:04 ]
って最後の行読んでなかった。まったくもってそのとおりであって、なんていうかごめん。

ちなみにnew[]-deleteはnew[]-delete[]の間違いだよな?

>>426
> 人の感覚なのでそう見えない人がいることは仕方が無いと思います。
なんか多分読み違えているけれど、
create_my_structのような関数を見た場合、同ライブラリにdelete_my_structのような関数があれば
プログラマは注意を払うが、なければ特に何もしなくて良い(freeを使う必要がない)と思ってしまうクセがある。
そういう意味で、hoge-freeが対に見えないという話だよ

432 名前:>425 mailto:sage [2010/04/25(日) 08:44:44 ]
>431

>ちなみにnew[]-deleteはnew[]-delete[]の間違いだよな?

すみません。タイプミス。注意したつもりだったのに、日頃C++使わない物で、ご容赦ください。

>426
他の人とは、同じ感覚みたいだけど、strdup-freeはリソースの確保と解放のレベルがあっていない、
イヤなコーディングスタイルだってこと。mallocしているレベルが、一段低いから。
名前の問題ではない。
ただ、標準関数という意味でギリギリの許容範囲。
コーディングスタイルを操作できる立場なら、ANSIに含まれないから禁止としたいくらい。
拒否する。

もちろんそういう構造が取れない場合は、あり得る。
だけど「一般的には」リソースの確保と解放の対は、そろっている方がよい。




433 名前:デフォルトの名無しさん mailto:sage [2010/04/25(日) 09:22:07 ]
>>432
横からだけど、レベル合わせるのって必要か?
どちらかと言うと、アロケートとリリースが組み合わせになってないことの方が問題じゃないか?
strdupに対して、strdup_free()があれば良いだけで、
使う方は、その中身の実装は問わないってのが正解な気がするが…?
要するに、あるオブジェクトに対してのnewがあるなら、
そのオブジェクトに対するdeleteを用意して、それを使えってだけで、
組み合わせを間違えなければ、内部がどうなってようが、問題にならないと思うが…

434 名前:デフォルトの名無しさん mailto:sage [2010/04/25(日) 09:41:31 ]
同じく横からだけど
デストラクタが無い影響はスコープだけじゃなく構造体・共用体の中にまで影響する訳で
入れ物の階層毎に都度専用alloc/freeを用意するのが注意深いcデータ取り扱い方だとおもうよ

435 名前:デフォルトの名無しさん mailto:sage [2010/04/25(日) 10:05:18 ]
メモリを確保して返す関数は作るなって話か?
確保するメモリのサイズを事前に取得できない場合はどうすんのって話だな

436 名前:デフォルトの名無しさん mailto:sage [2010/04/25(日) 10:14:03 ]
専用reallocを用意するだけじゃないの?

437 名前:デフォルトの名無しさん mailto:sage [2010/04/25(日) 10:23:15 ]
とりあえず malloc して、そのポインタのアドレスを渡して、
関数内で realloc してもらうとか?

438 名前:デフォルトの名無しさん mailto:sage [2010/04/25(日) 10:30:07 ]
>>437
分けも分からずmalloc()する位なら、NULL使ってrealloc()の方がまし

439 名前:デフォルトの名無しさん mailto:sage [2010/04/25(日) 10:35:23 ]
それだと malloc/free の対応がとれないって主張なんじゃないの

440 名前:デフォルトの名無しさん mailto:sage [2010/04/25(日) 10:43:30 ]
>>439
必要なのはC++で言うnewとdeleteに対応するものであって
mallocとfreeではないと思うのだが?

441 名前:432 mailto:sage [2010/04/25(日) 10:45:57 ]
>433

>strdupに対して、strdup_free()があれば良いだけで、

それがレベルを合わせるってこと。
strdupの中でmallocしていれば、strdup_freeで責任もってそれを解放する方が、コード上で
リソースバランスの確認ができる。

>組み合わせを間違えなければ、内部がどうなってようが、問題にならないと思うが…
内部を気にしたくないから、リソース管理の責任レベルを合わせたいってこと。

>435
>確保するメモリのサイズを事前に取得できない場合はどうすんのって話だな
必ずしも、同じレベルでそろえられないかもしれない。でも、大抵は設計が行けてないだけ。

少し話を戻して>432で
「名前の問題ではない」と書いたけど、リソース管理レベルの話題であって、名前の話ではないといういみであり、
人間がコードを書いている以上、リソース管理レベルは識別子で認識している。
従って、リソース管理レベルを意識していれば、名前もそうなるはず。

コード上で名前のバランスが取れていない場合、設計を疑った方がよい。



442 名前:441 mailto:sage [2010/04/25(日) 11:00:58 ]
>426

>> >(1)の場合は、可変部の情報を含めサイズ情報を渡しません。
>> これは無理。
>いいえ。無理ではありません。
>例えば、関数内でrecv()を使ってネットワークからデータを受信する場合など、処理を完了して初めてデータのサイズが確定することがあります。

OK.あなたと私では、視点のレベルが違っていた。
私の視点は事前にサイズがわからない場合も、とりあえずバッファを用意しておいて、
読んでみないことには知りようがない、という意味だったのです。recvそのものの
レイヤーです。読んでみたあとはサイズがわかる、というのはそうですね。


議論はあくまでも一般論です。個別では理想的な実装ができないかもしれません。

余談ですが、メッセージループの処理ならば一般的には、下記のように書くと思います。
擬似コードです。

for (;;) {
 recvMsg(pMsg);
 /* メッセージに応じた処理 */
 freeMsg(pMsg);
}

これはメッセージを受けるところと、最後に解放するところでリソース管理レベルを
そろえています。



443 名前:デフォルトの名無しさん mailto:sage [2010/04/25(日) 11:07:19 ]
要するにコンストラクタとデストラクタを用意するみたいな感じにすべき、ということね?
まあその主張は分からんでも無い

444 名前:デフォルトの名無しさん mailto:sage [2010/04/25(日) 11:10:13 ]
>>441
>>strdupに対して、strdup_free()があれば良いだけで、
>それがレベルを合わせるってこと。
何か意図が違う気がする。
strdup()内でmalloc()を呼んでようが、さらに、strdup()で別の関数を呼んで
その中で、malloc()を呼んでようが、俺は気にしないって話だが合ってる?
strdup_free()に関しても、冗長になると分かってても実装して欲しと思うが、
最悪(本当に最悪だが)はdefineの定義するだけでも構わないと思ってるけど同じ?

445 名前:351 mailto:sage [2010/04/25(日) 12:24:26 ]
>>442
>議論はあくまでも一般論です。個別では理想的な実装ができないかもしれません。

はい。そのとおりです。
ですが、その下の擬似コードは>>351の質問の意図を表していません。

>>351の質問の意図は、
recvMsg(), freeMsg()を使う関数を作るような場合を含めて、
一般的に
・関数から構造体を返す必要がある場合、何か基準や定石があるのかを知りたい。
・こういう時にはこうすれば良いという指針があれば知りたい。
ということです。

recv()とrecvMsg()-freeMsg()のどちらが一般的かという議論は今回の質問の中ではしていません。

446 名前:デフォルトの名無しさん mailto:sage [2010/04/25(日) 12:29:35 ]
>>445
構造体自体を返すだけなら free() はいらない。
でも >>351 のお題にあがっている構造体は、メンバに malloc() で得たポインタがはいっているので、
当然 そのポインタを free() する必要がある。
一般化というが、上記のことだけ注意すれば OK なのでは。

447 名前:デフォルトの名無しさん mailto:sage [2010/04/25(日) 12:30:02 ]
>>351俺なら(1)だな。

さらに、(オーバーロードできるなら、C++なら同名で)
void delete_my_struct(struct my_struct **md) {
 delete_my_struct(*md);
 *md = 0;
}
とすらする。

448 名前:デフォルトの名無しさん mailto:sage [2010/04/25(日) 12:32:34 ]
>>447
Cでオーバーロードできる環境なんてあるのか?

449 名前:351 mailto:sage [2010/04/25(日) 12:36:38 ]
>>446
つまり、構造体内部の後処理だけを関数で行えということなので、常に>>351の(2)が良いということですね。

>>447
どういう場合、>>351の(1)が良いですか?
基準があれば教えてください。

それとも、常に>>351の(1)が良いでしょうか?

450 名前:デフォルトの名無しさん mailto:sage [2010/04/25(日) 12:51:51 ]
>>448
いっけね。Cスレだった。C/C++かと思ってた。

>>449
基準も何も、(2)は俺にとって煩雑。
呼び出し元でmallocなりして、init_my_struct呼んで、
要らなくなったらrelease_my_struct呼んで、free呼ぶ。
呼び出し回数が多い。呼び忘れるのも怖い。

(1)ならcreate_my_structで生成と初期化を同時に行い、
delete_my_structで後片付けと削除を同時に行う。
呼び出し回数が少ない。余計な気を使わなくて良い。
create - deleteの対を分かって使えば良いだけ。

C++にしたってコンストラクタ以外に、
new後にinit()呼び出しを要する設計もあるが、
同じ理由で俺はそういうの嫌い。

メソッド間、関数間に呼び出し順の依存関係があると使いにくい。

451 名前:デフォルトの名無しさん mailto:sage [2010/04/25(日) 13:33:21 ]
>>351 は構ってちゃんだから、マジレス禁止ね(^o^)ノ

452 名前:デフォルトの名無しさん mailto:sage [2010/04/25(日) 13:54:52 ]
>>351は常に(1)でいいよ。
ただし構造体のメンバにアクセスできないようにカプセル化したほうがいい。
ヘッダに

  struct my_struct* create_my_struct(int param);
  void delete_my_struct(struct my_struct* md);
  その他my_structを操作する関数のプロトタイプ宣言

を書いて、ソースのほうに

  struct my_struct {
   int size;
   void *ptr;
   int data[];
  };
  関数の定義

を書く。



453 名前:351 mailto:sage [2010/04/25(日) 18:27:17 ]
>>450
> 基準も何も、(2)は俺にとって煩雑。
>>452
> >>351は常に(1)でいいよ。

ありがとうございます。基本は(1)ということですね。

では、呼び出し元で構造体を格納したい場所が決まっている場合はどうすればいいと思われますか。

>>351の(1)の場合は、
呼び出し元で構造体のcretateを実行し、呼び出し元でその結果を構造体を格納したい場所にコピーしなければなりません。

>>351の(2)の場合は、
呼び出し元で構造体のinitに格納したい場所を指定して実行すれば、結果として格納したい場所に構造体が格納されるので、呼び出し元では改めてコピーする必要はありません。

この点で、やはり(2)は捨て切れません。
上位でどう使われるかわからない関数を設計する場合は、やはり(1)(2)の両方を用意したほうがいいでしょうか。

(1)(2)以外にうまい方法があれば知りたいところです。

454 名前:デフォルトの名無しさん mailto:sage [2010/04/25(日) 18:51:27 ]
>>453
自分で答え出してるじゃないか。まだ何か困ってるの?

455 名前:351 mailto:sage [2010/04/25(日) 18:53:31 ]
>>454
はい。
>>453の一番最後の行に書きました。

456 名前:デフォルトの名無しさん mailto:sage [2010/04/25(日) 19:30:23 ]
>>455
へぇ。そこ読んでも俺には何に困ってるのかわかんないや。

457 名前:デフォルトの名無しさん mailto:sage [2010/04/25(日) 19:34:52 ]
>>351
何のために格納したい場所ってのが必要なのかわからんが、変な書き方するよりは
おとなしくコピーしたほうがいいかもね。

458 名前:351 mailto:sage [2010/04/25(日) 19:43:23 ]
>>457
格納したい場所が決まっている状況というのは、
例えば、下記のようなコールバックハンドラーを実装する場合に、引数に格納するメモリー領域を渡されるような場合です。

int (*some_callback_handler)(char* buf, int buf_size);

パフォーマンスがそれほど要求されない場面では確かにコピーすれば解決なのですが、
そうではない場合もあるので、コピーの回数は減らせられるようにもしたいのです。

459 名前:デフォルトの名無しさん mailto:sage [2010/04/25(日) 19:56:46 ]
おかしいな、引数がヌルポインタかどうかで判断すればいいよっていうのはどうしちゃったんだろ。
reallocみたいな感じといえばいいかな

460 名前:デフォルトの名無しさん mailto:sage [2010/04/25(日) 21:13:28 ]
>>458
get_my_struct関数を作ってポインタを返して、そのポインタを使えばいいのでは。

461 名前:351 mailto:sage [2010/04/25(日) 21:24:14 ]
>>460
構造体を格納したいポインタを知っているのは呼び出し側なので
get_my_struct関数を作っても仕方ないですよね?

462 名前:デフォルトの名無しさん mailto:sage [2010/04/25(日) 23:54:00 ]
まだやってんのか

こういうどうでもいい質問はOKウェブみたいな初心者向けQ&Aサイトでやればいいのに



463 名前:デフォルトの名無しさん mailto:sage [2010/04/26(月) 00:03:24 ]
>>462
それがこのスレさ

464 名前:デフォルトの名無しさん mailto:sage [2010/04/26(月) 11:01:21 ]
いや寧ろ、ここは>351みたいに捻くれた初級者向きじゃない。
いっそ小心者スレ辺りでやってほしい。

465 名前:デフォルトの名無しさん mailto:sage [2010/04/26(月) 13:02:05 ]
>>464
お前が童貞専用自慰スレに行けばいい

466 名前:デフォルトの名無しさん mailto:sage [2010/04/26(月) 22:05:24 ]
フローチャート記号の「準備」ってどうやって使うものなの?
変数の宣言というのがこういうので、この時に使う?↓
int nurupo;
これは「処理」でいいよね?↓
int nurupo = 1

467 名前:デフォルトの名無しさん mailto:sage [2010/04/26(月) 22:14:54 ]
int nurupo = 1
が準備だな

処理に備えて初期化という準備をしているわけだし
変数宣言はフローチャートの中では書かないことが多い

468 名前:デフォルトの名無しさん mailto:sage [2010/04/26(月) 22:52:29 ]
会社で初期化と同時に代入書いたら
「こんな書き方見たことない、直せ!」と言われた。

469 名前:デフォルトの名無しさん mailto:sage [2010/04/26(月) 23:02:07 ]
初期化と同時に代入ってどうやるんだ

470 名前:デフォルトの名無しさん mailto:sage [2010/04/26(月) 23:02:55 ]
int i;
int j = i = 0;

こういうやつか
まあキモいな

471 名前:デフォルトの名無しさん mailto:sage [2010/04/26(月) 23:03:11 ]
>>469
語弊があって申し訳ないが、>>467みたいなやつ。

472 名前:デフォルトの名無しさん mailto:sage [2010/04/26(月) 23:06:20 ]
「初期化」と「代入」を勉強し直させるべきだな
つーか見たことない、って



473 名前:デフォルトの名無しさん [2010/04/26(月) 23:08:35 ]
宣言と同時に代入ってことか?

474 名前:デフォルトの名無しさん [2010/04/26(月) 23:10:00 ]
>>466
ソース読めば瞬間わかることを書いてはいけない
よく読まなければわからないことをアシストしてこそ意味がある

475 名前:デフォルトの名無しさん mailto:sage [2010/04/26(月) 23:11:39 ]
>>473
それを初期化と言う
まあ、初期化は代入ではないがな

476 名前:デフォルトの名無しさん mailto:sage [2010/04/26(月) 23:26:20 ]
初期化は代入じゃない?
int main(void) {int x = 5; return 0; }
なんかだと代入じゃない?

477 名前:デフォルトの名無しさん mailto:sage [2010/04/26(月) 23:34:34 ]
いいえ、初期化です

478 名前:デフォルトの名無しさん mailto:sage [2010/04/26(月) 23:41:51 ]
466だけど、アホ言ったみたいでほんとごめん。
もう少しグーグル先生で探してくる。プログラムって難しそうね。。
>>474
そういうものなのね。
じゃあ殆どつかわねーよ!という記号もあるとか?

479 名前:デフォルトの名無しさん mailto:sage [2010/04/26(月) 23:46:14 ]
auto 変数に初期化なんかあるのか?全部代入じゃないのか?
それとも俺の頭が古いのか?

480 名前:デフォルトの名無しさん mailto:sage [2010/04/26(月) 23:58:19 ]
>>479
古いんじゃなくて、最初からちゃんとした文法を覚えていないだけ。

481 名前:デフォルトの名無しさん mailto:sage [2010/04/27(火) 00:01:05 ]
>>480
static な変数に対する初期化は理解できるが、auto な変数に初期化という動作はあるのか

main() {
int x; /* 宣言 */
x = 1; /* 代入 */
}

をひとつにまとめものが
main()

482 名前:デフォルトの名無しさん mailto:sage [2010/04/27(火) 00:01:46 ]
int main() {
int x = 1; /* 宣言&初期化 */
}
と思っていたのだが。



483 名前:デフォルトの名無しさん mailto:sage [2010/04/27(火) 00:03:31 ]
ごめんなさい。やりなおし。
main()
{
int x; /* 宣言 */
x = 1 /* 代入 */
}
をひとつにまとめたものが
main()
{
int x = 1 /* 宣言+代入 */
}
だと思っていたのだが、規格はこれを初期化と呼んでいるのか?

484 名前:デフォルトの名無しさん mailto:sage [2010/04/27(火) 00:11:39 ]
>483

それは、初期化子付きの宣言。あくまでも宣言で、宣言+代入ではない。
式と宣言では文法が区別されている。

int a[] = {1, 2, 3,};
と書けるが
int a[10];
a[] = {1, 2, 3,};
とは書けないのは別物だから。

485 名前:デフォルトの名無しさん mailto:sage [2010/04/27(火) 00:16:06 ]
>>483
JIS X3010 6.7.8 初期化

486 名前:デフォルトの名無しさん mailto:sage [2010/04/27(火) 01:11:59 ]
>>481
途中で送信したとは思ったがシュール過ぎて笑った。

487 名前:デフォルトの名無しさん [2010/04/27(火) 11:47:43 ]
制御系プログラミングの初歩として、C言語(++ではない)のビット演算を勉強しています。
unsigned char型の変数を、二進数でバラして8個の0/1フラグとして使うための一番効率のよいやり方って何ですか?
一般的に使われるロジックとしては以下のメソッドのような感じでOKですか?

//引数srcのnビット目を0か1かで取り出す
unsigned char getNbit(unsigned char src,unsigned char n)
{
//srcと2のn乗(nビット目だけ1の値)と論理乗算して、0になったら0を返す。そうでなければ1。
if( src & (1<<n) == 0 )
{
return 0;
}
else
{
return 1;
}
}

//引数srcのnビット目に指定の値param(0/1)をセットした値を返す
unsigned char setNbit(unsigned char src,unsigned char n,unsigned char param)
{
//0をセットする場合、srcと2のn乗の値を反転した値(255-1<<n)とを、論理乗算する
if(param == 0)
{
return src & (255-1<<n);
}
//1をセットする場合、srcと2のn乗(1<<n)の値とを、論理加算する
else
{
return src | (1<<n);
}
}

488 名前:デフォルトの名無しさん mailto:sage [2010/04/27(火) 11:54:37 ]
ビットフィールドじゃあかんの?生成されるコードは汚いけど

489 名前:デフォルトの名無しさん mailto:sage [2010/04/27(火) 11:58:10 ]
二つ目はon/offで関数わけようぜ

490 名前:デフォルトの名無しさん mailto:sage [2010/04/27(火) 12:00:41 ]
IO操作するならビットフィールド使って、関数で隠蔽する

491 名前:デフォルトの名無しさん mailto:sage [2010/04/27(火) 12:15:09 ]
(255 - 1 << n) じゃなくて ~(1 << n)ってするのがビット演算らしい

492 名前:デフォルトの名無しさん mailto:sage [2010/04/27(火) 12:34:18 ]
__inline unsigned char getNbit(unsigned char src, unsigned char n) {
return src & (1 << n);
}

__inline unsigned char setNbit(unsigned char src, unsigned char n, unsigned char param) {
return src & ~(1 << n) | (!!param << n);
}



493 名前:デフォルトの名無しさん mailto:sage [2010/04/27(火) 12:39:45 ]
return (src >> n) & 1


494 名前:487 [2010/04/27(火) 13:33:20 ]
皆さん、ありがとうございます。

>>490
まさにIO制御の学習です。
基盤にランプが8個乗っていて、指定のIOポート1つ(1バイト)に値をセットすることで点灯/消灯を制御するといった課題です。
ビットフィールドというのを調べてみます。

>>492
前者は、指定したビットが0のときは0が返るけれど、1のときは1<<nが返りますね。
それでも、このメソッドを使う際に、「0かそうでないか」という運用をすれば良いということですか?
JavaのbooleanやC#のbool型に慣れているゆえ、0か1かの戻り値にこだわらないといけないと思っていましたが、
Cの常識だとそうでもないという認識で良いですか?

後者は、「src & ~(1 << n) | (!!param << n);」の記述の意味を詳しく教えていただけると助かります。
「src & ~(1 << n)」の部分までは、「とりあえず指定ビットを0にする」というのは分かりますが、
その後、 !!とはどういう意味の記述なのでしょうか。

こういう短く基本的な処理を書くにはinlineにしたほうが高速なのですね。とても参考になります。

495 名前:デフォルトの名無しさん mailto:sage [2010/04/27(火) 13:38:56 ]
ビットフィールドの実装依存の部分からいってその用途には使えないんじゃないの?
パディングとか順番入れ替わるとかで

496 名前:デフォルトの名無しさん mailto:sage [2010/04/27(火) 13:46:15 ]
>>494
>>492の get の方は指摘の通りで、0, 1 に固定するなら(した方がいいだろうけど)、
return !!(src & (1 << n));
としてもいいが、それなら >>493 の方がいいね。

!! は ! を2回やってるだけ。 0なら0、0以外なら1にしたいときにやる常套手段。

497 名前:デフォルトの名無しさん mailto:sage [2010/04/27(火) 14:15:09 ]
>>487の判定文、演算子の優先順位をよく調べとけ


498 名前:デフォルトの名無しさん mailto:sage [2010/04/27(火) 14:28:54 ]
>>494
JavaでもC#でも0が偽というところは変わらんよ。
if (3)とかかけるでしょ

499 名前:デフォルトの名無しさん mailto:sage [2010/04/27(火) 15:34:56 ]
>>498

500 名前:デフォルトの名無しさん mailto:sage [2010/04/27(火) 15:42:12 ]
JARO

501 名前:デフォルトの名無しさん mailto:sage [2010/04/27(火) 18:54:10 ]
!!はキモいんだよなあ
好みの問題だろうけど
ちゃんと最適化されるかどうかは気になる

502 名前:デフォルトの名無しさん mailto:sage [2010/04/27(火) 19:14:22 ]
!!がいやなら!=0はどうよ?



503 名前:デフォルトの名無しさん mailto:sage [2010/04/27(火) 19:20:04 ]
>>485
なるほど、「静的記憶域区間」のみならず「自動記憶域区間」の場合であっても、初期化という言葉が適用されるのですね。
インプリメント上では単なる代入にすぎないものであっても。



504 名前:デフォルトの名無しさん mailto:sage [2010/04/27(火) 19:53:57 ]
C++で挫折してCに流れ着いてCの入門書読み終えたんですが、中級者になるために試したらためになる演習課題とかありませんか
たぶんメモ帳とか作る場合GUIとか使わないとならないんですよね?できたらヒント付きで教えてくれませんか?


505 名前:デフォルトの名無しさん mailto:sage [2010/04/27(火) 19:54:16 ]
>>502
俺は基本そうしてる
if文に直接書く時はそれすら書かないけど

506 名前:デフォルトの名無しさん mailto:sage [2010/04/27(火) 19:55:02 ]
>>504
CUIで作れるような簡単なゲームでも作るといいよ
俺はいつもヒットアンドブローを作るようにしている

507 名前:デフォルトの名無しさん mailto:sage [2010/04/27(火) 22:01:56 ]
構造体のメンバに順次アクセスする
ナイスな方法ってある?

508 名前:デフォルトの名無しさん mailto:sage [2010/04/27(火) 22:10:36 ]
char*でキャストして、1バイト毎に順次アクセスする

509 名前:デフォルトの名無しさん mailto:sage [2010/04/27(火) 22:14:11 ]
メンバの位置や型を配列にして保存しておいて
それでループでアクセス

まあ普通そんなことやるなでFAだが

510 名前:デフォルトの名無しさん mailto:sage [2010/04/28(水) 15:43:35 ]
>>507
unionを使うのが一番楽で上品

511 名前:デフォルトの名無しさん mailto:sage [2010/04/28(水) 16:33:51 ]
>>510
順次アクセスという言葉の意味がわかってないだろ
馬鹿は黙ってればいいのに

512 名前:デフォルトの名無しさん mailto:sage [2010/04/28(水) 17:14:46 ]
順次アクセスできない理由を教えてくれ天才



513 名前:デフォルトの名無しさん mailto:sage [2010/04/28(水) 19:37:37 ]
>>511
こういう感じでいけるっしょ。
typedef struct {
int a;
int b;
int c;
int d;
} hoge_t;

typedef union {
hoge_t u;
int l[4];
} chinko_t;

514 名前:デフォルトの名無しさん mailto:sage [2010/04/28(水) 19:38:41 ]
あ、int l[0] にしといた方が便利がいいな。

515 名前:デフォルトの名無しさん mailto:sage [2010/04/28(水) 20:07:29 ]
アラインメントが気になる
同じ型ならまず問題は無いだろうが、万が一があるしな

516 名前:デフォルトの名無しさん mailto:sage [2010/04/28(水) 20:14:52 ]
メリット皆無だし。

517 名前:デフォルトの名無しさん mailto:sage [2010/04/28(水) 20:16:54 ]
>>515
それを言い出したらそもそもunionの存在そのものが怖いよな。

>>516
誰もメリットの話なんかしてねーだろ

518 名前:デフォルトの名無しさん mailto:sage [2010/04/28(水) 20:26:35 ]
添え字でアクセスしたいだけなら
#define STFX(N,V) switch(N){case 0:struct.a=V;break;case 1:〜}
で十分だし。

519 名前:デフォルトの名無しさん mailto:sage [2010/04/28(水) 21:01:43 ]
おいおい今日もまたCの連中はつまんねえことでもめてるよww

520 名前:デフォルトの名無しさん mailto:sage [2010/04/28(水) 21:10:53 ]
>>519
だよな、時代はD言語だろうに老頭児なC厨はオナニーでもしてろってのw

521 名前:デフォルトの名無しさん mailto:sage [2010/04/28(水) 21:12:26 ]
これだからC厨は・・・

522 名前:デフォルトの名無しさん mailto:sage [2010/04/28(水) 21:12:59 ]
D(笑)



523 名前:デフォルトの名無しさん mailto:sage [2010/04/28(水) 21:14:18 ]
おじいさまがたはFORTRANでも使っててください

524 名前:デフォルトの名無しさん [2010/04/28(水) 21:14:28 ]
老頭児って中国語か

525 名前:デフォルトの名無しさん mailto:sage [2010/04/28(水) 21:18:30 ]
おじいさまがたは LISP でも使ってください、
ん?

526 名前:デフォルトの名無しさん mailto:sage [2010/04/28(水) 21:24:39 ]
>>523,525
すまん、俺まだ20代だが両方とも会社で使ってるw

527 名前:デフォルトの名無しさん mailto:sage [2010/04/28(水) 21:32:21 ]
LISPは未だに超強力だからな。まあWindowsアプリに限って言うならC#の時代が来るかもしれない。囲い込みだしな
でもプログラムはWindowsアプリだけじゃないし、つーかDって誰が普及させるんだよw
世界中で使われてるCの牙城を崩す気ねーだろ
あとWebプログラミングのLLはこれからも生き残る

528 名前:デフォルトの名無しさん mailto:sage [2010/04/28(水) 21:35:21 ]
LISPはemacsとかあるからまぁ使う機会はそこそこあるかもしれんが
FORTRANを使う場面はまったく思い浮かばん
昔大学で実験に使って以来やってないから、もう文法もわがんね

529 名前:デフォルトの名無しさん mailto:sage [2010/04/28(水) 21:49:20 ]
順次アクセスとかそんなイレギュラーな使い方は普通しないし。

530 名前:デフォルトの名無しさん mailto:sage [2010/04/28(水) 22:02:10 ]
Fortranは大学ではまだつかってるところあるけど
Lispってemacsのマクロくらいしかないよ

って書こうとしてリロードして>>528を読んだ
たぶんほとんど同じものを見たのに出した答えが真逆で面白いなと思った

531 名前:デフォルトの名無しさん mailto:sage [2010/04/28(水) 22:25:40 ]
構造体の入れ子ってあまりよくないことなんでしょうか?(設計に問題あり?)


532 名前:デフォルトの名無しさん mailto:sage [2010/04/28(水) 22:27:57 ]
別に普通



533 名前:ノラ [2010/04/28(水) 23:55:51 ]
いま学校の課題で
do-while文を使って
1+2+3・・・というように数値を加算して表示し、
加算結果が300を超えたら表示して
処理を終了するというプログラムを組みたいのですが、
普段から授業ついていけなくて、よくわかりません
どなたか教えてください。お願いします

534 名前:デフォルトの名無しさん mailto:sage [2010/04/28(水) 23:57:45 ]
>>533
ここは入門スレなのであまり高度なことはお答えできません。

535 名前:ノラ [2010/04/29(木) 00:00:38 ]
>>534
どうしたらいいですか?

536 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 00:02:05 ]
中学校の課題?

537 名前:ノラ [2010/04/29(木) 00:03:53 ]
>>536
いえ専門なんですが
全く授業についていけなくてですね・・・

538 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 00:03:56 ]
>>535
pc12.2ch.net/test/read.cgi/tech/1246115922/

こちらへどうぞ

539 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 00:04:27 ]
#include <stdio.h>

int
main(void)
{
  int i = 1;
  int sum = 0;

  do {
    sum += i++;
  } while (sum < 300);
  printf("%d\n", sum);

  return 0;
}


540 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 00:04:29 ]
そういうときは美味しいカレーのレシピを書いて提出だろう

541 名前:ノラ [2010/04/29(木) 00:12:06 ]
>>539様ありがとうございます。
参考にしてがんばってみます

542 名前:ノラ [2010/04/29(木) 00:14:24 ]
>>539
sum入れないでもできますか?



543 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 00:16:16 ]
ついていく気は無いようだwww

544 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 00:24:11 ]
>>542 自分でやれよカス

545 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 00:52:38 ]
>>542
#include <stdio.h>

int
main(void)
{
int i = 1;
do {
printf("%d\n", i * (i + 1) / 2);
i++;
} while (i * (i + 1) <= 600);
return 0;
}


546 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 00:55:13 ]
>>542
結果を格納しておく変数が必要なわけ。
加算していって、それをどこに保持しておくの?って話になるでしょ?

だから、この場合は「sum」っていうy変数に入れてる。
別にgoukeiでもsでも、C言語の規則に従ってればなんでもいい。

547 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 00:55:55 ]
>>545
綺麗だけど初心者には分かりづらいソースだなwwwwwwwwww

548 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 01:03:48 ]
まて、少なくとも綺麗ではない

549 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 01:16:39 ]
この手の問題は、答えが分かるのなら質問しない。つまり初めから論外なレベル
宿題スレじゃないんだからさ

550 名前:デフォルトの名無しさん [2010/04/29(木) 02:39:15 ]
ちょっと質問なんですけど。。。
Raw Socketってあるぢゃないですか?
私の開発環境はWindowsでVC++ 2008なので
Winsock2を使ってws2_32.libをリンクし、
socket(AF_INET,SOCK_RAW,IPPROTO_IP);
こうやって書くんだと思うんですが(違ったらまた勉強してきます)、
IPヘッダを作成するときにIPを偽装できるという記事を
拝見したことがあります。

その場合、IPというのは何のIPなのでしょうか?
プライベートIPですか?
グローバルIPですか?

仮にグローバルIPを返られるとした場合、
例えば携帯IPに変更することは可能なのですか?

もし可能なら大変なことになるのでそれは出来ないと思うのですが、
出来たとしたら掲示板などはどのような対策を施すのでしょうか?

■以下、板違い発言すみません。
私はC言語のほかにPerlやPHPなどCGIで掲示板などを作成してます。
もし上記に書いたようなグローバルIPを偽装するような行為があったとしたら
どのように防げばいいかわかりません・・・
できればそんなこと出来ないものだと願いたいものです。。。

551 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 06:42:02 ]
>>550
スレチとか死ねよゴミ野郎

IPの偽装は現在は無理
一言でいうとヘッダに書いてあったIPに本当にそいつが送ってきたのか確認するから

それとグローバルIPですかプライベートIPですか?って質問も相当アホ



552 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 09:19:03 ]
グローバルだよ (LAN内にサーバもあるならローカルでもいいけど)

携帯のふりもできるよ 掲示板は対策要らないよ
あんたの掲示板はTCPだろうから>>551が言うようにそのIPに対して問い合わせするわけだから
偽装された他人に問い合わせしても返事来ないでしょ

UDPで動く(昔のネットゲームとか?)ものなら がんばって通信内容もまねれば 
他人がゲームやってるときにちょっかい出せるかもしれんけど



553 名前:デフォルトの名無しさん [2010/04/29(木) 15:12:39 ]
すみません、矩形画像出したくて以下のを書いてみたんですが画像が表示されません。
誰かお願いします。

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
char fi[50];
float buff[128*128];
int nx = 128, ny = 128;
int i, j;
FILE *fp;

// 画像の初期化
for (i = 0 ; i < nx*ny ; i++)
buff[i] = 0;



554 名前:デフォルトの名無しさん [2010/04/29(木) 15:14:47 ]
// 矩形画像の作成
for (i = 32 ; i <= 96 ; i++) {
for(j = 32 ; j <= 96 ; j++) {
buff[i*nx+j] = 100;
}
}

// 画像の書き出し
printf( "Input new file name: " );
scanf( "%s", fi );
if ((fp = fopen ( fi, "wb")) == NULL) {
printf("Error: file open [%s].\n", fi);
exit (1);
}
fwrite(buff, sizeof(float), 128*128, fp);
fclose (fp);
}


555 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 15:22:34 ]
どこそこがおかしいと言うレベルじゃなくめちゃくちゃなんだが
お前それ本とかみてやってそうなのか?

556 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 15:28:34 ]
>>553
画像ヘッダをつけるかフォーマット指定してビューワに読み込ませれば表示できるかもしれない
ACDSEE とかそういうの

float 型の画像ってことはCTスキャンデータかな?
後輩だったりしてw

557 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 15:29:11 ]
ウィンドウに絵を表示したいの?それとも画像ファイルを出力したいの?
前者ならまずウィンドウを作成しないと。
後者なら出力したい画像フォーマットに従ってデータを出力しないとダメだよ。

558 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 15:46:14 ]
>>557
とりあえず raw形式でいいんじゃない?

559 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 16:11:29 ]
釣りにつられたようだ

560 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 16:37:32 ]
>float 型の画像ってことはCTスキャンデータかな?

先輩、今時CTのデータが128ってことはないでしょ 
ネマコードもないし DICOM形式でもない

561 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 09:51:52 ]
ヘリカルスキャンCTの場合で、512x512x200くらいは平気でありそうだ。
つーか、float生データでも適切なツールを使えば表示はできるだろうけどね。
いずれにしても、Cの話じゃなく画像フォーマットの話というか仕様の解釈の話だ。

562 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 10:53:29 ]
ヘリカルCTなら512x512x320くらいデフォだけど
型はshortだな



563 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 11:15:48 ]
結局文型が業界にたくさん入ってきて保身に全力だからじゃないの?
あいつら技術的なこと分からないから技術持ってるベテランにいてもらうと邪魔なんだよ。
そいうやつらが外注管理とか客先交渉とかの技術的なこと分からなくてもできる仕事を創出してこの業界で生き残れるシステムを作ったんじゃないだろうか。
技術のない正社員はすぐ首にできるシステムになってないのがいけないんだと思うんだ。
だいたい技術職なのに技術にこだわってるやつを軽蔑する空気があるのはおかしいと思う。

564 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 11:18:53 ]
誰かが言った、偉大なる素人集団だと。

565 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 12:00:27 ]
そういう時、アメリカなら技術者だけが出て行って別会社を作る
たとえばintelの技術者が「もっとすごいCPUを作りたい」といって、独立して作った会社がAMD

ただし営業力がなくて負ける

566 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 13:33:12 ]
でもさ、反論を覚悟で書くけど

技術が高くてもメシは食えないんだよね
でも営業が小ざかしいくらい上手いと技術がクソでも売れる
メインな部分どっかに丸投げでもOK 
宣伝の上手い声の大きいやつが勝つ


あと、技術持ってないやつが上にいたりすると楽だよね
「あ、それ2週間はかかります」とかどう考えても5分で終わる仕事でも平気でそんな事いってみたり
ある程度技術があるようならバレバレでもさ
(「そんなことしてるお前がクソなんだよ」って言われちゃうだろうな)

567 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 13:35:19 ]
お前らマ板に帰れよ

568 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 13:39:55 ]
>>566
上が技術だとある意味もっと楽だぞ。
こっちの話がちゃんと伝わるから、更に上にリソースの確保をきちんと交渉してくれる。
尤も、弊社の場合No.2まで技術系だから突っ込まれたときはやばいw

569 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 13:40:35 ]
いい加減巣に帰れよ

570 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 13:41:26 ]
>>569
スレ違いの雑談と言う意味ではあんたも同罪。

で、Cの初歩的な質問未だ?w

571 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 13:43:10 ]
reallocって失敗したら元のデータはどこかへ消えてしまうんですか?
そのあたりがよくわかりません

572 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 14:07:53 ]
>>571
お前にわかる必要など無い



573 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 14:09:40 ]
>>571
宇宙の法則がみだれるからな・・・

574 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 14:54:33 ]
>>571
大丈夫。realloc()はメモリ確保に成功しない限り元の領域は解放しない。
つまり、使う側が間抜けでない限りどこにも消えはしない。

575 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 15:10:13 ]
>>574
回答ありがとうございます
reallocに与えるアドレスをとっておいて、reallocがNULLを返したらそっちを取り扱えばいいってことですね

とはいえ今まで一度もmalloc系が失敗するとこをみたことないんですけどね

576 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 15:57:46 ]
>>575
いつ失敗するんだろうと思って延々mallocをしてみるのが普通のマ。

577 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 15:59:32 ]
まぁ確かに。標準設定のままのLinuxだと楽観的メモリ管理を採用しているから
以上に大きな値を指定しない限り、メモリが足りようと足りなかろうとNULLは返さないからね。

で、実際に使おうとしたときに足りなくなるとプロセス落として知らん顔w

578 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 16:09:09 ]
カーネルパラメータいじる前にメモリを増設します

579 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 16:12:07 ]
じゃあ俺は64bitLinuxにしてかつスワップもりもりにする

580 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 16:17:50 ]
Linuxのソースを改造してメモリ管理を改善させます。

581 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 16:20:17 ]
なにを改善するんだろ。楽観的メモリ管理をやめるために改造するはずはないし

582 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 16:24:21 ]
楽観的メモリ管理をやめたいだけなら設定変更するだけじゃなかったっけ?
まぁ、Linux板向けの話だね。



583 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 18:39:33 ]
/proc/sys/vm/overcommit_memory

584 名前:側近中の側近 ◆0351148456 [2010/04/30(金) 19:19:45 ]
>>575
(っ´▽`)っ いや、異常終了にしたほうがいいんじゃね?
alloc系がエラー返すって相当やばいから、処理続行するのは危険だね。

585 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 20:19:21 ]
reallocしたい場面にもかかわらず、reallocに失敗しても続行できる場面が想像しがたいけど、
続行できるのなら続行してもいいと思うよ。
ほんとに必要な場面で失敗したなら異常終了で。

586 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 20:23:22 ]
そういう場面では、キャッシュとして確保しっぱなしのメモリを開放とかじゃないかなあ・・・

587 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 21:20:56 ]
つか、実際そういう時って
固まっちゃって動かなくて、引き続き他の動作もクソもないよな

588 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 21:44:01 ]
Hello, world!
の出力を21byteで思いつける天才いる・・・?
code golfです。

golf.shinh.org/p.rb?hello+world

589 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 21:48:52 ]
なんでgorubyがあってHQ9はないんだろうな

590 名前:588 mailto:sage [2010/04/30(金) 21:53:43 ]
あ〜・・・
C言語ね・・・

591 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 22:04:09 ]
>>588
#include使ったチート技じゃないかい?

592 名前:側近中の側近 ◆0351148456 [2010/04/30(金) 22:05:45 ]
>>588
(っ´▽`)っ
#error Hello, world!



593 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 22:16:04 ]
側近ってこんなところにも来るんだ・・・
今日のアキバにしか存在できないと思ってた

594 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 22:16:23 ]
>>592
側近死ね

595 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 22:17:24 ]
安価同じw

596 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 22:30:57 ]
側近マジ死ねよ消えてくれ。ウザい。

597 名前:デフォルトの名無しさん [2010/05/01(土) 01:29:47 ]
int *cp = (int *)calloc(50, sizeof(int));
int *p[5][10];
for(int i = 0; i < 5; i++){
for(int j = 0; j < 10; j++){
p[i][j] = cp++;
}
}

*cpのデータは外部モジュールから受け取る2次元の情報で縦、横のサイズは決まっている。
ここではとりあえずcallocで代入。
2次元として加工したいのでポインタの二次元配列を宣言して「それぞれの要素にポインタを代入していく」。

「それぞれの要素にポインタを代入していく」操作が結構まどろっこしいように思えるのですが、もう少しスマートな方法はありますか?

598 名前:デフォルトの名無しさん mailto:sage [2010/05/01(土) 01:44:25 ]
>>588
まったく思いつかない。
どうやったんだ?

599 名前:デフォルトの名無しさん mailto:sage [2010/05/01(土) 01:55:46 ]
すみません、質問させてください
問題の箇所以外ははしょってますが

#define LINE_BUF 1024

main(){

int i;
int num;
char rf[LINE_BUF];

scanf("%d", &num);
fflush(stdin);

fgets(rf, LINE_BUF, stdin);



}
-------

残っている改行文字をfflushして、
次のfgetsにいきたいのですが、fgetsがそのまま飛んでしまいます

改行文字が入力ストリームに残っている、という状態なのかと思いますが
まずいと思われる箇所を指摘していただけると幸いです

600 名前:デフォルトの名無しさん mailto:sage [2010/05/01(土) 01:59:41 ]
>>599
コンパイラによっては使えることもあるけど
fflush(stdin);
は未定義動作

601 名前:デフォルトの名無しさん mailto:sage [2010/05/01(土) 02:01:25 ]
>>599
scanf("%d", &num);
fflush(stdin);

fgets(rf, LINE_BUF, stdin);
sscanf(rf, "%d", &num);

602 名前:デフォルトの名無しさん mailto:sage [2010/05/01(土) 02:03:13 ]
なるほど、ありがとうございます
fflush関係のページをいろいろ見てみます
夜分遅くに、早いレス大変助かりました



603 名前:デフォルトの名無しさん mailto:sage [2010/05/01(土) 02:04:14 ]
調べてわからなければ聞くようにしろよ

604 名前:デフォルトの名無しさん mailto:sage [2010/05/01(土) 02:06:58 ]
>>601
これまた申し訳ございません
なるほど、こちらは一旦文字列をクッションに使う感じですね
こちらも後で試してみます
ありがとうございました

605 名前:デフォルトの名無しさん mailto:sage [2010/05/01(土) 02:21:37 ]
>>603
fflush(stdin)

setbuf(stdin, NULL)
と変更することでちゃんと動いてくれました

>>601
こちらの方法でも無事確認出来ました

お二人ともどうもありがとうございました

606 名前:デフォルトの名無しさん mailto:sage [2010/05/01(土) 02:37:00 ]
kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10582.txt
kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10583.c

上のテキストファイル(年別の平均気温などのデータ)の2列目のデータの小さいほうから順番に並べかえて、ファイルに出力するプログラムを作りたいのですがうまくいきません。
コンパイルは通るのですが、うまく作動しません
どこが違うんでしょうか?
なんかソートの部分がうまくいってない気がするのですが、よくわかりません
よろしくお願いします

607 名前:デフォルトの名無しさん mailto:sage [2010/05/01(土) 03:48:20 ]
nが2重に使われているのと

for( n=0 ; n < number ; n++ ){
for( j=n+1 ; n < number ; j++ ){
の2行目はj < numberかと

608 名前:デフォルトの名無しさん mailto:sage [2010/05/01(土) 03:54:48 ]
for( n=0 ; n < number ; n++ ){
// for( j=n+1 ; n < number ; j++ ){
for( j=n+1 ; j < number ; j++ ){

// for( n=0 ; n < number ; n++ ){
for( j=0 ; j < number ; j++ ){

609 名前:607 mailto:sage [2010/05/01(土) 04:01:49 ]
ああ、見直してみたらnは2重になってなかったや。。
整形せずに見たらごらんの有様だよ

610 名前:デフォルトの名無しさん mailto:sage [2010/05/01(土) 04:21:21 ]
It's eight tabs.

611 名前:側近中の側近 ◆0351148456 [2010/05/01(土) 07:30:02 ]
>>597
(っ´▽`)っ

for(int i = 0; i < 5; i++){
for(int j = 0; j < 10; j++){
p[i][j] = cp++;
}
}

の部分が、

memcpy(p, cp, sizeof(p));

でいけそうだが。どうだろう?

612 名前:側近中の側近 ◆0351148456 [2010/05/01(土) 07:35:27 ]
(っ´▽`)っ
メモリ上の表現がpとcpで同じってところがポイントな。
どちらも、sizeof(int *)*50 バイト分、連続した領域が確保されている。



613 名前:デフォルトの名無しさん mailto:sage [2010/05/01(土) 07:40:54 ]
何を代入してるかわかってない

614 名前:側近中の側近 ◆0351148456 [2010/05/01(土) 07:42:16 ]
(っ´▽`)っ
cpとcを同じ共用体で定義すれば、コピーが不要になる。
union U
{
  int *cp;
  int *c[5][10];
};

615 名前:側近中の側近 ◆0351148456 [2010/05/01(土) 07:46:23 ]
>>613
(っ´▽`)っ cpは実体の配列、cは各々のポインタの配列だったか・・・。
しにたい

616 名前:側近中の側近 ◆0351148456 [2010/05/01(土) 07:55:51 ]
>>614
(っ´▽`)っ ダブルポインターにしないとね☆

union U
{
  int **cp;
  int *c[5][10];
};

617 名前:デフォルトの名無しさん mailto:sage [2010/05/01(土) 10:18:19 ]
NG Name:側近中の側近 ◆0351148456

618 名前:デフォルトの名無しさん mailto:sage [2010/05/01(土) 10:20:22 ]
ID出ないからコテなのはありがたいねw

619 名前:梓川水乃 ◆0351148456 [2010/05/01(土) 12:57:35 ]
>>618
(っ´▽`)っ そうだね☆

620 名前:デフォルトの名無しさん mailto:sage [2010/05/01(土) 13:18:54 ]
codepad.org/lVHSm6Xk
codepad.org/JhFT5Ged
codepad.org/KW2MGMGe
単純過ぎるくらい単純にしないと当方バカなので3日後に読めないのです


621 名前:606 [2010/05/01(土) 15:07:07 ]
指摘された部分を直したらファイルは出力されるようになったのですが、出力されたデータが
00000000000000000000000000000000000000みたいな感じになっちゃってます

622 名前:デフォルトの名無しさん mailto:sage [2010/05/01(土) 15:20:23 ]
ちゃんと>>608の指摘した2箇所を直したか?
後半のはfprintfのループのところだぞ?



623 名前:597 [2010/05/01(土) 15:28:27 ]
>>616
それだと2重ポインタの方が0x00000000のままなので、
渡されるデータの位置アドレスと、配列の先頭アドレスとで共用してくれません。

私の例ではポインタの2次元配列にしていますが、2次元配列(ポインタではない)の先頭アドレス=渡されるデータの位置アドレス
となればそれが一番いいのですけど…

int hairetu[5][10];
int **p = hairetu;
これの逆バージョン…

int *p = (int *)0x********;
int a;
&a = p;
無茶ぶりですが配列無しでいえばこんな動作…やっぱり無理な気がしてきました。

624 名前:606 mailto:sage [2010/05/01(土) 15:39:59 ]
>>622
一つだけnがjに変わってませんでした
確認不足でした
無事に出力することができました
ありがとうございます

625 名前:デフォルトの名無しさん mailto:sage [2010/05/01(土) 15:50:06 ]
>>623
やりたいことがいまいちわからない

こういうことかな?

union tag_hoge_t
{
int cp[50];
int c[5][10];
}hoge_t;

int *p=(int*)0x********;
hoge_t *q=(hoge_t*)p;

q->cp[10]==q->c[1][0];

============================================================
それともこうかな?

int *cp=(int*)0x********;
int (*c)[10]=(int*[10])cp;

c[1][1]==cp[11];

626 名前:デフォルトの名無しさん mailto:sage [2010/05/01(土) 16:03:45 ]
>>625
訂正
int (*c)[10]=(int(*)[10])cp;

627 名前:597 [2010/05/01(土) 16:20:26 ]
>>625
ズバリそれです!!どちらでも理想の動作でした!
共用体のポインタもできるんですね。
後者は仕組みがよくわからないのでもう少し考えてみます。
後者の方がスマートで見た目がわかりやすいのでそちらを利用したいと思います。
以下に自分のやりたいことの完成形を載せておきます。
ありがとうございました!


union tag_hoge_t
{
int c[5][10];
};

int *p=(int*)0x********;
tag_hoge_t *q=(tag_hoge_t*)p;

if(q->c[1][0] == 10)…

============================================================

int *p=(int*)0x********;
int (*c)[5][10]=(int (*)[5][10])p;

if((*c)[1][0] == 10)…

628 名前:597 [2010/05/01(土) 16:25:34 ]
>>627
後者はポインタの配列ではなく、配列のポインタになっているんですね
勉強になりました!

629 名前:デフォルトの名無しさん [2010/05/01(土) 20:30:06 ]
IMG 02691 JPG
www.seikei.or.jp/kakubu/rehabili/IMG_02691.JPG
私たちが当院の言語聴覚士です 宜しくお願いします
www.yushinkai.jp/hakodate/design/image/come/reha/Ststh.jpg
言語聴覚士を目指す高梨さん
www19.atpages.jp/imagelinkget/get.php?t=v&u=www.tokai-med.ac.jp/kagaku/gakka_st/images/real_photo1.jpg
理学療法士 作業療法士 言語聴覚士
www.ims.gr.jp/ohtafukushima/images/section/photo_section_05.jpg


630 名前:デフォルトの名無しさん mailto:sage [2010/05/02(日) 11:54:32 ]
マクロ機能って標準Cに含まれるんですか?

631 名前:デフォルトの名無しさん mailto:sage [2010/05/02(日) 12:22:15 ]
当然

632 名前:デフォルトの名無しさん mailto:sage [2010/05/02(日) 13:13:26 ]
#include <stdio.h>

int main(void)
{
int a, b;

printf("キーボードから数値を入力してください");
printf("数値1を入力してください:"); scanf("%d", &a);
printf("数値2を入力してください:"); scanf("%d", &b);


printf("10割る3は、%d余り%dです。\n", a / b, a % b);

return (0);

}

8行目が違うっぽいんだけど、なんで?



633 名前:デフォルトの名無しさん mailto:sage [2010/05/02(日) 13:14:39 ]
全角スペース

634 名前:デフォルトの名無しさん mailto:sage [2010/05/02(日) 13:15:19 ]
printf("数値1を入力してください:"); scanf("%d", &a);
scanfの前が全角スペースになってる

635 名前:デフォルトの名無しさん mailto:sage [2010/05/02(日) 13:16:13 ]
>printf("10割る3は、%d余り%dです。\n", a / b, a % b);
printf("%d割る%dは、%d余り%dです。\n", a, b, a / b, a % b);

636 名前:デフォルトの名無しさん mailto:sage [2010/05/02(日) 13:20:22 ]
>>633-635
ありがとう!

637 名前:デフォルトの名無しさん mailto:sage [2010/05/02(日) 14:23:17 ]
文字型の変数を初期化する時に、本のサンプルコードには

char ch = '\0'

って書いてあるんだけど、この\0ってエスケープシーケンスの「\xxx:8進数でxxxの文字コードを持つ文字」って解釈で良いんですかね?
xxxだから数字が3文字(例えばnullを表す場合は\000のように)じゃなきゃいけないと思ってたんだけど、
上の例みたいに数字1文字で表せる場合は省略しちゃっても良いんですか?

638 名前:デフォルトの名無しさん mailto:sage [2010/05/02(日) 14:51:10 ]
君は最初から最後まで間違っている

639 名前:637 mailto:sage [2010/05/02(日) 14:52:17 ]
え・・・・何が間違っているのか指摘して頂けると助かるのですが・・・・

640 名前:デフォルトの名無しさん mailto:sage [2010/05/02(日) 15:04:43 ]
'\000' で問題ないと思うけど、'\xxx'でも'\xx' '\x'でも。

641 名前:637 mailto:sage [2010/05/02(日) 15:06:31 ]
ああなるほど理解できました。ありがとうございました。
xxxっていうのは要するに一般化された時の便宜で3文字表記になってただけなんですね。

642 名前:デフォルトの名無しさん mailto:sage [2010/05/02(日) 15:07:38 ]
なんで'\0'より先にエスケープシーケンスがどうこう言ってるんだろう



643 名前:デフォルトの名無しさん mailto:sage [2010/05/02(日) 15:12:58 ]
たぶんさ 彼はポインタをNULLにしたがてる所と間違ってるとも生んだけど
厳密には\0とNULLはちげーよって言うエライ方のお話はとりあえず置いておいて

644 名前:637 mailto:sage [2010/05/02(日) 15:15:50 ]
>>642
このような表記のされ方で、既に読んだ部分に書いてある知識がエスケープシーケンスしかなかったのです・・・
本は結構親切な部類に入るんですけど、文字型変数を初期化する時の'\0'っていきなり出てきたので混乱してますorz
エスケープシーケンスじゃないんですか?

645 名前:デフォルトの名無しさん mailto:sage [2010/05/02(日) 15:19:47 ]
'\0'なんて機械的にそういうもんだと覚えるほうが多いと思うんだが。

646 名前:デフォルトの名無しさん mailto:sage [2010/05/02(日) 17:58:39 ]
>>644
\で始まる表記なので、エスケープシーケンスという解釈であってるよ。

647 名前:デフォルトの名無しさん [2010/05/02(日) 20:13:31 ]
>>646
だね

648 名前:デフォルトの名無しさん mailto:sage [2010/05/02(日) 22:53:36 ]
ダブルクォーテーションの出力ってどうすればいいのでしょう?
printf(""""); こんなことやっても出てこないので泣きそうです・・・

649 名前:デフォルトの名無しさん mailto:sage [2010/05/02(日) 22:55:06 ]
>>648
"\"\""

650 名前:デフォルトの名無しさん mailto:sage [2010/05/02(日) 22:55:21 ]
\"

651 名前:デフォルトの名無しさん mailto:sage [2010/05/02(日) 22:57:00 ]
>>649
ありがとうございます!!

652 名前:デフォルトの名無しさん mailto:sage [2010/05/02(日) 23:49:47 ]
646で思いっきりエスケーなんちゃらの話しがでてるのに
いきなりprintfでダブルコーテションどうやんの?とか釣りだろ



653 名前:デフォルトの名無しさん mailto:sage [2010/05/02(日) 23:54:14 ]
>>652
頭の悪い奴だよなw

654 名前:デフォルトの名無しさん mailto:sage [2010/05/03(月) 00:05:58 ]
おれも似たようなこと聞いて良い??

行が長いときの行末に置く¥あるじゃないですか
行末は良いんだけど、数行になると、そこ数行だけ行頭から始まるのが嫌なんだけど
あれをインデントしても良い方法ってないすか?先生方よろしくお願いします

655 名前:デフォルトの名無しさん mailto:sage [2010/05/03(月) 00:07:31 ]
文字列の話です

656 名前:デフォルトの名無しさん mailto:sage [2010/05/03(月) 00:11:45 ]
>>654
一旦ダブルクォートを閉じればいい

char foo[]="ABC"
"DEFG"
"H";

657 名前:デフォルトの名無しさん mailto:sage [2010/05/03(月) 00:44:22 ]
ほんとうだ、先生ありがとう 

658 名前:デフォルトの名無しさん mailto:sage [2010/05/03(月) 02:10:09 ]
どういたしまして

659 名前:デフォルトの名無しさん [2010/05/03(月) 16:19:16 ]
C言語により記述された次の関数fがある。ここで、display()は
画面に1個の文字Aを書く手続きであるとする。
int f(int x){
display();
if(x==0)return 1;
if(x==1)return 3;
if(x==2)return 5;
return(f(x-1)+f(x-2)+f(x-3));
}
いま、f(x)を呼び出したとき、値105が返された。このf(x)が呼び出されてから
値を返すまでの間に、文字Aは画面にいくつ書かれたか。
1.43 2.44 3.45 4.46 5.47

すみませんが、このプログラムを文章に言い換えてもらえないでしょうか?

660 名前:デフォルトの名無しさん mailto:sage [2010/05/03(月) 17:05:34 ]
我輩はfである


661 名前:デフォルトの名無しさん mailto:sage [2010/05/03(月) 17:10:58 ]
>>659
下記の二式 f(x) および g(x) が与えられている

f(x)=f(x-1)+f(x-2)+f(x-3)
f(0)=1
f(1)=3
f(2)=5

g(x)=1+g(x-1)+g(x-2)+g(x-3)
g(0)=g(1)=g(2)=1

f(x)=105 であるとき g(x) はいくらになるか?

662 名前:デフォルトの名無しさん mailto:sage [2010/05/03(月) 17:15:21 ]
x>3の時、f(x)=f(x-1)+f(x-2)+f(x-3)
x<=3の時、
f(0)=1
f(1)=3
f(2)=5

だな



663 名前:デフォルトの名無しさん mailto:sage [2010/05/03(月) 17:27:36 ]
>>662
x≧3とx<3

664 名前:デフォルトの名無しさん mailto:sage [2010/05/03(月) 18:08:57 ]
宿題は宿題スレへ

665 名前:デフォルトの名無しさん mailto:sage [2010/05/03(月) 19:51:51 ]
「負の値が入力されるまで繰り返す」ってどうやるんだっけ?

666 名前:デフォルトの名無しさん mailto:sage [2010/05/03(月) 19:54:47 ]
入力値が0以上っていうのを継続条件にしましょう

667 名前:デフォルトの名無しさん mailto:sage [2010/05/03(月) 19:55:47 ]
なんで「どうやるんだっけ?」ってまるで以前は知ってたみたいな風に聞くの?

668 名前:デフォルトの名無しさん mailto:sage [2010/05/03(月) 19:58:06 ]
そういう設定なんです

669 名前:デフォルトの名無しさん mailto:sage [2010/05/03(月) 19:58:32 ]
痴呆症なんだろう

670 名前:デフォルトの名無しさん mailto:sage [2010/05/03(月) 20:08:58 ]
敵のスタンド攻撃で忘れちゃうんです

671 名前:デフォルトの名無しさん mailto:sage [2010/05/03(月) 20:10:25 ]
>>661>>662>>663
ありがとうございます

ところで
>g(x)=1+g(x-1)+g(x-2)+g(x-3)
>g(0)=g(1)=g(2)=1
はどこから出てきたんでしょうか?

672 名前:デフォルトの名無しさん mailto:sage [2010/05/03(月) 20:13:12 ]
f(x)一回につき文字を一個表示してるところからだろw



673 名前:デフォルトの名無しさん mailto:sage [2010/05/03(月) 21:25:43 ]
g(x) は表示回数を返す関数を定義してるだけ

x=0,1,2 の時は 1回書いて 抜ける: g(0)=g(1)=g(2)=1
それ以外では 1回書いた後、

674 名前:デフォルトの名無しさん mailto:sage [2010/05/03(月) 21:26:58 ]
途中送信してしまったが… (上略)
あとはわかるな

675 名前:デフォルトの名無しさん mailto:sage [2010/05/03(月) 23:19:16 ]
ポインタのサイズは4バイトの固定というのを見た事があるのですが、
64bitの場合でも同じですか?

676 名前:デフォルトの名無しさん mailto:sage [2010/05/03(月) 23:21:17 ]
別に固定じゃない

677 名前:デフォルトの名無しさん mailto:sage [2010/05/03(月) 23:22:28 ]
はい

678 名前:デフォルトの名無しさん mailto:sage [2010/05/03(月) 23:51:34 ]
見た事はすべて忘れろ

679 名前:デフォルトの名無しさん mailto:sage [2010/05/04(火) 00:05:48 ]
この環境のこのコンパイラは4バイト固定です、みたいな所読んだんだろ
それはそれで忘れちゃダメだろ

680 名前:デフォルトの名無しさん mailto:sage [2010/05/04(火) 00:14:20 ]
intが16ビットの環境だとポインタも2バイトだったの?

681 名前:デフォルトの名無しさん [2010/05/04(火) 00:15:45 ]
>>675
8バイトだよ
main() {
printf("%u", sizeof(void*));
}

682 名前:デフォルトの名無しさん mailto:sage [2010/05/04(火) 00:25:49 ]
データーバスのビット数とアドレスバスのビット数が違う環境があってな
int 型は、おおよそデータバスのビット数にあわすことが多いが
ポインタは、おおよそアドレスバスのビット数にあわすことが多い

アドレスレジスタが単純に並ばない 変態的な環境もあったのさ:
16ビットレジスタx2 を使って 24ビット物理アドレス を指す。  



683 名前:デフォルトの名無しさん mailto:sage [2010/05/04(火) 00:28:10 ]
>>681
環境書かなきゃ全く意味無いよ

684 名前:デフォルトの名無しさん [2010/05/04(火) 00:33:36 ]
すぐ気付いたけどもういい

685 名前:デフォルトの名無しさん mailto:sage [2010/05/04(火) 04:44:08 ]
64ビット64ビットと偉そうに言ってるけどさ、
結局はいまだ1バイト8ビットじゃん。
そろそろ進化させないのか?
C言語の生まれたPDP-11でさえ10ビットあったのに。
俺に言わせりゃi7もPhenomも8ビットCPUだよ。
進歩してない。

686 名前:675 mailto:sage [2010/05/04(火) 08:15:31 ]
>>681
thx

687 名前:デフォルトの名無しさん mailto:sage [2010/05/04(火) 09:09:35 ]
>>685
確かに1バイトは8ビットだけど、いまどきワード以外のデータを
使うなんて貧乏人だけだよ
C言語のcharとかshortとか互換性のためだけに残ってるけど
富豪は常にintですよ。0か1のフラグ変数にもint使いますよ
しかもILP64ですよ

688 名前:デフォルトの名無しさん mailto:sage [2010/05/04(火) 10:11:45 ]
×貧乏人だけ
○キャッシュ効率のことが頭にないバカだけ

689 名前:デフォルトの名無しさん mailto:sage [2010/05/04(火) 11:11:28 ]
命令増やしてキャッシュ潰してりゃ世話ないな

690 名前:デフォルトの名無しさん mailto:sage [2010/05/04(火) 11:33:45 ]
文字もintなのか
すげぇな

691 名前:デフォルトの名無しさん mailto:sage [2010/05/04(火) 12:54:31 ]
>>680
8086でMS-DOSの頃
16ビット(64KB)の範囲しか扱わないモードと1MBアクセスできるモードがあって
使い分けていた。今でもfarとかnearという残骸を見ることあるでしょ?

692 名前:デフォルトの名無しさん mailto:sage [2010/05/04(火) 14:19:06 ]
>>691
WIndows95の頃Morland-C++5.0を買ったんだが、えらくぶ厚い
マニュアルが数冊入っていて、今では考えられない位に8086のアーキテクチャ
を詳しく解説してあった

Windows3.1もまだまだ現役だった頃なので、STRICTを使ったプログラミング
も非常に克明に書いてあって、今読み返すと「ああこの頃はまだコンパイラ
メーカはやる気があったんだなあ」と思わせる



693 名前:デフォルトの名無しさん mailto:sage [2010/05/04(火) 14:20:17 ]
ああビール飲んでるからかtypoした

×Morland-C++
○Borland-C++

昼間から酒飲めるのは今日までか・・・orz

694 名前:デフォルトの名無しさん mailto:sage [2010/05/04(火) 15:35:54 ]
Cの文法的に下の書き方は正しいのでしょうか?

unsigned short Value;
Value = ((unsigned short)('AB'));

コンパイルされたアセンブリソースを見ると期待通りの結果になっているのですが、
移植等を考慮した場合、この書き方は避けるべきなのでしょうか?

movw ax,#04142H

分野は組込で、コンパイラはNECのものですが、エラーも警告もなしで通ります。
ググってみたものの、'A'については記述があるものの、期待する記述には出会えませんでした。

どうか、よろしくお願い申し上げます。

695 名前:デフォルトの名無しさん mailto:sage [2010/05/04(火) 16:02:52 ]
文法上は問題なし。 意味は処理系依存。


696 名前:デフォルトの名無しさん mailto:sage [2010/05/04(火) 16:05:45 ]
JIS X3010:2003 6.4.4.4 文字定数 より
2文字以上を含む(例えば 'ab')又は1バイトの実行文字で表現できない文字若しくは逆斜線表記を含む単純文字定数の値は, 処理系定義とする。

697 名前:デフォルトの名無しさん mailto:sage [2010/05/04(火) 16:23:26 ]
bccでやったら4241になったw

698 名前:デフォルトの名無しさん mailto:sage [2010/05/04(火) 16:24:34 ]
>>695-696
ありがとうございました。
時間があるときにJIS X3010:2003をよく読んでみます。

699 名前:デフォルトの名無しさん mailto:sage [2010/05/04(火) 19:08:56 ]
>>697
志村、エンディアン!エンディアン!

700 名前:デフォルトの名無しさん [2010/05/04(火) 19:11:45 ]
fgets関数について質問です。
この関数はEOFに達するとNULLを返すとのことですが、

FILE *fp;
char str[8];

while(fgets(str, 8, fp)){
printf("%s",str);
}

とやってファイルの内容を出力していった場合、最後はEOFが来てNULLが
返るので、最後のprintf1回が実行されないような気がするのですが、
そうではないようです・・・。それとも1文字ずつ判定してそのたびにprintfを
実行しているのでしょうか?


701 名前:デフォルトの名無しさん mailto:sage [2010/05/04(火) 19:16:50 ]
fgets内部の実装にもよるが、普通はバッファに一文字でも
書き込んだ状況でEOFが来てもフラグを設定するだけで
NULLは返さず次回の同じFILE*にたいする呼び出し時に
NULLを返す設計が取られるんじゃないかと...
(標準仕様でもそれが期待されているようだし)

702 名前:デフォルトの名無しさん mailto:sage [2010/05/04(火) 19:21:52 ]
>>700
ファイルの終端に達している状態でfgets()を呼ぶとEOFを返す



703 名前:デフォルトの名無しさん mailto:sage [2010/05/04(火) 19:22:50 ]
>>700
意味を勘違いしてる
最後の文字までとりこむfgetsではNULLを返さず
その次のfgetsでNULLを返すの

704 名前:デフォルトの名無しさん mailto:sage [2010/05/04(火) 19:25:39 ]
>>701 >>702 >>703
ありがとうございます!
なるほど理解できました。

705 名前:デフォルトの名無しさん mailto:sage [2010/05/04(火) 22:42:34 ]

質問です。

#include <stdio.h>
#include <string.h>
void main(void)
{
char name[5];
int len;
do{
printf("お名前を入力して下さい\t");
scanf("%s",name);
len = strlen(name);
} while(len>5);
printf("\nあなたのお名前は %s です。\n", name);

}

これでname[5]の配列に30文字くらい打ち込んで終了させると、
OSのほうから終了時にエラーが出されます。

メモリに打ち込んだ文字が残ってるからだと聞いたことがあるのですが、
これらの記録を消去して、エラーを出さないようにするにはどういうことをすればよいのでしょうか。

706 名前:デフォルトの名無しさん mailto:sage [2010/05/04(火) 22:50:24 ]
最初からname[200]くらいとっておく。
200以上入力しようとするやつは知らん

707 名前:デフォルトの名無しさん mailto:sage [2010/05/04(火) 22:56:16 ]
それか可変長だな・・・。

708 名前:デフォルトの名無しさん mailto:sage [2010/05/04(火) 23:14:08 ]
>>705
エラーがでるのはスタックに積んであるリターンアドレスをぶっこわしてるから

scanf("%4s",name);

とかやって、そもそも配列外にアクセスしないことが大事

709 名前:デフォルトの名無しさん mailto:sage [2010/05/06(木) 12:16:27 ]
>>706
その考えは身を滅ぼす。gets()を使うくらい、下策。
どうせscanf()を使っているのだから>708が妥当。

710 名前:デフォルトの名無しさん mailto:sage [2010/05/06(木) 17:44:36 ]
会社の研修の問題でもscanfは使わずにコーディングしなさい、だったぞ。

711 名前:デフォルトの名無しさん mailto:sage [2010/05/06(木) 17:51:47 ]
>>710
だからなんだってんだよ・・・・・・・・・・・・・

712 名前:デフォルトの名無しさん mailto:sage [2010/05/06(木) 19:16:58 ]
>>710
お前は何を言っているんだ



713 名前:デフォルトの名無しさん mailto:sage [2010/05/06(木) 19:21:55 ]
         /  ( ●)(●) |  

714 名前:デフォルトの名無しさん mailto:sage [2010/05/06(木) 19:25:49 ]
scanf は使わないのが常識だよ

715 名前:デフォルトの名無しさん mailto:sage [2010/05/06(木) 19:28:23 ]
printfも使わないのが常識

716 名前:デフォルトの名無しさん mailto:sage [2010/05/06(木) 19:31:22 ]
>>715
携帯開発部隊の方ですか?

717 名前:デフォルトの名無しさん mailto:sage [2010/05/06(木) 19:31:35 ]
scanf 使いたいときは sscanf を使うのが鉄則

718 名前:705 mailto:sage [2010/05/06(木) 21:19:16 ]

バグ取れました。
次からはsscanfにすればいいのですね、ありがとうございました。

719 名前:デフォルトの名無しさん mailto:sage [2010/05/06(木) 22:04:51 ]
>>715
printfの戻り値を毎回確認してからしゃべれ、クソが

720 名前:デフォルトの名無しさん mailto:sage [2010/05/07(金) 11:07:13 ]
>>719
なにも考えずにつかっていたが、printfって戻り値があったのかw

721 名前:デフォルトの名無しさん mailto:sage [2010/05/07(金) 11:48:44 ]
そりゃ関数だし

722 名前:デフォルトの名無しさん mailto:sage [2010/05/07(金) 11:51:02 ]
voidだとおもってたわ。



723 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 00:42:00 ]
質問します。

#include <stdio.h>
#include <stdlib.h>

char *input(void){
int i; char aaa[8]; int count =0; char *bb="";
printf("番号入力する");
scanf("%07s",aaa);
fflush(stdin);
while (aaa[count]){
count++;
}
for (i=0;i<count;i++){
*(bb+i)=aaa[i];
}
return(bb);
}
int main (void){
int i; char *p;
i=atoi(input()); printf("%d\n",i);
p=input(); printf("%s\n",p);
return(0);
}

これで実行してみると、printf("%s\n",p);で表示される文字の5桁目だけ、数字が入力時から+1された状態になります。
何故このようなことが起きるのでしょうか。
正しい表示にするにはどうすればよいのでしょうか?

724 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 01:17:34 ]
わぁお、char *bb="";*(bb+i)=aaa[i];
とんでもないことしてくれてるな

725 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 01:20:10 ]
スーパースマートコーディング

726 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 01:21:04 ]
それ以前に変数名を何とかしろよw

727 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 01:44:32 ]
>>723
何をしたいプログラムなのかわからないが、差し当たりの問題点を指摘する。

char *bb=""; は、コンパイラによっては書き込み不可領域に配置される場合があり、
実行時に落ちる気場合がある。

また、"" のみで初期化した場合、確保される領域は 2 バイトであるため、バッファ
オーバーフローを起こす可能性がある。

これらを防ぐには、malloc() でメモリ領域を動的に確保するか、main() 側でバッファ
を用意して input() に渡し、そこに入力結果を書き込むようにする。

なお、malloc() を使用する場合は必ず呼び出し側 (こごては main()) で戻り値を
記憶し、入力結果が不要になった時点で free() すべき。

728 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 02:52:30 ]
その他の指摘。
・fflush(stdin)は環境依存なので避けた方がいい。
・数値入力用関数を作る積もりなら戻り値は整数の方が使い易くないか?
・scanf()の書式指定で'0'なんてあったか? printf()系の書式指定とは互換性がないと思った方がいい。
・returnは関数じゃないから括弧はつけない方がいい。まぁ、どうしても括弧つけたいなら止めないが。
・ポインタに対する単項の*演算子は厳格なコーディング規約では禁止される。意味的に等価なbb[i]を使うべき。
・演習目的なら止めないが、文字列のコピーは専用の標準関数を使うべき。

729 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 03:30:52 ]
>>728
えっ
ってのが二つ三つ……

730 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 03:34:22 ]
>>729
kwsk

731 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 04:18:26 ]
えっ
ってのが全部なんだが……

>・fflush(stdin)
意図が分からないので書くべきコードでは無い

>・数値入力用関数
はてな

>・scanf()の書式指定で'0'なんてあったか?
あるといえばある

>書式指定とは互換性がない
何を今さら

>・returnは関数じゃない
何を今さら

>・ポインタに対する単項の*演算子は厳格なコーディング規約では禁止される
大変なところに迷い込んでしまいましたね、読みやすさを重視して時には間接参照しましょう
スワップ関数はマクロですか、memcpy()ですか、汎用ポインタですか

>文字列のコピーは専用の標準関数を使うべき
文字列のコピーをしようとしたわけでは無いかもしれない

といってみるテスト

732 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 04:27:54 ]
>>731
何か勘違いしているようだから一言。
>>・ポインタに対する単項の*演算子は厳格なコーディング規約では禁止される
これは文字通り、*(p+i)と書かずにp[i]と書けということ。
厳格なコーディング規約ではこのほか、ポインタ演算も禁止される場合がある。

そうそう、scanf()の書式指定では'0'は特別な意味を持たないようだね。
単純に幅指定の一部と見做されるのかな。この辺りは仕様を読み直さないとなんとも言えない。

その他は趣旨が不明なので割愛。



733 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 09:28:17 ]
>723

実行するとSegmentation faltでこけるよ。
色々おかしいところがありすぎて、何がしたいのかよくわかりません。

入力文字列を数値に変換したいように見えるが、atoi使ってイイなら
文字列をそのままつっこめばいいし、scanf使ってイイなら%d使えよ
という気がする。

ま、一番の問題は>724の指摘通り;
*(bb+i)=aaa[i];
だね。
bbは書き換え可能な有効な領域を指していない。

734 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 09:40:37 ]
>732

「厳格なコーディング規約」ってのは何?

いずれにしても
・ポインタに対する単項の*演算子禁止
・ポインタ演算も禁止
っていうコーディング規約は賛同できない。

>これは文字通り、*(p+i)と書かずにp[i]と書けということ。
何が文字通りなのかわからんが、p[0]ではなく
*pと書くべきケースは、少なからずありますよ。

>ポインタ演算も禁止される場合がある。
揚げ足とるようですまないが、文法を厳格に解釈すれば、
p[i]は*(p + i)のシンタックスシュガーでしか無いので、これも禁止されるように
読めてしまう。こうなるとまともなコーディングは無理。

「厳格なコーディング規約」というからには、しょうもないつっこみを
受けないような、「厳格な」表現を使ってください。

735 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 09:42:36 ]
>>734
知識不足は恥じゃないけどねぇ。
今出掛けるんで、あとで資料を提示するよ。

736 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 10:02:06 ]
メモリ領域を確保したら動くようになりました。
ご指摘のとおり、数値文字のみを文字列型で入力させて
その文字列をメインで受け取る入力用関数を作れという演習目的の課題でした。
質問の仕方が悪くて混乱させてしまい、すみません。

ご指摘ありがとうございました。


737 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 10:12:45 ]
宿題は宿題スレへ

738 名前:デフォルトの名無しさん [2010/05/08(土) 12:43:57 ]
読み込むテキストファイルには*.cと書いてあるのですが、
(仮引数で拾った文字列).cに置換する方法をご教授願えないでしょうか。
以下がソースです。
色々突っ込みどころがあると思いますが宜しくお願いします

#define LEN_MAX 256
int FileRewrite(char *proj_name)
{
FILE *fp;
char *search_p;
char replace_p;
char line_buff[LEN_MAX];
char tar_buff[LEN_MAX];
char rep_buff[LEN_MAX];
char source_name[LEN_MAX];

sprintf(source_name, "./%s/Source/%s.c", proj_name, proj_name);
if ((fp = fopen(source_name, "r+")) == NULL){
fprintf(stderr, "file open error...¥nexit status(-100)¥n");
exit(EXIT_FAILURE);
}
strcpy(tar_buff, "*.c");
while (fgets(line_buff, LEN_MAX, fp) != NULL) {
search_p = strstr(line_buff, tar_buff);
if (search_p != NULL) {
sprintf(rep_buff, "// %s.c¥n", proj_name);
rtn = fputs(rep_buff, search_p);
}
}
fclose(fp);
return (0);
}

739 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 12:57:08 ]
>>738
ソースファイル内の *.c という文字列を全て置換するの?
ソースファイルのコメント中の *.c という文字列を全て置換するの?

740 名前:デフォルトの名無しさん [2010/05/08(土) 13:02:17 ]
>>739
ソースファイルのコメント中の *.c という文字列です。
紛らわしくて申し訳ないです。

*.cという文字列は読み込みファイルの中に1つしかないので全てでもアリだと思います。

741 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 15:16:52 ]
>>734
ほい、一例を。
ttp://sec.ipa.go.jp/reports/20050523/coding_guide.pdf
こいつの14ページ目辺りにポインタ演算について書かれているよ。
但しこいつは、逆参照自体はNGとはしていないけれど。
まぁ少なくとも、糖衣構文を理由に双方を適合とはしないということは判ると思う。

742 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 15:29:10 ]
>>740
Cでやるよりsedやawkでやった方が楽な気がするけど。
sed -e 's/\*\.c/proj.c/' source > destination
該当ファイルを検索する辺りから含めてシェルスクリプトで書けば管理も楽だろうし。

Cでやりたいなら、以下に注意。
--
・読み込みバッファと書き出しバッファの共有は無茶
仮令"r+"でオープンしても、読み込みと書き出しは混在できない。
1行読んだら読む前の場所まで巻き戻してから書けば書けなくはないが、
行の長さが長くなるので次の行(の先頭)を潰してしまう。
あれこれ気を遣うくらいなら、一旦別のファイルに書いた方がいい。
・「*.c」が含まれる行は本当にそのコメント形式だけなのか
例えば「// *.c (ここに重要なコメント)」のようになっていたら、
そのコメントを潰してしまうことになる。
そこに気を遣うくらいなら、「*.c」を置換するに留めるべき。
尚、置換処理自体はsprintf()で%*.*sを駆使すれば数行で書ける。



743 名前:デフォルトの名無しさん [2010/05/08(土) 15:29:43 ]
#include<stdio.h>
int main(void){printf("%[d]"[2+3-1])}
の計算cygwinでやったんですが、でてきません。
どこが間違ってるでしょう?
一〇進の計算です。4とでてきません
基礎すぎてすいません・・・

744 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 15:34:12 ]
>>743
・コンパイルエラーが出る場合はエラーメッセージを貼りましょう。
・何か参考にした資料があるなら明記しましょう。

まぁ、突っ込みどころは山ほどあるけど正解を以下に。
--
#include <stdio.h>
int main()
{
printf("%d\n", 2 + 3 - 1);
return 0;
}
--
尚、空白・改行は適宜変更してもいいが、記号類は省略も追加もしないこと。

745 名前:デフォルトの名無しさん [2010/05/08(土) 15:43:40 ]
>>744
レスありがとうございます。
ですが
それでやってみたところ
chmod:missing operand after `755'
Try `chmod--help'' for more inormation.c
とでてきたんですが??
755ってなんですか?ずっと755がでるんですが

746 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 15:52:35 ]
>>741
「ポインタに対する単項の*演算子禁止」なんて規約が存在する、
というのは嘘でしたってことでいいのね?

747 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 15:54:31 ]
>>745
コマンドラインパラメータの不足
C言語関係なし
コンパイル方法(打ち込む文字)が間違ってる

748 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 15:56:26 ]
>>745 いったい何を「やってみた」んだ?

749 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 15:59:58 ]
>>745
エラーメッセージを貼るときはきちんと貼りましょう。
また、自分が何をやったらそうなったのか、必要ならコマンドラインのコピーも交えて説明しましょう。
まぁ、最早Cの問題じゃないことは>747の言う通り。
このまま続けたいならエスパースレへ。

750 名前:デフォルトの名無しさん [2010/05/08(土) 16:00:40 ]
やってみたとは、プログラムの実行です。
gcc(ファイル名>>744のソース)をするとerrorがでました。
コンパイルエラーというのはプログラムの中身にエラーがあるとき
出るのですよね?

751 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 16:02:28 ]
chmodできないのはコンパイラか。
取り敢えず、コマンドラインを貼れないならソースファイル名を晒してみようか。

752 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 16:23:32 ]
厳密に言うとコンパイラ本体じゃなくてコンパイラとリンカを呼び出すスクリプトがエラーを出してる
missing operandだからソースファイル名がちゃんと入力されていないか、
コンパイルエラーでオブジェクトが生成されなくてリンカの手前でエラーが出てるかだと思う



753 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 16:47:51 ]
>>750
コンソールを全部引用しろよ
お前クラスの素人の場合、普通の人が想像もしないことを
やってるから、抜粋すると解決しない

だいたい勝手にchmodが動くわけないし、誰かの作ったMakefileを
流用してるとかで、どっかで起動してるんじゃねーの

754 名前:734 mailto:sage [2010/05/08(土) 18:37:34 ]
>732 >741

参照資料を見たけどさ、
「ポインタへの整数の加減算は使用せず、確保した領域への参照・代入は[]を用いる
配列形式で行う。」
としか書かれていないよ。
ポインタ演算禁止とは書かれておらず、丁寧に
「ポインタの演算を行う場合には、ポインタの指す範囲に気を付ける。」
と書いてある。

技術用語には「厳格な」定義があるので、勝手にねじ曲げないように。
>728で挙げている、あなたの感覚はおおむね間違っていないが、
理由付けからは、根本的な理解の甘さがかいま見える。
そのせいで、色々つっこまれている。

今回引っかかった表現は
×「ポインタに対する単項の*演算子は厳格なコーディング規約では禁止される。」
×「ポインタ演算も禁止される場合がある」


755 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 18:45:08 ]
>750

すでにつっこみが入っているが、何をやっているのかさっぱりわからない。

>やってみたとは、プログラムの実行です。
>gcc(ファイル名>>744のソース)をするとerrorがでました。

2行目でやっていることはコンパイルであって、プログラムの実行では無いぞ。
コンパイル中にchmodが勝手に走るなんてことは無いと思うけど。

>コンパイルエラーというのはプログラムの中身にエラーがあるとき
>出るのですよね?
chmod:missing operand after `755'
Try `chmod--help'' for more inormation.c
これはコンパイルエラーではない。chmodのエラーで、引数が無い
という意味。なんでchmodが出てくるのか、想像できない。

コンソールをそのままコピペして貼り付けてみたら?
もっともCの問題ではないと思えるが。

756 名前:デフォルトの名無しさん [2010/05/08(土) 19:42:10 ]
>>755
すまん、弟に聞いたらできたよ。
gcc OOO.c

a.exe

で実行でできた、あなたが間違ってるとかじゃなかったから
ごめん。
また来るよ。


757 名前:デフォルトの名無しさん [2010/05/08(土) 19:44:13 ]
今人いるかな?質問させていただきます
char型の'1'をint型の1にしたいんですけど、テストしたら49になってしまう
どうやったらいいです?

758 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 19:45:17 ]
48を引きます。

759 名前:デフォルトの名無しさん [2010/05/08(土) 19:47:08 ]
>>758
今VBでやってるんだが、
ほかのコンパイルでもそれで結果同じになるならいいんだがどうなんです?

760 名前:デフォルトの名無しさん [2010/05/08(土) 19:47:49 ]
コンパイラーでした間違えた

761 名前:>>757 [2010/05/08(土) 19:57:04 ]
ちなみにキャスト代入でやった
while文で、ひとつずつchar型の数字をint型にしたいんだがどうすればいいんだorz

762 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 20:07:34 ]
ここはC言語スレです。
VBの質問ならVBスレへどうぞ。



763 名前:デフォルトの名無しさん [2010/05/08(土) 20:08:23 ]
VBでC言語やってるんだ
誤解させてすまぬ

764 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 20:20:39 ]
>>761を読む限りではこんな感じ

int i, n[ 5 ];
char s[] = "12345";
for( i = 0; i < 5; ++i )
n[ i ] = s[ i ] - '0';

765 名前:デフォルトの名無しさん [2010/05/08(土) 20:22:44 ]
>>764
ありがとうございます!
あとでやってみます

766 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 20:25:44 ]
>>761
char型の数字をint型に
int intsuji = charsuji - 48;

while文で、ひとつずつひとつずつ
何をしたいの?

767 名前:デフォルトの名無しさん [2010/05/08(土) 20:29:30 ]
>>766
char型に入ってる数字を一文字ずつint型にいれるっていうことを
配列でやってるんでなんか簡単にまとめられないものかとおもって;

768 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 21:05:44 ]
>>767
やりたいことを具体的に書いた方がいいよ。

769 名前:デフォルトの名無しさん [2010/05/08(土) 21:34:22 ]
>>768
そうですね、あんまつたわらないしよくなかったとおもいます
こんどからそうします;
>>764
そのやり方でできました。ありがとうございます。

770 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 22:39:41 ]
#include <stdio.h>

int main(void)
{
printf( "%d - %X + %o = %d\n", 398, 1FB , 327 ,398-1FB+37 );

return 0;
}
これどこが間違ってますか?cygwinでこれを実行したら前のプログラミングがでました。
間違えたプログラミングだと実行したら前やった実行がそのまま出るっぽいです。



771 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 22:41:39 ]
>>770
1FB じゃなくて 0x1FB じゃないの?

772 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 22:47:54 ]
レス早い、本当助かる。
なぜ0xをつけるんですか??!??!

あと質問ですが何故int main()っているんですか?
printfだけじゃだめなんですか?ただの数値計算なんですが・・・




773 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 22:48:45 ]
すげぇww
できたwww0xつけたらできた。涙出てきたわ。ほんまありがとう
また来るよ。

774 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 22:50:01 ]
二度と来るな

775 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 23:23:23 ]
ひでぇ・・・w
1FBって16進だろ
16進ってことを表すのが0x

c言語はint main()っていれなきゃいけない
これは関数だからc言語は関数型言語

776 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 23:24:37 ]
>>775
手続き型言語じゃないの

777 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 23:42:42 ]
最初よくわからなかったものが
わかるとなんでわからなかったのかわからなくなる

778 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 23:51:21 ]
>>775
えっ

779 名前:デフォルトの名無しさん mailto:sage [2010/05/09(日) 00:09:04 ]
18禁ゲームからエロシーン削除して家庭用に移植というくだらない事、最初にやったアホがいると聞いて

780 名前:デフォルトの名無しさん mailto:sage [2010/05/09(日) 00:10:49 ]
C言語では、プログラムがどこから始まるか、ちゃんと書かなきゃいけないルール。それがmain()
C言語を発明した人がそう決めた。

ほかの言語だとファイルの先頭からいきなり始まるやつもあるし、そういうわけわかんないルールを
覚えるのも含めてプログラミングの勉強だから。

781 名前:デフォルトの名無しさん mailto:sage [2010/05/09(日) 00:50:35 ]
JavaやC#よりはマシだな

782 名前:デフォルトの名無しさん [2010/05/09(日) 07:49:11 ]
entry は結局日の目を見なかったね



783 名前:デフォルトの名無しさん mailto:sage [2010/05/09(日) 12:11:22 ]
mainってただの慣習じゃないの

784 名前:デフォルトの名無しさん mailto:sage [2010/05/09(日) 12:21:32 ]
>>783 ちがうよ。規格で定められている関数だよ。

785 名前:デフォルトの名無しさん mailto:sage [2010/05/09(日) 12:38:36 ]
え?そうなの?
じゃぁWinMain使うときはどういう扱いなの?

786 名前:デフォルトの名無しさん mailto:sage [2010/05/09(日) 12:43:57 ]
単なるコンパイラの独自拡張

787 名前:デフォルトの名無しさん [2010/05/09(日) 12:56:59 ]
>>785
規格ではフリースタンディング環境に分類される
OS はないことになっているので、あくまで利用者定義ライブラリという位置づけ

788 名前:デフォルトの名無しさん mailto:sage [2010/05/09(日) 13:00:50 ]
>>786,787
ありがとうございました


789 名前:デフォルトの名無しさん mailto:sage [2010/05/09(日) 15:54:38 ]
質問します。
#include <iostream>
using namespace std;
static char *plus(char *fp_c, char *fp_c2);

int main()
{ char buf[]="ab,cde,fghi",buf2[100];
char *fp_c,*fp_c2;

fp_c=buf;
fp_c2=buf;

fp_c2=fp_c2+2;
*fp_c2=0x00;
strcpy(buf2,fp_c);
cout << buf2 << '\n';

fp_c,fp_c2= plus(fp_c,fp_c2);

fp_c2=fp_c2+3;
*fp_c2=0x00;
strcpy(buf2,fp_c);
cout << buf2 << '\n';
return 0;}

char *plus(char *fp_c, char *fp_c2){
return fp_c2++; //1進める
return fp_c=fp_c2;}
関数plusの中でポインタを1進める物を作ろうとしたのですが
実行すると、関数の中に入ってないのか、先頭のポインタに戻っているのか
上手くいきません。上手く関数を使いポインタを進めるにはどうしたらよいのでしょう?

790 名前:デフォルトの名無しさん mailto:sage [2010/05/09(日) 16:33:21 ]
警告、いや、エラーも出ると思うが、また、お笑いコードを書くなよ
っていうかスレチ

791 名前:デフォルトの名無しさん [2010/05/09(日) 21:45:19 ]
皆さんの知恵をお貸しください

今度学校の授業でモジュラス10ウェイト3のC言語のソースを書くことになったのですが、どのように入力した
数値を使ってチェックコードを導くのか苦戦しています。

どのような方法で考えればいいか教えてください。

792 名前:デフォルトの名無しさん mailto:sage [2010/05/09(日) 21:46:15 ]
>>791 宿題スレ池。



793 名前:デフォルトの名無しさん mailto:sage [2010/05/09(日) 22:31:02 ]
日本語で

794 名前:デフォルトの名無しさん [2010/05/09(日) 22:36:40 ]
>>791
scanfで数値を取得して、後は粛々と計算で終了では?
何を苦戦しているのか全くわからない。

795 名前:デフォルトの名無しさん mailto:sage [2010/05/09(日) 23:24:40 ]
質問です。
すでに入力されている文字列"12345678"があるとして、 "1234"だけを表示させて後は表示させないにはどうすればよいのでしょうか。
%cで一つずつ表示しか思いつかなかったのですが、よい方法はありますか?

796 名前:デフォルトの名無しさん mailto:sage [2010/05/09(日) 23:34:49 ]
>>795
#include<stdio.h>

int main(void)
{
char buf[256]="12345678";

printf("%.4s", buf);
return 0;
}

797 名前:デフォルトの名無しさん [2010/05/09(日) 23:34:54 ]
printf("%.4s", "12345678");

798 名前:デフォルトの名無しさん mailto:sage [2010/05/09(日) 23:35:08 ]
5の部分を\0に書き換える

799 名前:795 mailto:sage [2010/05/10(月) 01:51:59 ]
素早い回答有り難う御座いました。

800 名前:デフォルトの名無しさん mailto:sage [2010/05/10(月) 02:29:34 ]
Cの勉強初めて数日の者ですが質問です

#include<stdio.h>

main(){
char a,b;
scanf("%c",&a);
printf("%c",a);
scanf("%c",&b);
printf("%c",b);

return 0;
}

これを実効すると
一つ目の文字を入力した時点で終了してしまうのですが何故でしょうか?

801 名前:デフォルトの名無しさん mailto:sage [2010/05/10(月) 02:35:40 ]
コンピューターの機嫌が悪い

802 名前:デフォルトの名無しさん mailto:sage [2010/05/10(月) 02:44:29 ]
>>800
例えば、プログラムを実行して
1[改行]
と入力した場合、入力内容は
'1\n'
となる。
よって、2つめのscanf()が実行された時点で、未読込の文字'\n'があるので、
2つめのscanf()は、更なる入力を待たず b に '\n' を代入してすぐ返る。
よって一つ目の文字を入力した時点で終了してしまうように見える。



803 名前:デフォルトの名無しさん mailto:sage [2010/05/10(月) 02:48:42 ]
>>802
なるほど
納得しました
ありがとうございました

804 名前:795 [2010/05/10(月) 02:57:13 ]
お早い回答ありがとうございました。

805 名前:デフォルトの名無しさん mailto:sage [2010/05/10(月) 12:01:15 ]
getchar()やscanf()のような文字単位処理関数と端末エミュレータの一行編集とが相性悪いんだよな。
その点だけはGUIの方が初心者には判り易いと思うんだが。
# 尤も、そこに辿り着くまでの長い道程がGUIの最大の欠点なわけで……

入門書ではscanf()やgetchar()を使わず、全部コマンドラインオプションでやる方がシンプルに説明できるんじゃないか?
# そうすると、今度はコマンドインタプリタの余計なお世話を回避することを学ばないとならなくはなるけれど。

806 名前:デフォルトの名無しさん mailto:sage [2010/05/10(月) 14:07:23 ]
>>805
コマンドラインオプション?
コマンドインタプリタ?

意味が通じてない。えらそうなこという前に正しい用語ぐらい覚えておけ。

807 名前:デフォルトの名無しさん mailto:sage [2010/05/10(月) 14:47:07 ]
>>806
コマンドライン引き数、コマンドラインインタプリタと言えばご満足?

808 名前:デフォルトの名無しさん mailto:sage [2010/05/10(月) 14:48:53 ]
つーか、>805が偉そうだと思えるほど、>806は自信の知識の足りなさを実感しているのだろうな。

809 名前:デフォルトの名無しさん mailto:sage [2010/05/10(月) 15:01:20 ]
えらそうな人は実際えらい

810 名前:デフォルトの名無しさん mailto:sage [2010/05/10(月) 15:02:27 ]
原始UIと入出力はプログラミングの基本だろ
それ無しでどうやって入門するんだよ

811 名前:デフォルトの名無しさん mailto:sage [2010/05/10(月) 15:24:39 ]
scanfなんて最初の勉強以外で使ったこと無いな

812 名前:デフォルトの名無しさん mailto:sage [2010/05/10(月) 17:09:08 ]
>>806 も少しうざいけど、
>>805 の発言こそ「えっ」なんだが。



813 名前:JaneDoeの抽出って便利だな mailto:sage [2010/05/10(月) 17:15:50 ]
なんで>729とか>731とか>778とか>812って、その「えっ」の内容を書かないんだろうな。
余程自信がないんだろうか。

814 名前:デフォルトの名無しさん mailto:sage [2010/05/10(月) 17:40:16 ]
>>813
書かなくても普通にわかるだろwwww
お前が書いた本人なの?添削して欲しいの?



815 名前:デフォルトの名無しさん mailto:sage [2010/05/10(月) 18:05:54 ]
>>805
まじで何が言いたいのかさっぱりわからん。

>>807
それならますます意味が通じなくなる。
国語の成績が最低だったことだけはわかる。

816 名前:デフォルトの名無しさん mailto:sage [2010/05/10(月) 18:26:16 ]
おれが訳してやろう

getchar()やscanf()ってコマンドラインから入力とかに素直に使えないよな
だから初心者はGUIのほうがいいんだろうけど、GUIはやりたいことやるまでのおまじないの解説とかが多いしな

いっそコマンドラインのやつはパラメータを全部引数にしちゃって渡すとかが入門にはいいかな
でも、それだと引数の解釈のところがめんどくなるだけか

みたいな話だと思う、要は、えらそうにアレにもこれにも文句つけてるけど特に建設的な意見はない人だ
国語の成績はよかったと思うよ、大した事言ってないのにえらそうにするやりかたとかさ
でも、人に説明とかは苦手(で、通じなくて相手を馬鹿にして非難)な人だろうな

817 名前:デフォルトの名無しさん mailto:sage [2010/05/10(月) 18:49:06 ]
>>816
翻訳ありがとー
彼の言ってる内容はわかったが、その内容に意味がないこともよくわかったわw

818 名前:デフォルトの名無しさん mailto:sage [2010/05/10(月) 18:50:43 ]
研修でscanf()の使用を禁じられていたので。

819 名前:デフォルトの名無しさん mailto:sage [2010/05/10(月) 19:08:53 ]
同じ言葉を2回続けるとニュアンスが正反対になるよ!ふしぎ!


はい
はいはい

820 名前:デフォルトの名無しさん mailto:sage [2010/05/10(月) 19:19:05 ]
>>815
それはお前が低脳だからだよ
高脳なら低脳の書いたよくわからん文でも理解できるが、
低脳はさっぱりわからんで終わり。
俺も低脳だから>>805はよく分らんがな
>>817
周りは普通脳以上は、やれやれ低脳にはこんなことまでしてやらないと理解できないのか
低脳は大変だな、これじゃ仕事でも手間かかるなだろな。

821 名前:デフォルトの名無しさん mailto:sage [2010/05/10(月) 19:38:52 ]
>>805 の言いたいことは解るけど、
「相性が悪い」という点に同意できないんだよ。

822 名前:デフォルトの名無しさん mailto:sage [2010/05/10(月) 19:50:03 ]
>>821
それはお前が低脳だからだよ



823 名前:デフォルトの名無しさん mailto:sage [2010/05/10(月) 23:12:00 ]
仕方ない。俺が >>805 を翻訳してやろう
-- 
 >>getchar()やscanf()のような文字単位処理関数と端末エミュレータの一行編集とが相性悪いんだよな。 

 getchar()とかscanf()のような標準入力からデータを受け取る関数は、
 echo offにしてないと出力と入力のechoが混ざって相性悪いんだよな。

 >>その点だけはGUIの方が初心者には判り易いと思うんだが。 
 >># 尤も、そこに辿り着くまでの長い道程がGUIの最大の欠点なわけで…… 

 その点GUIはそういうToLoveるが無いので初心者も安心。
 もっともGUIアプリを作るなんて、初心者には果てしなき道のりなわけで…… 

824 名前:デフォルトの名無しさん mailto:sage [2010/05/10(月) 23:41:00 ]
getchar()はいいだろ。
素直にストリームの動作のイメージを反映してるし。


825 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 00:05:25 ]
問題は、行内編集ができるから一文字ずつ入力するのに向かないってことでしょ。
getchar()で一文字入力しようとして「なぜか先に進む」類の罠に嵌まる質問が後を絶たないからね。

826 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 01:35:25 ]
だから、単におまえの望む動作になってないってだけで全然相性は悪くないだろ。
ついでに言うと、1行編集は端末エミュレーターの機能じゃねえよ。
無知をさらしてるってことに早く気付けよ。

827 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 02:08:52 ]
ファイルを分割するプログラムで疑問に思った点があります
質問させていただきます

fseek(fp, 0, SEEK_END)
ftell(fp)

としてサイズを取得した場合
今の自分の目的としているものが 195768 バイトのファイルなので
値としても 195768 とでてきます
しかし、

fseek(fp, 0, SEEK_SET)
ftell(fp)

として見てみると、この値は 0 とでてきます
ファイルポインタを先頭に置いているときは、
ftellの結果は 1 と出てくるのが妥当ではないかと感じるのですが
(fseek(fp, 195768, SEEK_SET) と
 fseek(fp, 0, SEEK_END)
が一致するなら、データが 195769 個あるように思うため)
先頭、あるいは末尾がopenしたファイルのデータとは異なる
特殊なものになっているのでしょうか?

分かりにくいかと思いますが、上手く説明できず申し訳ないです

828 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 02:12:16 ]
>>827 fseek(fp, 0, SEEK_END) のあとに fgetc(fp) してデータが取れるかな?

829 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 02:13:34 ]
>>827
0バイトのファイルで考えてみて

830 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 02:14:18 ]
>>827
char file[195768] に対する添え字と同じ。
fseek(fp, 0, SEEK_END) は &file[195768] ってこと。

831 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 02:15:19 ]
うほ、なにやら沢山ありがとうございます
付けてもらったレスみて考えてみます
感謝

832 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 02:28:37 ]
みなさまのおかげで修正したプログラムも無事動きました
ありがとうございます



833 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 02:39:06 ]
>>827
> ファイルポインタを先頭に置いているときは、
> ftellの結果は 1 と出てくるのが妥当ではないかと感じるのですが

ファイルアドレスは 0 から始まるので、ファイルポインタが先頭、つまり
0 バイト目にある時は ftell() の結果は 0 と出るのが妥当です。
ファイルサイズ 0 の場合に fseek(fp, 0, SEEK_END) した時、ftell() が 1 を
返すのは妥当ではないと感じませんか?
ファイルサイズ 1 の場合に fseek(fp, 0, SEEK_END) した時、ftell() が 2 を
返すのは妥当ではないと感じませんか?

> fseek(fp, 195768, SEEK_SET) と
>  fseek(fp, 0, SEEK_END)
> が一致するなら、データが 195769 個あるように思うため)

いきなり 195768 のように大きなアドレスを扱うから混乱します。
まずファイルサイズ 0 の場合を考えてみてください。
fseek(fp, 0, SEEK_SET) ないし fseek(fp, 0, SEEK_END) をしてもファイル
ポインタは先頭、つまり 0 バイト目を指したままですが、そこに 1 個目の
データが存在すると思いますか?
いいえ、存在しません。

同様に、ファイルサイズ 195768 の場合、fseek(fp, 195768, SEEK_SET)
ないし fseek(fp, 0, SEEK_END) をしてもファイルポインタは 195768 バイト
目を指しますが、そこに 195769 個目のデータが存在すると思いますか?
ファイルサイズ 195768 なのに、最後の 1 バイトのデータはどこから来る
のでしょう?
いいえ、どこからも来ません。データは 195768 個しかありません。

ファイルポインタが指している場所に必ずしもデータが存在するとは限り
ません。

834 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 03:45:02 ]
コンソールに計算式(例:34+4)を入力して演算結果を出力するプログラムを作っています。
作ってみたのですが、足し算しかうまくいきません。
どこが違ってるのかよくわからないのでアドバイスください。

kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10592.c


835 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 04:07:50 ]
>>834
if(p!=NULL){
b = atoi(p + 1);
printf("%d + %d = %d\n", a,b,a+b);
} else if(q!=NULL) {
c = atoi(q + 1);
printf("%d - %d = %d\n", a,c,a-c);
} else if(r!=NULL){
d = atoi(r + 1);
printf("%d * %d = %d\n", a,d,a*d);
} else if(s!=NULL){
e = atoi(s + 1);
printf("%d / %d = %d\n", a,e,a/e);
}

836 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 04:38:18 ]
なんでb, c, d, eを分けてるの?
ch1, ch2, ch3, ch4は何の意味があるの?

837 名前:デフォルトの名無しさん [2010/05/11(火) 12:15:32 ]
>>834
それ以前に
文字列の初期化なし
入力妥当性チェックなし

838 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 12:29:04 ]
>文字列の初期化なし
ってなんの話?

839 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 12:30:49 ]
空の文字列入れるとか、memsetで埋めるとかしないと
何にも入ってない不定の状態での格納は危険じゃないかと。
あと、ch1〜ch4に入れるときのキャストがなんか気持ち悪い。

840 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 12:37:33 ]
>>839
>何にも入ってない不定の状態での格納は危険じゃないかと。
どんな危険があるのですか?


841 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 13:12:06 ]
0でターミネートし忘れた場合とかぬかすんだろどうせw

842 名前:デフォルトの名無しさん [2010/05/11(火) 14:29:03 ]
至急!!!!

任意個数の整数を標準入力(キーボード)から入力し、
入力された整数の個数
平均値(小数点以下 1 桁まで表示)
最大値
最小値
を標準出力(ディスプレイ)に表示するプログラムがわかりません。




843 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 14:29:52 ]
ただし、9999が入力されたら入力を終了するものとし、9999は入力個数、平均値、最
大値、最小値には含めない。
また、最初に9999が入力された場合には、入力個数=0、平均値=0.0、最大値=0、
最小値=0が出力されるようにする。


844 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 14:37:52 ]
>>842
わかりました!!!!

845 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 14:55:29 ]
>>834
NULLだろうけど変数が多いね。
kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10593.txt
やりたいのはこういうこと?

846 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 15:01:03 ]
>>842
まず、入力がなくなるまでループ
最初の1個目を最大値、最小値とみなす
2個目以降は最大、最小を調べる
合計値に順次足していってループ回数もメモっておく
ループ抜けたら最大値、最小値、平均値を出力しておわり

847 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 15:03:30 ]
小数点一桁目まで出すのなら %.1f だっけ?

848 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 15:04:59 ]
>>846
それができないから聞いてるんですけど・・・

849 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 15:27:07 ]
>>484
なぜ出来ないか詳しく。
制限のためか、それともC言語を書けない為か?

850 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 15:35:03 ]
ここまで書いたけど・・・とソース晒すとか、何がわからないのかを具体的・端的に説明するとかしない奴は
プログラムを自分で書く気はない。
宿題スレへ。

851 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 15:36:27 ]
宿題スレどこ?w

852 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 15:48:34 ]
死ぬがよい



853 名前:デフォルトの名無しさん [2010/05/11(火) 16:44:46 ]
課題で出たんですが
アルファベット1文字と整数型の数値 n を読み込んで,その文字の n 文字後の文字を表示するプログラムを書きなさい
とはどういうことでしょうか?アルファベットとは数値のことですか?全体的に問題の意味が
わからないんですが・・・

854 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 16:53:55 ]
>>853
アルファベット1文字・・・A-Z a-z
整数型の数値n・・・0-99999999...

A + 0 = A
A + 1 = B
A + 2 = C ...

855 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 16:56:56 ]
はぁ?アルファベットはアルファベットだろうが
つかCの話でもなんでもないじゃん

たとえば

a5 なら a から5番目→g
f3なら fから3番目→i
D1なら E ってことだろ

もらった文字に数字足して、zをこえるならAに残ったぶんを足すんじゃね?




856 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 16:59:21 ]
a5 なら a から5番目→f だったwww
zまで行ったらAにもどるのめんどいなら
「そこに文字はないです」って言って再入力させるとか

857 名前:デフォルトの名無しさん [2010/05/11(火) 17:40:08 ]
うん?よくわかりません、アルファベットってのは数字に値するんですか?
どういう数え方ですか?アルファベットにアルファベットを足したら?
このプログラムの方法もよくわかりません。頭悪くてすいません・・・一応
今日も徹夜・・

858 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 17:49:22 ]
>>857
アルファベットの文字コードのことなんだけどね。

char c = 'A';

という構文はわかる?
そして

c = c +1;
putchar(c);

とすると画面には B と表示されるんだけど・・・

859 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 18:03:43 ]
>>857

アスキーコードでググれ
どのアルファベットがどの数字に割り当たってるのかわかるし
順番に並んでるのを見れば理解も早い

860 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 18:08:33 ]
いろいろな操作を行って、例えばABCD\0が入っている文字配列Z[5]を
空にする(宣言直後の状態に戻す)方法はありますか?
例えばループ中で代入しようとするとエラーを吐いてしまいます。

まだかなり初心者だと思いますが、よろしくお願いします。

861 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 18:13:04 ]
>>860
とりあえず、君が書いたコードを貼れよ

あと宣言直後は空でなく、デタラメな文字が入ってるよ。

862 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 18:28:58 ]
>>860
memset( Z, 0x00, sizeof( Z ) );



863 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 18:29:58 ]
>>860
for(i=0;i<=5;i++)としてないかな?
添え字は0から始まるので要素数5の場合は
for(i=0;i<5;i++)として0〜4の範囲を指定せねばいかんよ。

初期化の方法は
Cならmemset
WinAPIならZeroMemory
C++ならstd::fill
使い回さずにその都度宣言した方がいいと思う


864 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 18:31:35 ]
宣言直後に入っている文字列を別の配列にコピーしておいてあとでコピーしなおせばいいんじゃないの?何がしたいのか分からんが。

865 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 18:39:44 ]
>>860
*z = '\0';

866 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 20:21:33 ]
>>865
君は C プログラマには向いてないから
BASIC 等をやったほうが良いんじゃないかな。

867 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 20:57:13 ]
>>866
なんだって

868 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 22:16:02 ]
シューティングゲーム作ってるんですが、int型とdouble型では
どちらのほうが計算速度が速いですか?

869 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 22:17:23 ]
double型。

870 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 22:21:20 ]
>>869
ありがとう!

871 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 22:22:40 ]
んなわけないだろ。

872 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 23:03:44 ]
いやdouble型早いから



873 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 23:16:39 ]
今時のCPUならほとんど変わらない、まぁ、実測が基本
intからdoubleとかdoubleからintへの変換が多くあると急激に遅くなる
がんばって、固定小数にしてもそれほど早くもならなかったので、浮動小数でいいやとなった
これ以上速くしようと思ったらアルゴリズム改良するかGPUに支援してもらうか、はぁ

874 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 23:44:15 ]
VIA の CPU なら整数演算でないと激遅

875 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 23:48:05 ]
浮動小数点型はCPUによって微妙に数値誤差の出方が変わるので
リプレイ機能と相性が悪い聞く事がある
同じIntel系同士でもそうなるのかは俺は知らない

876 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 23:49:50 ]
使う命令を切り替える実装を使うな

877 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 23:56:58 ]
アセンブラでCPUの拡張命令(SSEとか3D Now!!)を叩くしかない。

878 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 00:11:57 ]
WINAPIのwsprintfでは実数が扱えなかったので、
sprintfを使いました。
そこからWINAPIのTextOut等で、ウィンドウに文字を表示したいのですが、
char *型からLPCWSTRへの変換が出来ないのでエラーになります。
何かいい方法ありませんか?



879 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 00:22:21 ]
mbstowcsって言えばいいのかな?

880 名前:デフォルトの名無しさん [2010/05/12(水) 00:41:05 ]
>>858
char型って整数の範囲決まってませんでした?じゃぁnが大きいと
計算できないんじゃ?Aは65ってこと?
プログラムにはアルファベットとnを入力させるように作るのですか?・・
初心者に見せかけて相当理解力が弱いんで優しくしてください・・
まじわからんww

881 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 00:47:53 ]
文字コードってのがあんだよ。
コンピューターは01しか理解できないから文字も01に変換して処理させてるわけ。

882 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 00:54:44 ]
>>878
tchar.hをインクルードして_stprintf使え。
これでcharではなく、Windows APIのTCHARが使える(正確には、ちと違うが)。



883 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 00:55:21 ]
>>878
TextOutA()

884 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 00:56:04 ]
ASCIIコード表を見るといいと思うよ。

885 名前:デフォルトの名無しさん [2010/05/12(水) 00:56:55 ]
>>881
文字コードは01じゃないけどな。

886 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 01:00:07 ]
2進数に直したら全部01だろ馬鹿か

887 名前:デフォルトの名無しさん [2010/05/12(水) 01:00:51 ]
直すからだろw

888 名前:デフォルトの名無しさん [2010/05/12(水) 01:01:49 ]
>>1
山手線符号化したら、全部駅名だろwwアホww

889 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 01:32:15 ]
>>888
もしよろしければどこへの誤爆かおしえていただきたいのですがいかがですかね

890 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 01:41:51 ]
>>882
TCHAR の意味解ってないだろ。

>>884
ASCII とは限らないだろ。

891 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 01:49:13 ]
TCHAR?
ティーチャーって先生って意味ですよね。


892 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 07:40:39 ]
>>880
文字コードの文字のところ一部抜粋。
#include <stdio.h>
int main(void)
{
int i;
for (i=61;i<123;i++)
{
printf("%c(%3d) ",i,i);
if((!(i%10))||(i==122))printf("\n");
}
return 0;
}



893 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 08:03:20 ]
>>882
_stprintfから、swprintfの存在を知り、問題なく実数でも扱えて
処理できました。

ありがとう!

894 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 08:31:06 ]
文字コード云々じゃなくてさ、問題の意味がわからないって質問だろ?
アルファベットにアルファベットを足すとか言ってるし、「整数 n」←このnをアルファベットだと思ってるんじゃないの?
入力されたアルファベットにnというアルファベットを足すってどういう意味って聞いてるんじゃないの?

895 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 08:58:14 ]
初心者質問していい?

896 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 09:02:10 ]
だめ

897 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 09:51:53 ]
>>895
どうぞ。

>>894
>「整数 n」←このnをアルファベットだと思ってるんじゃないの?
その発想はなかったw

898 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 12:11:13 ]
どうも元質問者は VBからの移行なのか variant型 が当然のようで

 変数 a に 文字の '1' を与える
 → 整数演算の時 値として 1 に評価される

という思考から抜け出せないでいるようだ

899 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 13:46:27 ]
PHPとかその辺混乱しまくりw

900 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 15:29:52 ]
いつの話してんだ

901 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 18:57:08 ]
VC++2008を使っています.
画像を入れる配列を3つに増やそうとすると
'System.StackOverflowException' のハンドルされていない例外が ○○.exe で発生しました。
とエラーがでてしまいます.少し調べたところ,unsigned charしすぎて回帰の回数が増えたためなのかと思ったんですが,どうしても配列を3つ以上使いたいのですがあきらめるしかないのでしょうか?
以下エラーの原因と思われるソースの一部です.(main.cpp)
FILE *fp;
unsigned char header[54];
unsigned char screen[400][300][3];//読み込み用
unsigned char screenB[400][300][3];//保存用
unsigned char screenG[400][300][3];//保存用  //ここをコメントアウトしたらエラー消える
//unsigned char screenR[400][300][3];//保存用

/* 画像サイズ */
int yl=400;//y_long //呼び出し履歴によるとここでデバッグが止まる
int xl=300;//x_long

/* ファイルから読む */
fp=fopen("test.bmp","rb"); /* Windowsビットマップ形式 400*300ピクセル,24ビットカラー */
fread(header,1,54,fp); /* ヘッダ(54バイト)を飛ばす */
fread(screen,1,yl*xl*3,fp); /* 残りはデータ(最下行から順に入る) */
//fread(screenB,1,yl*xl*3,fp);
fclose(fp);


902 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 19:01:11 ]
スタックがあふれるならヒープに取ればいいじゃない、ということで、
mallocとか使って動的にメモリを確保するんです。
多分その段階だとポインタになれてないだろうから、がんばれ、とエールを。



903 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 19:05:58 ]
取り敢えず、スタックの割り当てを増やすのも手かと。

904 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 19:09:29 ]
適当にテストするならグローバルにすればよころう。

905 名前:901 mailto:sage [2010/05/12(水) 19:13:58 ]
>>902
ありがとうございます.
もう一度調べなおしてみます.

906 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 20:06:33 ]
>>901
>editbin /stack:1000000
とかやっとけば OK

907 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 20:38:04 ]
>>906
なんでそんなひどいこというの?

908 名前:デフォルトの名無しさん [2010/05/12(水) 21:43:28 ]
>>894
質問したものですが
さすがにそれはないです。このスレでも意見分かれてませんか?
nをたくさんたすとzまでいってまたaに戻るとか。
アルファベトに数値をたすって意味が分からないんですよ。
たとえばAに1000足したら?
Aとはそもそも何か、16進数の10番目のやつか、何ちゃら
規格とかのコードなのか。それが分かりません

909 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 21:50:49 ]
てst

910 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 21:55:19 ]
>>908
> アルファベトに数値をたすって意味が分からないんですよ。
'A' は0x41や65の別表現でしかない。('A'==0x41==65)
全て内部的にはただの数値。
'A'+1==0x42==66=='B'


911 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 21:55:20 ]
アルファベットに数字を足す問題ですが、
クラスの友達に聞いて解決しました。
ここの人たちは理解力がなさすぎだと思います

912 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 21:56:26 ]
>>908
'a'+1='b'
これならわかる?



913 名前:デフォルトの名無しさん [2010/05/12(水) 21:57:59 ]
>>908
ja.wikipedia.org/wiki/ASCII

ここを読めば文字「A」が65に対応してることがわかるとおもうよ。

914 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 22:01:28 ]
まぁ、普通はアルファベットに数値を足すと聞いたらアルファベットを並べて何文字か後のことだ。なんて思わない罠。

915 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 22:58:04 ]
C言語初心者です。入力した整数の数だけ*を表示したいんですが、
エラー続きです。どこをどう直せばいいか教えて下さい。

#include <stdio.h>
int f(int);

int main(void)
{
int no;
printf("整数を入力:");
scanf("%d",&no);
return 0;
}

void(int n)
{
while (n-->0)
putchar('*');
putchar('\n');
}


916 名前:デフォルトの名無しさん [2010/05/12(水) 23:01:23 ]
#include <stdio.h>
int f(int);

int main(void)
{
int no;
printf("整数を入力:");
scanf("%d",&no);
func(no);     //☆
return 0;
}

void func(int n)  //☆
{
while (n-->0)
putchar('*');
putchar('\n');
}


917 名前:デフォルトの名無しさん [2010/05/12(水) 23:02:57 ]
×func
○f

918 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 23:37:56 ]
プロトタイプ宣言と定義で戻り値の型が喰い違っている。

919 名前:デフォルトの名無しさん mailto:sage [2010/05/13(木) 01:18:41 ]
>>915
#include <stdio.h>
#include <ctype.h>

/* function prototype */
void disp_char( int );

int main( void )
{
 char no;
 printf( "整数を入力してください:" );
 scanf( "%c", &no );

 if( isdigit( no ) == 0 ) {
  printf( "Error:数値以外の文字が入力されました\n" );
 } else {
  disp_char( no - '0' );
 }
  return 0;
}

void disp_char( int t )
{
 int i;
 char c = '*';

 for( i = 1; i <= t; i++ ) {
  printf( "%c", c );
 }
 printf( "\n" );
}

920 名前:デフォルトの名無しさん mailto:sage [2010/05/13(木) 02:30:42 ]
>>908
もっと単純に考えたら?
Aの次のアルファベットって何?って聞かれたら困るのかな。そういうレベルよ。
Hの3つ前のアルファベットは?

で、zの次は何?って聞かれた時に、
・ないわー
・最初に戻ってa
・小文字終わったからA
とするか、そこは問題に明記されてないから、あなたが決めなきゃならないという話

921 名前:デフォルトの名無しさん mailto:sage [2010/05/13(木) 02:31:23 ]
解決してタワーorz

922 名前:デフォルトの名無しさん mailto:sage [2010/05/13(木) 03:55:38 ]
成りすましにマジレスしなくてもw



923 名前:デフォルトの名無しさん mailto:sage [2010/05/13(木) 09:44:49 ]
Cでプログラム組んでます。
ファイルの扱い方で質問があります。

fopen、fread、fwrite、fseek、fclose
でファイルの読み込みや書き込みを行っているのですが
あるファイルを読み書き可能状態でfopenして
10バイトfwiteしたあと、fcloseせずに
書いたデータをファイルの最後から1バイトずつfseekして
freadして、その1バイトが特定の条件に一致した場合に
そこまで読み込んだデータを破棄して
10-fseekしたバイト数だけのファイルを作りたいのですが
そんなこと可能なのでしょうか?

fwiteする前に書き込みデータをチェックしたかったのですが
その部分には手を入れられないため、
1度書き込んだファイルの途中をぶった切れるのかが知りたいです。

■■■■■■■□□□

□を破棄して、■だけのデータを作りたいというようなイメージです。

924 名前:デフォルトの名無しさん mailto:sage [2010/05/13(木) 09:55:29 ]
chsize

925 名前:デフォルトの名無しさん mailto:sage [2010/05/13(木) 09:56:49 ]
>>923
ftruncate()が使えればできなくはないが、事情が許すなら別ファイルに書き出すのが無難。

926 名前:デフォルトの名無しさん mailto:sage [2010/05/13(木) 10:00:44 ]
>>923
fclose()した後に切り詰めたいなら>924かtruncate()、開いたまま切り詰めたいならftruncate()。
但し、後者はファイルハンドルをfileno()で取得する必要あり。

927 名前:デフォルトの名無しさん mailto:sage [2010/05/13(木) 17:53:32 ]
フィボナッチ数列を出力するプログラムを書いたのですが
どうもうまく動きません
どうすればいいでしょうか
#include<stdio.h>
#include<stdlib.h>
#define TERM 30
int main(void){
int fivo=0,n=0,temp;
FILE *fp;
fp=fopen("fivo.txt","wt");
if(fp==NULL){
fprintf(stderr,"ファイルオープンエラー");
exit(1);
}
while(fivo<=TERM){
if(fivo==1||fivo==2)n=1;
fprintf(fp,"F(%2d)=%10d\n",fivo,n);
fivo++;
temp=n;
n+=temp;
}
fclose(fp);
printf("正常に終了しました\nfivo.txtに保存しました");
return 0;
}






[ 新着レスの取得/表示 (agate) ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<245KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef