C言語なら俺に聞け( ..
[2ch|▼Menu]
391:デフォルトの名無しさん
07/10/26 20:29:39
関数の引数としてポインタを渡して、そのポインタの変数に値をいれているのですが、
関数を呼び出す時によって、値をいれる必要が無いときがあります。
不要な値のために変数を宣言したくないのですが、変数を宣言しないでいい方法などはありませんか?

hoge( &x, &y, &height, &width);
と呼び出すのですが、&heightと&widthの結果を使わないときもあるので、
int x, y; だけ宣言して、heightとwidthは変数宣言したくないと思っています。

392:デフォルトの名無しさん
07/10/26 20:30:26
型がヘンすぎる 勉強不足

393:デフォルトの名無しさん
07/10/26 20:31:42
>>391
C++は入れない場合も同じ名前に出来る 2つ書けばいい

394:デフォルトの名無しさん
07/10/26 20:33:40
int hoge( a, b, c, d);を定義して
たとえばcとdを使わないなら、hoge( a, b) { return hoge( a, b , 0 , 0);}

395:デフォルトの名無しさん
07/10/26 20:34:45
>>391
NULL を使えばいいと思うよ

>>393
ここはC言語のみ
C++なら誘導してからにしてください

396:391
07/10/26 20:39:55
>>393
すみません、C言語です。

>>394
すみません。 私が関数ではないため動作が変えれないのと、不必要な値は6この引数のうち、
1, 2, 5が不要になったりする場合もあります。

>>395
すみません。
NULLを使うと言うのは、どのようにすればいいのでしょうか?
型を、castするという意味でしょうか?

397:391
07/10/26 20:48:00
連続投稿失礼します。
hoge( &x, &y, NULL, NULL);
とすれば、コンパイルは通ったのですが、これは正しいのでしょうか?

簡単に動作を説明して頂けるとありがたいです。

398:デフォルトの名無しさん
07/10/26 20:50:47
>>397
動作はNULLで通るように自分で書かなければ行けない

399:391
07/10/26 21:26:43
>>398
> 自分で書かなければいけない
と言うのは、関数をそのように修正すると言うことでしょうか?
関数は自分で作ったもので修正はできないと思います。

400:デフォルトの名無しさん
07/10/26 21:27:56
>>399
NULL の指す先を読み書きしないようにするだけ

401:デフォルトの名無しさん
07/10/26 22:00:33
>>399
hoge()の仕様がわからないと、引数でNULLを渡していいかどうかは判断できない。

402:デフォルトの名無しさん
07/10/26 22:44:08
heightとwidthは>>391が使わないというだけでhogeは内部で値を設定しようとするからNGだと予測する俺エスパー

403:デフォルトの名無しさん
07/10/26 22:51:54
まともな関数ならチェックしてるだろうけど・・・

404:デフォルトの名無しさん
07/10/27 00:01:40
昔はチェックしてたけど不定値渡されて以来チェックするのをやめた

405:デフォルトの名無しさん
07/10/27 00:10:28
>>404
あなたが hoge() か

406:デフォルトの名無しさん
07/10/27 00:15:31
#include <stdio.h>

int f(int &x){
if(&x==NULL)
return -1;
return x+10;}


int main(){
int x=0;
printf("%d\n",f(x));}

407:デフォルトの名無しさん
07/10/27 00:23:05
>>406
それじゃポインタ渡した意味な(ry

408:デフォルトの名無しさん
07/10/27 00:29:32
-1がreturnされることってある?

てか参照渡しってCで使えるの?

409:デフォルトの名無しさん
07/10/27 00:38:22
#include <stdio.h>

int f(int *x){
if(x==NULL)
return -1;
return *x+10;}


int main(){
int x=0;
printf("%d\n",f(NULL));}

410:デフォルトの名無しさん
07/10/27 00:42:57
それがどうしたと言わざるをえない

411:デフォルトの名無しさん
07/10/27 00:45:11
assert(p != NULL); で十分。

412:デフォルトの名無しさん
07/10/27 00:50:42
assertと引数チェックは違うんだぜ・・・

413:デフォルトの名無しさん
07/10/27 01:30:01
引数チェックが一番の使いどころだろ > assert()

414:デフォルトの名無しさん
07/10/27 01:34:02
>>413
へぇ、永遠のデバッグビルドか

415:デフォルトの名無しさん
07/10/27 09:58:07
>>414
sunも引数チェックにassert使えって言ってるよ。

416:デフォルトの名無しさん
07/10/27 10:40:38
それは引数を渡す方も一緒に開発してる時だろ
内部的なエラーでも無い限りNULLになる事はありえない前提

417:デフォルトの名無しさん
07/10/27 11:38:55
自分で作ってるライブラリじゃなくても、仕様にNULLを渡した時の動作が書いてなかったら、
NULLを渡すなんてありえない。

418:デフォルトの名無しさん
07/10/27 16:10:15
引数チェックはやって当然。

419:デフォルトの名無しさん
07/10/27 16:15:39
両方書いておけばおk

420:デフォルトの名無しさん
07/10/27 16:20:57
ポインタで渡される引数のチェックって
NULL比較?

421:デフォルトの名無しさん
07/10/27 17:39:12
mallocとかポインタがわけわかりません。

図とかでイメージしやすく解説してください


422:デフォルトの名無しさん
07/10/27 17:44:10
>>391
カリー化

423:デフォルトの名無しさん
07/10/27 17:45:58
>>421
本読め

424:デフォルトの名無しさん
07/10/27 17:46:25
mallocって
char *str;

/* 文字列のためのメモリを確保 */
str = (char *)malloc(100);

こんな感じに書いてるけど

char str[100]

ってやった方が楽じゃん。なんでmallocなんて使うの?

425:デフォルトの名無しさん
07/10/27 17:49:17
>>391
型が分からなかったので適当に決めた
int hoge_wrap(int *x, int *y, int *width, int *height){
int dummy=0;
if(x==NULL) x=&dummy;
if(y==NULL) y=&dummy;
if(width==NULL) width=&dummy;
if(height==NULL) height=&dummy;
return hoge(x, y, width, height);
}

426:デフォルトの名無しさん
07/10/27 17:50:10
>>424
必要ないなら無理して使わなくても良い物です

427:デフォルトの名無しさん
07/10/27 17:52:55
>>426
無理して使えるようになるためにおせーてよ
何か新天地が開けるかもしれないじゃん


というか教えてくださいお願いしますガンダム見ませんから

428:デフォルトの名無しさん
07/10/27 17:56:59
newやvectorつかえば十分 性能も変わらない

429:デフォルトの名無しさん
07/10/27 17:58:13
char型で考えるから分かりにくいことになる。

430:デフォルトの名無しさん
07/10/27 18:00:08
char だと領域確保に制限がある new mallocは巨大なのが出来る

431:デフォルトの名無しさん
07/10/27 18:00:14
newやvectorがわからないっす

432:デフォルトの名無しさん
07/10/27 18:04:55
>>427
char array[100]; のかわりにchar *p; p=(char*)malloc(100);を使うとき

1.配列のサイズが未定のとき
  実行時にしかか配列のサイズ(この場合100)がわからないとき
2..配列のサイズが大きすぎて内部変数として確保できないとき
  外部変数を使うという手もある

433:デフォルトの名無しさん
07/10/27 18:05:28
ここって C++ ありだっけ?

434:デフォルトの名無しさん
07/10/27 18:09:53
char型だと巨大配列を確保できない

#include <iostream>
#include <vector>
using namespace std;
#define N 10000000

main(){

int *x;
x=new int[N];

vector<int> y;
y.reserve(N);

// char z[N];z[0]=1;

for(int n=0;n<N;n++)x[n]=y[n]=1;
printf("%d",x[0]);}

435:デフォルトの名無しさん
07/10/27 18:10:55
>>433
なし

436:デフォルトの名無しさん
07/10/27 18:11:16
mallocとnewに性能の違いはなく、vectorはちょっと高性能でちょっと動作に負担がかかる

437:デフォルトの名無しさん
07/10/27 18:30:06
(ノ∀`) アチャー

438:デフォルトの名無しさん
07/10/27 18:58:41
>>418
状況による。
たまにいる、必ずやるってやつは素人。

439:デフォルトの名無しさん
07/10/27 19:23:20
>>424
配列サイズが分からなかったり、途中で増える可能性がある時に使う

440:デフォルトの名無しさん
07/10/27 19:35:21
>>438
やらないとLintに叱られます

441:プリンがー
07/10/27 19:55:12
問題を解く時、まず問題を見て引数があるかないかってどうやって分かります?


442:デフォルトの名無しさん
07/10/27 20:02:57
問題ってのが仕事上の問題なのか学校で先生に出された問題なのかによる

443:デフォルトの名無しさん
07/10/27 20:03:16
エスパー!! エスパー!!

444:デフォルトの名無しさん
07/10/27 20:07:27
>>440
そんなlintありません。

445:デフォルトの名無しさん
07/10/27 20:21:30
>>434
スタックサイズを増やせばおk
ま、普通はポインタにして malloc するがな

446:デフォルトの名無しさん
07/10/27 20:37:47
>>424

char str[100] の[]の中に変数を入れるとコンパイルエラーになるが、
mallocだとそれができます。

447:デフォルトの名無しさん
07/10/27 20:42:54
コンパイラによってはエラーにならないけどな

448:デフォルトの名無しさん
07/10/27 20:55:01
C99

449:プリンがー
07/10/27 22:06:09
>>442
学校で先生に出された問題ってか演習問題とか


450:デフォルトの名無しさん
07/10/27 23:11:41
>>449
コンピュータじゃないんだから人間的に考えればいいと思うよ

451:デフォルトの名無しさん
07/10/27 23:16:35
入力として必要なものは引数なんじゃね

452:デフォルトの名無しさん
07/10/28 00:19:56
1 getchar() を用いて 1 文字入力を行い、Ctr+Z が入力されるまで次の処理を繰り返しなさい。
  大文字、小文字に関係なく、アルファベットを入力した場合には、それぞれの入力した個数を数えなさい。
2. 1. の処理終了後、アルファベットをそれぞれ何個ずつ入力したか出力しなさい。
これなんですがどう頑張っても意味不明です・・・
ヒントとして
?入力アルファベットの個数を数えるカウンタは大きさ 26 の配列で用意。
最初に、配列の 26個の要素すべてを0クリアすること。
?A〜Z、a〜z は ASCIIコードの 65〜90、97〜122 に該当することを考えれば、配列の何番目をカウントUP するかは計算で求められるはず。
実行結果
入力文字
14abcaaabccdzzgk(リターン)
aabc147cab8cc3c(リターン)
CTRL+Z(リターン)
とすると
a = ○○個 b = ○○個 c = ○○個 改行
d = ○○個 e = ○○個〜〜〜 と一覧を出力させたいんです。
とあるんですが、どう書いたらいいんでしょうか・・・('A`
switch使ってみたりしたんですが、イマイチ意味がわからなくなってきました・・・。
ちなみに今まで習った事は、
if if else for while break continue goto 算術関数 strcpy等、 等の初歩的なことだけです。。。

453:デフォルトの名無しさん
07/10/28 00:22:10
>>452
宿題スレ行け

454:デフォルトの名無しさん
07/10/28 00:25:32
どこがわからないのかが分からないが

65-65は0
90-65は25

97-97は0
122-97は25
ってことじゃね

455:デフォルトの名無しさん
07/10/28 00:25:45
今まで習った事の中にgotoがあるのが気になる・・・
普通初心者にgotoは教えないだろ

456:デフォルトの名無しさん
07/10/28 00:25:56
>>152
宿題スレに行け……と言いたいところだがヒントをやろう

'a'-'a' == 0
'z'-'a' == 25
'A'-'A' == 0
'Z'-'A' == 25

457:デフォルトの名無しさん
07/10/28 00:29:12
goto嫌いな人ってbreakとかcontinueとかも嫌い?

458:デフォルトの名無しさん
07/10/28 00:30:44
goto が嫌いな理由は goto に過剰反応する人を呼ぶ事

459:デフォルトの名無しさん
07/10/28 00:33:50
gotoが嫌いというよりは、(gotoを)初心者に教えるのが嫌い

460:デフォルトの名無しさん
07/10/28 00:56:35
あーいえA=65とかで、考え方としては、
scanfで変数cに文字を入れた場合、変数cから65を引いた数、例えばAなら65で0となり、Cなら67で2となり、
配列a[26]の[]内をcとして、そこに+1づつカウントしていく というのはわかるんですが、
どう書いていいのかチンプンカンプンなんです・・・。
そもそもgetcharって1文字入力なのに演習問題の実行例には
abcdddef14(return)
afijjgjkk(return)
CTRL+Zってなっててなんで文字列での入力になってるんだろうとか思ったり('A`

ちなみにgotoは多段ループから強制的に抜けたい場合にのみ使ったほうがいいかもしれないけどオススメはできないとも書いてありました。

461:デフォルトの名無しさん
07/10/28 01:01:19
あ、ちょっと頑張って書いてみます。
なんとなくわかりかけたかも・・・?
ちなみにC言語学んでからまだ5日目です('A`

462:デフォルトの名無しさん
07/10/28 01:03:27
getcharで一文字ずつ取り出す
意味のある文字はアルファベットとCTRL+Z。
それ以外の(return)とか数字とかは無視すればいいんじゃね?
CTRL+Zはなんだっけ・・・EOT?

463:デフォルトの名無しさん
07/10/28 01:09:23
>>462
whileでのgetcharでのループから抜け出すための CTRL+Z=EOF っす。
a と入力して、画面に a = 1個 と入力させるのはかけるんですが、
abcと入力した場合は配列使うと思うんですが、まずそもそも
getcharでabcの場合 while ((c = getchar()) != EOF) //cは配列 配列に入力 CTRL+Zを押すとwhile終了。
でc[]にc[0]=a c[1]=b c[2]=cとなる・・・の?あれ理解しかけてきました。
ずっとc[0]にabcとなると思ってました・・・。
文字列の場合はgetsになるんですね、このすぐ先に習う項目にgetsあってみてみたら文字列って書いてあってアッーって思いました。

464:デフォルトの名無しさん
07/10/28 01:10:57
勘違いしてるっぽい

465:デフォルトの名無しさん
07/10/28 01:12:50
・「abcと入力した場合」でもgetcharは「a」を入力した時点で抜けてくる
・c = getchar()のcは配列である必要ない

のはず・・・

466:デフォルトの名無しさん
07/10/28 01:20:45
ナンダッテー!
見た目的には a と打ち込むだけでは エンターを押さない限り文字入力待機画面になってるんですけど、(上記問題の場合はwhileなので文字→エンター→入力待機→文字→エンター→入力待機となるのはわかります)
内部的には処理されているということですか?
aだけ押す、エンターは押さない→画面には入力待機状態であるが、内部的には処理されている?
ちょっとやってみまつ。

467:デフォルトの名無しさん
07/10/28 01:24:39
内部的にどのタイミングで処理してても、変わらないんだが。

468:デフォルトの名無しさん
07/10/28 01:26:04
ということはgetcharでabcdefと入力した場合は
aからfまで順に1つ1つ処理していくということになるんですか?

469:デフォルトの名無しさん
07/10/28 01:30:56
while ((c = getchar()) != EOF) {
puts("なんか入力された\n");
}

470:デフォルトの名無しさん
07/10/28 01:34:00
エンターを押した時点で処理が開始されるが、文字列をまとめてじゃなくて一文字ずつ読み込む

471:デフォルトの名無しさん
07/10/28 01:35:44
#include <stdio.h>
int main(void)
{
int c;
while ((c = getchar()) != EOF) {
printf("%d\n" ,c);
}
return 0;
}

出力した結果、>>470さんの言ったとおり、例えばAAA(リターン) の場合綺麗に65656510と表示されました!
これで問題に取り組んでみたいと思います!
ありがとうございます!!!

472:デフォルトの名無しさん
07/10/28 01:37:46
あれ?Enter待ちになるのか/(^o^)\
引っ込んでようorz

473:デフォルトの名無しさん
07/10/28 01:40:34
いえいえ、協力してくれようとしてくれただけでも感謝感激雨霰です。
皆さん本当にありがとうございました。

474:デフォルトの名無しさん
07/10/28 01:41:46
霰が霧に見えた orz

475:デフォルトの名無しさん
07/10/28 09:44:07
goto嫌いな人が do{}while(0) で break を使っているのを見て泣けた。

476:デフォルトの名無しさん
07/10/28 11:44:11
VisualStudio2008で作ったプログラムなんですが、
重複したシンボルがある(?)とか怒られてて困っています
原因がわかる方いませんか?おねがいします

URLリンク(www.uploda.org)
一応ファイルをうpしました

477:デフォルトの名無しさん
07/10/28 11:56:55
>>476
マルチうざい

478:デフォルトの名無しさん
07/10/28 13:19:04
>>476
どのシンボルが重複してるかまで表示されてるだろ?
それが重複してるんだよ。

479:デフォルトの名無しさん
07/10/28 13:41:16
>>478
ありがとうございました。よく見たら書いてました。

480:デフォルトの名無しさん
07/10/28 15:03:31
2バイト文字の扱いがよくわからないです
例えば、配列の中身を順に表示させようと思っても文字化けします
array[11] = {"しーげんご"};
Shift-Jisとかに変換してから使うんですか?

481:デフォルトの名無しさん
07/10/28 15:17:35
>>480
> 配列の中身を順に・・・
1バイトずつの表示はできない。

482:デフォルトの名無しさん
07/10/28 15:30:49
>>481
そうなんですか・・・
じゃあ半角英字みたいに平仮名でも文字コードに数字を足して
次の文字へ!みたいな処理はできますか

483:デフォルトの名無しさん
07/10/28 15:54:37
なんの文字コードを使っているのかわからないが、
いちど使用している文字コードの文字コード表を見ることを薦める。

ちなもに、S-JISでは、「あ」「い」「う」は,それぞれ,0x82a0, 0x82a2, 0x82a4

484:デフォルトの名無しさん
07/10/28 16:02:41
>>483
調べてみたんですが、SーJISで「あ」を表示させるには
%cを2回と0x82,0xa0をつかって表示させると書いてありました。
ほかの表示方法は見つけられなかったのですが、ありますか?

485:452
07/10/28 17:12:30
無事できました!
が、次の問題で一点引っかかる事が('A`
終了条件eまたはEってどういう風に記述するんですか?
while(gets(str) != ○○)
の○○にeかEを入力した場合で終了という風にしたいのですが・・・。
'e' とか'E'は駄目みたいです。

486:デフォルトの名無しさん
07/10/28 17:13:57
なんでgetsになってんの?

487:デフォルトの名無しさん
07/10/28 17:17:56
あ、ごめんなさい。
習う順番でgetchar+putchar → gets+putsという風になってて
問題が、
gets() を用いて、テストの点数を文字列として入力しなさい。
上記処理中、eかEを入力した場合は下記処理をスキップさせ、内容を出力せよ っていう問題なんです。
考え方としては、今まで習ってきたように ○○が入力されるまでは処理を続けるというwhileループでの処理だと思うんですが・・・。

488:デフォルトの名無しさん
07/10/28 17:21:55
文字列の中に'e'か'E'があるかどうかをチェックする

489:デフォルトの名無しさん
07/10/28 17:33:29
ありがとうございます><
int変数aというものを新たに用意し、
getsで入力した中に、a = 'e' か a='E' での判定を入れたら無事とおりました><

490:デフォルトの名無しさん
07/10/28 19:18:39
どうしてもwhile内で済ませたかったら、
while(gets(str)[0] == 'E')
とか? 試してないけど

NULLが返ってきた時に危険だなw

491:デフォルトの名無しさん
07/10/28 19:42:10
URLリンク(a-draw.com)
できたました!
こんな長い(すごい短いんだろうけど・・・)の書いたの初めてです・・・。

492:デフォルトの名無しさん
07/10/28 19:47:06
3つの整数値を読み込んでそれらの値がすべて等しければ「3つの値は等しいです」と、
どれか2つの値が等しければ「2つの値が等しいです」と、そうでなければ「3つの値が異なります」と表示するプログラムをつくりなさい
   

#include <stdio.h>
int main(void)
{
int n1,n2,n3;
printf("整数A"); scanf("%d", &n1);
printf("整数B"); scanf("%d", &n2);
printf("整数C"); scanf("%d", &n3);
if(n1==n2==n3)printf("3つの値は等しいです");
else if(n1==(n2||n3))
printf("2つの値は等しいです");
else if(n2==(n1||n3))
printf("2つの値は等しいです");
else if(n3==(n2||n1))
printf("2つの値は等しいです");
else printf("3つの値は異なります");
return(0);
}
このように組んで整数Aに1整数Bに2整数Cに3を代入すると2つの値は等しいですと表示されてしまいます
問題点を教えてください><

493:デフォルトの名無しさん
07/10/28 19:53:17
n1==n2==n3 は n1==(n2==n3) で、意味が違う。
n2||n3 n2||n1 n1||n3 は、それぞれ両方0のとき0、それ以外だと1になる。

494:デフォルトの名無しさん
07/10/28 19:55:04
#include <stdio.h>
int main(void)
{
int n1,n2,n3,k=0;
printf("整数A "); scanf("%d", &n1);
printf("整数B "); scanf("%d", &n2);
printf("整数C "); scanf("%d", &n3);

if(n1==n2)k++;
if(n1==n3)k++;
if(n2==n3)k++;

if(k==3)printf("3つの値は等しいです");
else if(k==1)printf("2つの値は等しいです");
else printf("3つの値は異なります");
}

495:デフォルトの名無しさん
07/10/28 19:56:48
問題点を聞かれてるのに、俺プログラムを自慢されても困る

496:492
07/10/28 20:05:56
>>493-494
ありがとうございました。||の使い方をかんちがいしていました。。。

497:デフォルトの名無しさん
07/10/28 20:33:46
>>491
なんか無駄が多い気がするが、まあそれは眼をつむっておこう


だがgetsの入力先配列が要素数2てのは……誤入力もあるだろうし、せめて256くらい確保した方が良い気がする

というか、要素数2だとヌル文字入らないじゃん(というか100も入らないし)
atoiってヌル文字入らないと変な動作になることあるはず

498:デフォルトの名無しさん
07/10/28 21:06:24
>>497
むむ、
getsでの取得は 例えば入力が50なら、charだから配列[0]に50 で配列[1]に\0が入る=2個で足りるってことじゃないですか?
もしgetsでの取得変数がintの場合なら点数最大100(つまり3桁)は最低でも[4]になるのはわかります。

まぁでも、教えてもらっている人にも、配列は無駄でもいいから多く取った方がいいと教わりましたので、多くとる事を、この先心がけていきます!
ありがとうございました!

499:デフォルトの名無しさん
07/10/28 21:21:49
ごめんなさいボクが馬鹿でした。
ためしにcharでの変数aに入力したものを、出力させるのかいてみて
a[0]をやったら、最初の1文字しか出力されませんでした。
本当にありがとうございました。

500:デフォルトの名無しさん
07/10/28 22:56:33
int *foo
int* foo
の違いを教えてください><

今までint *foo しか使ってなくて
いきなりint* fooが出てきてわけわかりません><

501:デフォルトの名無しさん
07/10/28 22:57:42
>>500
次は int * foo だ

502:デフォルトの名無しさん
07/10/28 23:00:18
宣言時のアヌスの位置くらい自由にさせてあげてください

503:デフォルトの名無しさん
07/10/28 23:03:21
いまだにforの無限ループを見ると悲しくなる( ; ; )

504:デフォルトの名無しさん
07/10/28 23:04:11
>>501
そんなのもあるのですか

ソース解読してる途中にこんなの出てきてわけわからんのです
すいませn助けてください。ほんと

何でグぐれ場いいのかもわからなくて
すんません、マジで

505:デフォルトの名無しさん
07/10/28 23:07:39
>>504
int *foo;
int* foo;
int * foo;
は全部一緒

506:デフォルトの名無しさん
07/10/28 23:09:54
ありがとうございます

なんでこんな風に書き方分けてるのか

507:デフォルトの名無しさん
07/10/28 23:14:35
*は型名にも変数名にも使えないから問題ない

508:デフォルトの名無しさん
07/10/28 23:35:53
初歩的な質問なのですが

for(int i = size >> 1 ; ; i >>= 1)

というループがあったのですが
size >> 1 や i >>= 1 というのはどういう意味なのですか?




509:デフォルトの名無しさん
07/10/28 23:37:41
int*foo;もいけるんじゃない?

510:デフォルトの名無しさん
07/10/28 23:40:19
>>508
ビットシフト

511:デフォルトの名無しさん
07/10/28 23:44:55
>>508のだとiをビットシフトするとどうなるんでしょう

あとforの2つ目のところが空白なのもわけがわかりません

512:デフォルトの名無しさん
07/10/28 23:46:35
i >>= 1 すると i の各ビットが右へ 1 桁ずつずれる

forの2つめが空白の場合は条件なしの繰り返し=無限ループ

513:デフォルトの名無しさん
07/10/28 23:53:43
>>511
iが10(2進数で1010)だとすると5(101)になる
5だとすると2(10)になる。その次はもう予想できるよな?

514:デフォルトの名無しさん
07/10/29 00:07:56
>>512-513
ありがとうお兄ちゃんたち!

515:デフォルトの名無しさん
07/10/29 01:18:22
>>506
俺は
int* foo;
のほうが好きかな
「int型へのポインタを返す」ってのをあらわしてる感じで

516:デフォルトの名無しさん
07/10/29 01:35:28
俺は
int *foo;
のほうが好きかな
int *foo, *bar;
みたいに複数いっぺんに宣言するときわかりやすいし

517:デフォルトの名無しさん
07/10/29 01:35:53
しかしそれだと、2個目以下に*付け忘れる可能性がある。

518:デフォルトの名無しさん
07/10/29 01:37:09
517は>>515

519:デフォルトの名無しさん
07/10/29 02:21:33
大きな配列の初期化って
どうしていくべきですか?
100X100くらいの配列の

520:デフォルトの名無しさん
07/10/29 02:23:34
あんな風にしていくべきだと俺は思っている
だがそういう風にするとああいうことも起きるわけでいちがいに
どちらがいいとは判断しかねるな

521:デフォルトの名無しさん
07/10/29 06:11:01
ど素人におすすめの参考書を教えてください。

522:380
07/10/29 11:19:52
先週質問させていただいた者ですが、mallocでどうしても組めません。
mallocでメモリに格納→格納した文字列を検索後抜き出す動作をもう一度ご教示いただけないでしょうか。

523:デフォルトの名無しさん
07/10/29 12:46:28
>>522
先ずは試しにfgets()版を見せてくれ。

524:380
07/10/29 13:16:03
>>523
void Hairetsu(void) {
FILE *read;
char fnameread[90];
char charline[90];
char KensakuName[20];
strcpy(fnameread, "*****.txt");
strcpy(KensakuName, "C3 10237");
StartTime = clock();
printf("%d\n", StartTime);
while(KensakuCount < 10) {
read = fopen(fnameread, "r");
if (read == NULL) {
printf("ファイルがオープンできません\n");
exit(1);
}
while(1) {
fgets(charline, 90, read);
if (strcmp(charline, "ENDDATA\n") == 0){
***ファイルは必ず最後の行にENDDATAと記載されています
break;
}
if (strncmp(charline, KensakuName, 16) == 0) {
***ここで検索に引っかかった行から新たな要素を取り出して再度同ファイル内で検索をかけます
***その際にまた先頭行から読み直してfgetsを用いて検索をしこれをこのif内で3回程度繰り返えします。
}
}
fclose(read);
}
}

525:デフォルトの名無しさん
07/10/29 13:31:08
>>524=380
「えらい時間」とあるけど、どれくらい掛かるの?
試しに>524相当のロジックを書いて10万と1行のファイルで動かしてみたが、1秒も掛からないんだが。

526:380
07/10/29 13:37:22
>>525
これを1行目から順に繰り返すので総読み出し回数は10万行^5になります。
それで更にその中に計算式が組み込まれていますので・・・・

527:デフォルトの名無しさん
07/10/29 13:45:24
>これを1行目から順に繰り返すので総読み出し回数は10万行^5になります。
>524からこれは読み取れないわけだがw
つーか、それはそもそもアルゴリズムに問題がないか?
オンメモリでもそれだけアクセスすればそれなりに遅いと思うぞ。

528:デフォルトの名無しさん
07/10/29 13:49:43
どうでもいいが、10万行^5は10^25だな。
仮に1nsで処理できる凄まじいコンピュータがあったとして、ざっと3億年掛かる計算だが。

529:デフォルトの名無しさん
07/10/29 14:58:18
ポインタ配列のキューに文字列を挿入するプログラムを作っているのですがうまくいかないです。
挿入後に現在入っているキューを全部表示するようにしたいのですが、最後に挿入した文字列しか表示されないです。
ちなみに変数opをint型に変えると期待通りに出力されます(intのscanfだと数値以外の文字も0と認識してしまうので使えない)が、
char型だとなぜこうなってしまうのでしょう?

実行結果(変数opがchar)
Operation(0:enqueue 2:quit)0
input string : a
String Queue : [a]
head[0] tail[1]
Operation(0:enqueue 2:quit)0
input string : b
String Queue : [b]
head[0] tail[1]
Operation(0:enqueue 2:quit)

実行結果(変数opがint)
Operation(0:enqueue 2:quit)0
input string : ab
String Queue : [ab]
head[0] tail[1]
Operation(0:enqueue 2:quit)0
input string : bc
String Queue : [ab] [bc]
head[0] tail[2]
Operation(0:enqueue 2:quit)

次レス以降にソースを書きます

530:1/2
07/10/29 14:58:49
#include "stdio.h"
#include "stdlib.h"
#include "string.h"

struct structQ { char Q[5];};

int next (int x){
if(x==4) return 0;
else return x+1;
}

void enqueue(char *s, int head, int *tail, structQ *AllQ){
if(next(*tail)==head) printf("OVERFLOW!\n");
else
{
strcpy(AllQ[*tail].Q, s);
*tail = next(*tail);
}
}

void printQueue(int head, int tail, structQ *AllQ){
int h;
printf("String Queue : ");
for(h=head; h!=tail; h =next(h))
printf("[%s] ", AllQ[h].Q);
printf("\n");
}


531:2/2
07/10/29 14:59:25
int main (void){
structQ *AllQ;
AllQ = (structQ *)malloc( sizeof(structQ)*(5) );
int head =0, tail =0;
char *s, str[100];
char op;
// int op;
while(1){
printf("Operation(0:enqueue 2:quit)");
scanf("%s", &op);
if(op == '0')
// scanf("%d", &op);
// if(op == 0)
{
printf("input string : ");
scanf("%s", str);
s = (char *)malloc( sizeof(char)*(strlen(str)+1) );
strcpy(s,str);
enqueue(s, head, &tail, AllQ);
free(s);
printQueue(head, tail, AllQ);
}
else if(op == '2')
// else if(op == 2)
break;//終了
else
printf("invalid ope number!\n");
printf("head[%d] tail[%d]\n", head, tail);
}
free(AllQ);
return 0;
}

532:デフォルトの名無しさん
07/10/29 15:05:00
>>529
STL使っておけ

vector< string > x;

x.push_back("文字列");
x.push_back("名無しです");

x[0],x[1]で文字列にアクセスできる

533:デフォルトの名無しさん
07/10/29 15:09:27
>scanf("%s", &op);

文字列を入力したいんなら、char じゃだめだろ
char には 1 文字しか入らない
char の配列にしないと

534:デフォルトの名無しさん
07/10/29 15:11:49
>>532
突っ込みどころだらけ。

>#include "stdio.h"
cの規格にあるインクルードファイルは""で括ってはいけません。
また、一般的にプロジェクトローカルなもの以外は<>で括るべきです。

>ちなみに変数opをint型に変えると期待通りに出力されます(intのscanfだと数値以外の文字も0と認識してしまうので使えない)が、
%d指定で整数値を入力する場合、入力に失敗した場合は変数が更新されないので、「0と認識してしまう」というのは間違い。

>scanf("%s", &op);
文字型への%s指定は行なってはいけません。%sはあくまでも、文字列入力です。
この呼び出しで恐らくスタック領域の破壊が起こり、他の変数の値がおかしくなったせいでキュー登録に失敗した可能性があります。

535:デフォルトの名無しさん
07/10/29 15:12:45
>>532
cにはSTLなどありません。スレタイも読めないくらい頭が回らないのであれば、無理に回答しなくて宜しいかと。

536:デフォルトの名無しさん
07/10/29 15:26:38
>>533
opはオペレーションNoの取得なので、1文字です。
指定文字列の取得はchar str[100]に入れています。
>scanf("%s", str);

>>535
1文字入力の%cで
>scanf("%c", &op);
と変えてみました。
キューには格納されているようですが、変な出力結果になってしまいます。

実行結果
Operation(0:enqueue 2:quit)0
input string : ab
String Queue : [ab]
head[0] tail[1]
Operation(0:enqueue 2:quit)invalid ope number!
head[0] tail[1]
Operation(0:enqueue 2:quit)0
input string : bc
String Queue : [ab] [bc]
head[0] tail[2]
Operation(0:enqueue 2:quit)invalid ope number!
head[0] tail[2]
Operation(0:enqueue 2:quit)

537:デフォルトの名無しさん
07/10/29 15:30:17
>>536
"%c"を" %c"にして味噌。

538:デフォルトの名無しさん
07/10/29 15:32:33
>>537
できました!
ありがとうございます。
%cのスキャンにはスペースが必要なんですね。

実行結果
Operation(0:enqueue 2:quit)0
input string : ab
String Queue : [ab]
head[0] tail[1]
Operation(0:enqueue 2:quit)0
input string : bc
String Queue : [ab] [bc]
head[0] tail[2]
Operation(0:enqueue 2:quit)

539:デフォルトの名無しさん
07/10/29 15:35:11
>>524
ファイルのデータをすべてmallocで確保したヒープ領域に読み込む。
1.fstat関数でファイルサイズを取得する。
2.そのファイルサイズ分をmallocし、そこにファイルの全レコードを読み込む。
  レコードサイズ64バイトで10万レコードだと、6.4Mバイトほど。
3.検索はmallocで確保したバッファの中を検索する。


540:デフォルトの名無しさん
07/10/29 15:36:30
>>538
いや、今回はたまたまその前の%sの喰い残しの改行文字を破棄する必要があるので、空白を入れることで回避したと言うだけ。
毎回空白が必要だと言うわけではない。

scanf()の振る舞いについて、下手な入門書に頼らずきちんと確認しておくことをお勧めしておきます。
因みに、printf()とscanf()の指定子を互換性があるかのごとく並列で解説しているような入門書が多く出回っていますが、
互換性はないものと思って理解しておく方が間違いがありません。

541:デフォルトの名無しさん
07/10/29 15:42:20
>>540
scanfについて調べたら、改行の読み捨てが必要な場合があるみたいですね。
勉強になりました、ありがとうございます。

542:デフォルトの名無しさん
07/10/29 18:05:25
2ちゃんのトリップ生成法なんですがC言語板をしりたいです

$tripkey = "#istrip";
$tripkey = substr($tripkey,1,);
$salt = substr($tripkey.'H.',1,2);
$salt =~ s/[^\.-z]/\./go;
$salt =~ tr/:;<=>?@[\\]^_`/ABCDEFGabcdef/;
$trip = crypt($tripkey,$salt);
$trip = substr($trip,-10);
$trip = '◆'.$trip;
print "$trip";

543:デフォルトの名無しさん
07/10/29 19:59:39
丸投げはスレ違い

544:デフォルトの名無しさん
07/10/29 20:36:42
printf系の関数使わないで、浮動小数点数を文字列に変換するにはどうしたらいいでしょうか?

545:デフォルトの名無しさん
07/10/29 20:47:48
インクルードひとつも使わないやつ書いてやるぜ

546:デフォルトの名無しさん
07/10/29 20:51:06
面倒になったので一部日本語で説明する

double x;;
char top[100] down[100],t,d;


小数点の一から始めて、下向きに数字を読み取ってdownにいれて
一より大きいなら上向きにtopに入れていく

最後に出力

547:デフォルトの名無しさん
07/10/29 21:53:10
>>544 行数の関係上汚いコードで申し訳ない。
単なる思いつきで書いたから、特に色々とは突っ込まないで欲しい。
あと、こっちの環境ではまともに動いてくれない。 小数点の精度上、
下位ビットにゴミがあってそれを取り込んでしまう。
まぁ、その辺はなんとかしてくれい。 

void DoubleToStr(double f) {
char up[256], down[256],temp;
int d = f, i = 0, j = 0;
double z = f;

do { up[i++] = d % 10 + '0';
d = d / 10;
} while (d != 0);

up[i++] = '.'; up[i] = '\0'; i-=2;
while (j < i) {
temp = up[j]; up[j] = up[i]; up[i] = temp;
++j; --i;
}

z = f; d = f; z = z - d; i = 0;
do { z = z * 10;
d = z;
down[i++] = d + '0';
z = z - (double)d;
} while (z != 0.0);

down[i] = '\0';
strcat(up, down);
printf("%s\n", up); }

548:プリンがー
07/10/29 22:16:02
100個の実数データを配列a[100]に読んで、その最大値をmaxという
変数に求め、結果を出力するプログラムを書きなさい。

#include <stdio.h>
int main (void)
{
int i;
double a[100],max=0;

for(i=0;i<=100;i++){

scanf("%lf",&x[i]);

if(x[i]>max){
max=x[i];
}
}
printf("最大値は%fです。",max);
return(0) ;
}

 これであってますか?


549:aho
07/10/29 22:17:53
>>548
あってるよ〜

550:プリンがー
07/10/29 22:22:29
>>549
ありがとうございます。


551:デフォルトの名無しさん
07/10/29 22:22:40
あってねぇーよ

double a[100]で100個用意したのはいいが
for(i=0;i<=100;i++){ の行で101個目にアクセスしてるだろ。

for(i=0;i<100;i++){ が正解

552:デフォルトの名無しさん
07/10/29 22:24:32
実験データは正数だけかな?
配列に入れる必要性がわからんけど後でプログラムを拡張するのかな

553:aho
07/10/29 22:25:39
>>550
ばれたか。
やるな、おぬし!

554:プリンがー
07/10/29 23:00:39
1から1000までの数値の中で、2または3の倍数でかつ4の倍数でないものを
出力するプログラムを書きなさい。

#include <stdio.h>
int main (void)
{
int i;

for(i=1;i<=1000;i++){

if(i%2=0||i%3=0){

if(i%4!=0){
putchar('\n');
}
}
}
return(0);
}

これであってますか?

555:デフォルトの名無しさん
07/10/29 23:02:21
memcpy(input,output,size<<1);

//array copy
for(i=0; i < (size<<1); i++)
output[i] = input[i];

すみません、この二つの違いを教えてください。
初めに下のほうで計算していたら望む結果が出てこなくて
上のとおりやったら出来ました…

同じことをやっていると思ったのですが、どう違うのでしょうか

556:デフォルトの名無しさん
07/10/29 23:03:12
if ((i % 2 == 0 || i % 3 == 0) && (i % 4 != 0))

557:デフォルトの名無しさん
07/10/29 23:04:33
>>554
回したら、ものすごい数の改行が出た。

558:デフォルトの名無しさん
07/10/29 23:07:51
>>555
outputとinputの型によって差がでるんじゃないかな

559:プリンがー
07/10/29 23:08:15
>>554
訂正

#include <stdio.h>
int main (void)
{
int i;

for(i=1;i<=1000;i++){

if((i%2==0||i%3==0)&&(i%4!=0)){
putchar('\n')
}
}
return(0);
}

これでいいでしょうか??


560:デフォルトの名無しさん
07/10/29 23:09:29
×putchar('\n');
○printf("%d ", i);

561:プリンがー
07/10/29 23:12:32
>>560
ありがとうございます。


562:デフォルトの名無しさん
07/10/29 23:13:39
あってませんよ

563:デフォルトの名無しさん
07/10/29 23:15:45
>>558
どちらもint型のポインタ(1次元配列)なのですが。

単に求めた結果が出ればいいだけなら、これでいいのですが
初めのソースが合ってると信じて、違う原因がわからないのは自分でも納得がいかないので

564:デフォルトの名無しさん
07/10/29 23:15:54
テキストファイルに aあ と書いてそれを16進形式でテキストファイルに出力すると、
61 82 A0 0D 0A となりました。
ここからこの数を使って aあ と新たなファイルに表示させたいのですが、
a は出力できるのですが あ のやり方がわかりません。
どうしたら日本語の あ が出力できるんでしょうか。

ちなみにaは
char temp[50]
char moji[]="61";
strcpy(temp,"0x");
strcpy(temp,moji)
long int aa=strtol(temp,NULL,16);
fprintf(file,"%c",aa);
見たいな感じで出力しました。

565:デフォルトの名無しさん
07/10/29 23:22:43
>>564
char tmp[10];
tmp[0] = (char)strtol("82", NULL, 16);
tmp[1] = (char)strtol("A0", NULL, 16);
tmp[2] = '\0';

printf("%s", tmp);


566:デフォルトの名無しさん
07/10/29 23:23:54
>>555>>563
その二つはinputとoutputがchar型配列でない限り、違う結果になる


>memcpy(input,output,size<<1);
ここの第三引数は、バイト単位でのサイズを指定する

>for(i=0; i < (size<<1); i++)
>output[i] = input[i];
こっちで指定するのは、配列の要素数

567:デフォルトの名無しさん
07/10/29 23:25:46
>>564
printf("%c%c%c",0x61,0x82,0xA0);

568:デフォルトの名無しさん
07/10/29 23:26:00
>>563
memcpyのsize<<1はバイトで
for文のsize<<1はint型(4バイト?)分になるんじゃないかな?
試してないから間違ってるかもしれないけど

569:デフォルトの名無しさん
07/10/29 23:31:11
>>566 >>568
なるほど。。。と違いはわかったのですが
memcpyだとinputからoutputに何がコピーされているのか混乱してきました。

sizeはint型でinput分の要素数を表しています。
0 1 2 3 4 5 6 7 の要素が入っていて

それを計算したものをoutputに出力させているのです
for文の方をmemcpyと同じように働かせるにはどうしたらよいのでしょうか

570:デフォルトの名無しさん
07/10/29 23:31:45
>>380
入力に何を与えたら何が出力されるのか書いてくれれば考えてみる
>>524 >>526 を読んだが訳分からんかった

検索のキーとなるのは64バイトの内最初の固定 n バイトだけ?(>>524 だと n=16)
1行64バイトって改行文字を含まずに64バイト?
読み込むファイルは検索途中で書き換えられる?

571:デフォルトの名無しさん
07/10/29 23:36:06
>>569
要素数を表してるのになんでビットシフトしてるの?

572:デフォルトの名無しさん
07/10/29 23:39:32
フーリエ変換かなんか 2^n 要素数のアルゴリズムじゃね?

573:デフォルトの名無しさん
07/10/29 23:40:24
>>565>>567
どちらもできましたありがとうございます。


574:デフォルトの名無しさん
07/10/29 23:40:48
>>571
階差数列や漸加式をイメージしてもらいたいのですが
長さの半分の式を移していくという処理をやっています。

なんか頭が熱持ってきました。。。

575:デフォルトの名無しさん
07/10/29 23:41:57
>>572
そうです、2^nの式です。。。わかるものなのですね



576:デフォルトの名無しさん
07/10/29 23:44:48
ソースが全部貼り付けられてるわけじゃないからあくまで推測だが、
sizeが正しく使われてるか確認した方がいいと思う。

577:デフォルトの名無しさん
07/10/29 23:48:59
>>576
for(i=0; i < length<<1 ; i++)
input[i] = output[i];

…こうやったら、望む値が出てきました。。。。なぜ。。。。。
計算させるところを勘違いしていたのか、わけがわからなくなってきました。。。。


578:デフォルトの名無しさん
07/10/29 23:50:41
>>569
なんかよく分からんが例として

int a[10],b[10],size=10,i;
//何らかの代入処理
memcpy(b,a,size * sizeof(int));
//↑は↓と等価
for(i=0; i < size; i++)
b[i] = [i];

こんなふうにする
あと今気付いたが、memcpyの第一引数と第二引数が反対になってるよ
第二引数がコピー元で、第一引数がコピー先
代入文と同じ順序ね

579:デフォルトの名無しさん
07/10/29 23:55:00
>>578
ありがとうございます。ちょっと頭冷やして、ソースと頂いたレスを理解します。

ほんとなんかすみません

580:デフォルトの名無しさん
07/10/30 03:23:33
C言語初心者で、教えて欲しいのですが
sin^2(x)
(サインの二乗(x))
はどのようにプログラムに書けば良いのでしょうか?

581:デフォルトの名無しさん
07/10/30 03:34:41
>>580
sin(x)の2乗ということですよね

#include <math.h>

sin(x)*sin(x) /* sin(x)の2畳 */

sin関数を2階呼ぶのが面倒なら
double y;
y = sin(x);
y*y

582:581
07/10/30 03:36:22
pow関数を使うという手もありますが
2乗なら掛け算で十分

583:580
07/10/30 03:41:03
>>581
こんなにも遅い時間にありがとうございます。
プログラミングもですが、数学もやり直してきます

584:デフォルトの名無しさん
07/10/30 03:46:08
2倍角の公式の方が速い

585:デフォルトの名無しさん
07/10/30 03:51:51
exp( ix ) = cos(x) + i sin(x) だから2乗して実部を比較すると

cos(2x) = cos^2(x) -sin^2(x) となる

cos^2(x)  + sin^2(x) = 1 なので

1 - 2 sin^2(x) = cos(2x)

これより、(1+ cos(2x)) / 2 が求める値である

586:580
07/10/30 04:01:36
>>585
さらなる補足をありがとうございます。数学の教科書見て勉強してます


587:デフォルトの名無しさん
07/10/30 12:19:41
>>585
>>581 より計算量増えてね?

588:デフォルトの名無しさん
07/10/30 12:48:58
>>587
そもそも移項で間違ってる

589:デフォルトの名無しさん
07/10/30 12:55:03
sin^2(x) == (1-cos(2x))/2だな

>>587
・関数呼び出しが一回でいい(cf.sin(x)*sin(x))
・一時的な代入がいらない(cf.y=sin(x);y=y*y;)
ってことでこの方法が一番いいかと

590:デフォルトの名無しさん
07/10/30 12:58:06
計算増えるっていっても2倍と1/2と足し算だからもとのよりはいいんじゃね?

591:デフォルトの名無しさん
07/10/30 13:26:48
おまえら、数値計算の勉強をやり直せ。
1 - cos(2x) なんて、 x = 0 の近辺で桁落ちして使い物にならないぞ。

double t = sin(x);
double s2x = t * t;
しか、ありえない。


592:デフォルトの名無しさん
07/10/30 13:34:29
桁落ちw

593:デフォルトの名無しさん
07/10/30 15:50:05
->
これはどういう意味があるのでしょうか


次ページ
最新レス表示
スレッドの検索
類似スレ一覧
話題のニュース
おまかせリスト
▼オプションを表示
暇つぶし2ch

5164日前に更新/251 KB
担当:undef