1 :デフォルトの名無しさん:2011/08/31(水) 18:45:07.04
C言語の*入門者*向け解説スレッドです。

★前スレ
C言語なら俺に聞け(入門編)Part 88
http://hibari.2ch.net/test/read.cgi/tech/1312926287/
★過去スレ
http://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++の宿題片付けます 152代目
http://hibari.2ch.net/test/read.cgi/tech/1312201995/
★C++言語については避けてください。C++対応明記スレへどうぞ
★分からない事をなるべく詳しく書いて下さい。
★ソースコードを晒すと答えやすくなるかもしれません。
  # 抜粋/整形厳禁、コンパイラに渡したソースをそのまま貼ること
  # サイズが大きい場合は宿題スレのアップローダ等を利用してください
★開発環境や動作環境も晒すと答えが早いかもしれません。
★質問者は最初にその質問をした時のレス番号を名前欄に書いて下さい。
★ぬるぽ。

長くなりそうなコードはcodepadに貼り付けてもいいでしょう
http://codepad.org/

33 :デフォルトの名無しさん:2011/09/01(木) 21:07:44.92
つかぬことを伺いますが、下のようにchar配列を初期化をすると、
その配列の次のアドレスは必ず、NULL(\0)で初期化されるのでしょうか?

#include <stdio.h>

int main(void) {
char s[] = {'H','e','l','l','o',',','w','o','r','l','d'};
printf("[%s](%d)\n", s, sizeof(s) );
return 0;
}

これをコンパイル、実行をすると、出力は
>[Hello,world](11)
となり、配列のサイズとしてはNULL終端分のエリアは確保されていないように見えます。
ところが、下のように、配列の次のアドレスに文字を書き込むと、出力は、

int main(void) {
char s[] = {'H','e','l','l','o',',','w','o','r','l','d'};
char *p = s;
*(p+11) = 'A';
printf("[%s](%d)\n", s, sizeof(s) );
return 0;
}

>[Hello,worldA?Z$a[$a](11)
と'A'以降のゴミが出力され、'A'を書き込んでいた部分に'\0'が書かれていたように見えます。
また、printf()はその配列の次のアドレスまで読んで、'\0'の前まで出力していたように見えます。

40 :デフォルトの名無しさん:2011/09/01(木) 22:28:22.21
>>33の定義だと要素は11個しか用意してないから、
char s[11];

41 :デフォルトの名無しさん:2011/09/01(木) 22:34:06.50
>>40
その考えが正しいなら、sにはナル文字が入らないことになる。
このパターンはコンパイラでナル文字までの領域を確保するJK。

43 :デフォルトの名無しさん:2011/09/01(木) 22:41:27.33
>>41
char s[] = {'H','e','l','l','o',',','w','o','r','l','d'};
これは、
char s[] = {72,101,108,108,111,44,119,111,114,108,100};
これと同じ

44 :デフォルトの名無しさん:2011/09/01(木) 22:46:49.88
char s[] = {'H','e','l','l','o',',','w','o','r','l','d','\0','\0'};
これならいける

45 :デフォルトの名無しさん:2011/09/01(木) 22:53:14.76
>>43
char s[] = {'H','e','l','l','o',',','w','o','r','l','d'};
これは、
char s[] = {72,101,108,108,111,44,119,111,114,108,100};
と同じだし、
char s[] = "Hello,world";
と同じ。

121 :デフォルトの名無しさん:2011/09/03(土) 14:05:18.38
main関数とtasizan関数は別々だ。
add=tasizan(a,b); ここでtasizan関数を呼び出している。
tasizan関数はanswerを返す
よってaddにanswerが代入される

122 :デフォルトの名無しさん:2011/09/03(土) 14:12:10.76
>int tasizan(int x,int y){

最初のところに int ってあるだろ、これは関数tasizanがint型の数値を返すという事を示している。
関数tasizan 内に
return answer;
ってあるだろ。これが返す値だ。



123 :デフォルトの名無しさん:2011/09/03(土) 14:24:04.15
>121
>122
return answerでanswerという変数?をtasizan関数に代入するという意味でいいでしょうか?
そしてどこかでtasizan関数を呼び出した?時にanswerを表示するでいいですか?
あともうひとつだけmain関数は変数abの値をどこでtasizan関数に渡しているんでしょうか

124 :デフォルトの名無しさん:2011/09/03(土) 14:30:08.92
>>123
見ろ
http://www9.plala.or.jp/sgwr-t/c/sec11.html

129 :デフォルトの名無しさん:2011/09/03(土) 15:06:56.51
>>124
あぁ、ダメになるサイトだ。

130 :デフォルトの名無しさん:2011/09/03(土) 15:11:43.75
ポインタもアレだが構造体がワケワカラン
構造体の配列さっぱりです

>>129
ダメになっちゃうの?

131 :デフォルトの名無しさん:2011/09/03(土) 15:14:38.63
>>130
間違いが書かれているから指摘したら、切れられた。
更に指摘したら、言い訳が掲載された。
読んだ人がダメになるかどうかは、読んだ人次第。

214 :デフォルトの名無しさん:2011/09/05(月) 23:27:21.15
文字列を8文字のブロックにわけて数値化する方法を探しているんだけど、
有名なやつとかある?

218 :デフォルトの名無しさん:2011/09/06(火) 00:06:00.29
>>214
charポインタが指す内容をlong longで型キャストしてやりゃいいんじゃねぇの?

239 :デフォルトの名無しさん:2011/09/06(火) 18:17:07.89
マルチポストは嫌われるって、知らんのかな。。。

結果的には適切なスレ見つけて、一箇所で聞いた方が教えてもらえるんだよ


242 :デフォルトの名無しさん:2011/09/06(火) 18:37:53.79
>>239
マルチポストがばれない限りはマルチポストのほうが回答がつく確率は高いという話だと思う
嫌われないなんてことは誰も書いてないかと

324 :デフォルトの名無しさん:2011/09/08(木) 13:52:21.24
この流れなら質問できる!

MacのXcodeで勉強しているんですが
インクリメントのタイミングが意味不明なんで教えて下さい

int a=1,b=1;

printf("a=%d,%d,%d�\n",a,++a,a);
printf("b=%d,%d,%d�\n",b,b++,b);

アウトプットされた答えが

a=2,2,2
b=2,1,2

b++が1なのにソレより前にあるbが2になるのは何故でしょうか
同様に++aより前にあるaが2になるのも謎なんですけど
仕様と言われちゃうと仕方ないけど寂しいです
お願いします

355 :デフォルトの名無しさん:2011/09/10(土) 00:05:28.51
wikipediaのscanfのページのバッファオーバーランを回避する為の方法についての項で
以下のように書いてあります。

>さらに前述の改行コードがストリームに残る問題を考慮すると
>char a[20];
>scanf("%19s%*[^\n]%*c", a);
>となるが、この場合はaに入る文字列が 19バイト以下の場合には、入力ストリームにやはり改行文字が残る。

そこで,

#include <stdio.h>
int main(void){
char a[5];
scanf("%4s%*[^\n]%*c", a);
getchar();
return 0;
}

というプログラムを実行して,scanfの入力時に例えば「12<ENTER>」と入力すると,
上の文章に従えば,aに入る文字列が4バイト以下だから,入力ストリーム上に<ENTER>が残って,
getcharによる入力待ちは無いはずです.
しかし,実際にはgetcharの所で入力待ちになります.

wikipediaの説明が間違っていると思っていいでしょうか.
wikipediaの脚注にあるサイトにも上で引用したことと同じようなことが書いてあります.
そのサイトはソフトウェア開発会社のものなので,そうそう間違ったことは書かれないだろうと思います.
だから,本当に説明が間違っているのか自信が持てません.実行結果は上記の通りなのですが.

357 :デフォルトの名無しさん:2011/09/10(土) 02:44:22.64
>>355
WinVistaの cmd 上と、cygwin端末上で確認したけど、入力待ちにならなかった。
どんな端末で動かしてるの?

396 :デフォルトの名無しさん:2011/09/12(月) 00:59:49.79
VisualStudioの2010ExpressでC++の入門書を使って勉強しようとしています。

しかし、入門書では、コマンドプロンプトでコンパイルする方法で説明されていますが、
VSを使ってコマンドプロンプト方式で勉強する方法がわかりません。
Projectを作成する時にもCLRコンソールアプリケーションというのを選択すると
ソースに以下のような表示が出てしまい、これで、コンソールに表示する状態になっている
ようですが、本に書いてある内容と違います。
本には、以下のようなソースがかかれています
----------------------------
#include <iostream>
using namespace std;
cout << "こんにちは世界";
------------------------------
VS2010には以下のようなソースが表示されてしまいます。
本のような表示で勉強するにはどうしたらいいのでしょうか?
------------------------------------

#include "stdafx.h"

using namespace System;

int main(array<System::String ^> ^args)
{
Console::WriteLine(L"Hello World");
Console::WriteLine(L"Hello World");
return 0;
}

397 :デフォルトの名無しさん:2011/09/12(月) 01:12:07.40
CLR 以外

398 :デフォルトの名無しさん:2011/09/12(月) 01:51:39.39
>>396
それはC++じゃなくてC++/CLRという別の言語にさせられてる
なので、>>397のいうとおり、CLRを禁止する

399 :デフォルトの名無しさん:2011/09/12(月) 05:29:32.16
>>396
C++の話題はスレ違いだろ。
後、基礎的な勉強ならVCよりMinGWやCygwin導入した方が良いな。

400 :デフォルトの名無しさん:2011/09/12(月) 07:06:00.19
>>396
空のプロジェクトを選択


407 :396:2011/09/12(月) 21:43:36.55
>>397
>>398
>>399
>>400

ありがとうございます。
指示通り空のプロジェクトを作ってみたのですが、
ファイルから、ソースコードを追加して、以下の
ようなコードを書いて、デバッグをしてみましたが、
「visual studio2010\Projects\test3\Debug\test.exeを開始できません。」
「指定されたファイルが見つかりません」

と表示されてエラーになります。
これはどうしたらいいのでしょう・・・
コマンドプロンプトみたいな形で勉強することはVSではできないのでしょうか?
-------------------------------
#include <iostream>
using namespace std;

int main()
{
cout << "こんにちは世界";
}
-------------------------------


413 : ◆tr.t4dJfuU :2011/09/12(月) 22:44:05.72
1.VSを起動する
2.ファイルメニュー⇒新規作成→プロジェクト
3.Visual C++→全般→空のプロジェクト プロジェクト名と場所を入れる <OK>
プロジェクト名:test3
場所:...\visual studio2010\Projects
4.ソースファイル→右クリック⇒追加→新しい項目
5.コード→C++ファイル ファイル名を入れる <追加>
ファイル名:test3.cpp
#include <iostream>
6.ビルドメニュー⇒ソリューションのビルド

415 :396:2011/09/12(月) 23:27:31.03
>>413
ありがとうございます。
はじめは言われたとおりにやってもだめだったのですが、
何度か行うと、ヘッダファイルが読み込まれて、うまくいくようになりました。
ただ、ビルドしたあとでデバッグを実行すると、一瞬黒いDOS窓が出て、
チラっとHelloWorldと出ただけですぐに消えてしまうのですが、これは仕方ないのでしょうか?
質問ばかりですみません・・・

428 :デフォルトの名無しさん:2011/09/13(火) 08:52:23.88
配列("array")のアドレスについてお聞かせください。

char array[6] = "Apple";

ここで、printf("%p")で表示すると"array"と"&array"とで表示されるアドレスが同じになります。
"array"と"&array[0]"で表示される値が同じなのはなんとなく理解できるのですが、
"array"と"&array"で表示される値が同じになる理由がよく理解できません。
この二つの表記ってプログラム上どっちを書いても全く同じになるのでしょうか?
よろしくお願いします。


460 :デフォルトの名無しさん:2011/09/13(火) 18:41:07.38
int型の掛け算を1億回するのと、float型の掛け算を1億回するのとでは、速度に差はありますか。どっちが速いですか

463 :デフォルトの名無しさん:2011/09/13(火) 19:04:14.53
>>428

配列のポインタ変換についてのルールは3つ。
??式中の配列名は配列の最初の要素へのポインタとして扱われる
??添え字は常にポインタへのオフセットと同じ
??関数の引数宣言中の配列名は配列の最初の要素へのポインタとして扱われる

474 :460:2011/09/13(火) 21:10:23.99
なんで足し算なんてしてるんだ。意味がわからない。

話はかわって、乱数で、1か??1の乱数で、全部足していくと、できた波形がブラウンノイズになりますか。
とおもってやったら、なったけど、これは変だとおもった。
乱数があるていど周期的ってことだから乱数じゃないよ。っておもった。もし乱数だったら、すごく大きな風になったり、おおきなところで揺れ続けたりすることもあるはずだとおもったから。
そこで、すく乱数な乱数でも波がちゃんと範囲内に収まるように補正することが必要だとおもった。どうやればいいですか。

476 :デフォルトの名無しさん:2011/09/13(火) 21:36:40.12
>>474
すく乱数ってなんですか?

478 :460:2011/09/13(火) 21:54:11.18
>>476
スペルミスしてました
??すく乱数
○すごく乱数です

479 :デフォルトの名無しさん:2011/09/13(火) 21:54:45.36
Linuxのデバイスファイルの扱い方を解説してる
サイトや参考書で良いのあったら教えてください

480 :デフォルトの名無しさん:2011/09/13(火) 22:01:16.03
>>478
凄くスレ違いです。

483 :460:2011/09/13(火) 22:10:17.34
>>479
ここは英語だったです
https://github.com/torvalds/linux/tree/master/Documentation/input

>>480
乱数はC言語じゃないのか…むずかしい(・_;ノシ

583 :デフォルトの名無しさん:2011/09/16(金) 10:51:07.82
質問です10億回ほどループを回すプログラムを更に高速化したいと考えています。

for(int i = 0; i < N; i++){
for( int j = i+1; j < N; j++){
r = sqrt((x[i]-x[j])*(x[i]-x[j]) +
(y[i]-y[j])*(y[i]-y[j]) +
(z[i]-z[j])*(z[i]-z[j]))+0.5;
XY[r] += b[i]*b[j];
}
}

ボトルネックはここなのですが、ここを高速化する書き方はないでしょうか?
x,y,zはdouble, bはintです。

586 :デフォルトの名無しさん:2011/09/16(金) 12:08:30.52
>>583
7% 程度高速化
for(i=0;i<N;i++)
{
double bi, xi, yi, zi, xij, yij, zij;
bi=b[i];
xi=x[i];
yi=y[i];
zi=z[i];
for(j=i+1;j<N;j++)
{
xij=xi-x[j];
yij=yi-y[j];
zij=zi-z[j];
r = sqrt(xij*xij+yij*yij+zij*zij)+0.5;
XY[r] += bi*b[j];
}
}

652 :デフォルトの名無しさん:2011/09/17(土) 17:05:19.97
複数でインクルードしたとき、実体はどこにあることになる?


660 :デフォルトの名無しさん:2011/09/18(日) 00:03:37.62
階乗を求める方法で再帰以外を探しています
目的は並列計算で円周率の計算をする課題があるのですが
再帰では並列化ができそうにないからです
再帰で並列化できる方法でも構いません
何かいいものはありませんか?

685 :デフォルトの名無しさん:2011/09/18(日) 13:06:22.71
>>652
一箇所になればいいんだろ?

688 :デフォルトの名無しさん:2011/09/18(日) 13:10:29.00
>>685
書き換えない同一データがいくつもあるのは無駄だよね?

690 :デフォルトの名無しさん:2011/09/18(日) 18:31:44.33
>>688
だから一箇所になればいいんだろ?

694 :デフォルトの名無しさん:2011/09/18(日) 23:38:49.38
>extern は正直いって使わない。本当に必要なんですか?
初心者は使う必要ない。初心者は。

696 : ◆QZaw55cn4c :2011/09/18(日) 23:53:10.66
>>694
extern を使うメリットは?そんなものあるのですかね?

697 :デフォルトの名無しさん:2011/09/18(日) 23:55:46.48
外部で使ってることの目印になる

698 :デフォルトの名無しさん:2011/09/18(日) 23:58:51.52
>>696
使う必要がない人は、使わなくてもいい。
複数ソースに分割しているときに、
共通設定をグローバル変数においているときは、
多分使いたいと思うだろう。

699 : ◆QZaw55cn4c :2011/09/19(月) 00:03:44.77
>>698
そういう時も、共通なグローバル変数の宣言だけをヘッダに書いて、
そのグローバル変数を使うモジュールだけがそのヘッダを読み込むようにすれば、特に extern はいらないのでは?
グローバル変数の初期化はちゃんとコードとして表現しなければならないのだけれども、むしろその方が好ましいと思います。

>>697
変数名に約束事をつけたほうが、まし。読みやすいし。

703 :デフォルトの名無しさん:2011/09/19(月) 00:22:23.27
>>699
変数の*宣言だけ*するためには extern が必要だよ

704 :デフォルトの名無しさん:2011/09/19(月) 00:30:18.78
変数名に約束事をつけるのは、
コーディングしている人間のためであって、言語仕様ではない。

一人で趣味として作るならともかく、チームでするときは
個人的な好き嫌いでプログラムは書いてはいけない。

709 : ◆QZaw55cn4c :2011/09/19(月) 01:35:33.35
>>703
いや、初期化しなければ省略できる。仮定義は宣言ではない、というのであれば話は別ですが、それは字面の話。
実際の作業はリンカがする点ではなんらかわりない。

>>704
それはそのとおりだと思います。しかし、チームで作成するとき(経験はありませんが)を仮定しても、わざわざ extern を使う利点が想像しがたいのですが。
というか、extern を陽に記述することと、チームで作成することとになんらの相関を見出せないのですが。

extern を使うと、そのグローバル変数の帰属を決めなくてはなりませんが、たくさんモジュール分割すると、その作業で混乱しませんか?

711 :デフォルトの名無しさん:2011/09/19(月) 07:47:48.85
>>709
さすが無職の趣味プログラマが言う事は一味違いますなあ(笑)


http://hibari.2ch.net/test/read.cgi/tech/1314783907/l50人気ブログランキングへ