【初心者歓迎】C/C++室 Ver.102【環境依存OK】

■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
垢版 |
2017/11/04(土) 16:33:35.07ID:NYxCuvMY
エスケープシーケンスやWin32APIなどの環境依存なものもOK
そのような質問は必ず環境を書きましょう
半角空白やタブでのインデントはスレに貼ると無くなります

コードを貼れる所
http://codepad.org/
https://ideone.com/

前スレ
【初心者歓迎】C/C++室 Ver.101【環境依存OK】
https://mevius.5ch.net/test/read.cgi/tech/1500329247/
2017/11/07(火) 17:07:50.15ID:Zpoup5pM
int str2i( const char *s, size_t n )
{
    int v = 0;   
    while ( n-- ) {
        char c = *s++;
        if ( c == '??0' ) break;
        if ( '0' <= c && c <= '9' ) v = v * 10 + ( c - '0' );
    }
    return v;
}
2017/11/07(火) 17:17:37.91ID:jEe4bM6y
片山以外に文字化けするブラウザ使ってる奴いるのか
あとnull文字って初心者が背伸びしてる感じがして微笑ましいな
2017/11/07(火) 17:31:27.26ID:Zpoup5pM
ソフト歴35年ですが
2017/11/07(火) 17:50:48.44ID:6NdbJPOz
PC(プロセスコントローラー)のプログラマーですが何か?
ってのは居たが
2017/11/08(水) 01:37:38.03ID:MEe7IGP8
isdigitが関数コールな処理系ってあるのか?
ここって車輪の再発明好きな人多いのかね
2017/11/08(水) 02:06:05.60ID:TZ5JAUzS
isdigitは、ロケールの関係で遅くなる可能性があるはず。256バイトの配列を使うのが最速だ。
2017/11/08(水) 03:38:56.63ID:xvDlz0If
ちょっとした演算よりメモリアクセスの方が遅いこともあるよ。
本当に配列が最速?
(試したわけではないので配列が最速かもしれない……)
2017/11/08(水) 06:19:22.66ID:u4hO2YM0
配列www
ないない
仮に>>23より速くても
2017/11/08(水) 06:36:16.44ID:u4hO2YM0
int str2i( const char *s, size_t n )
{
    int v = 0;   
    while ( n-- ) {
        char c = *s++;
        switch (c){
        case '¥0':
            goto brk;
        case '0': case '1': case '2': case '3': case '4':
        case '5': case '6': case '7': case '8': case '9':
            v = v * 10 + ( c - '0' );
            break;
        }
    }
brk:
    return v;
}
2017/11/08(水) 06:36:55.45ID:u4hO2YM0
これのがまだマシ
2017/11/08(水) 06:40:10.32ID:u4hO2YM0
普通に>>23でいい
2017/11/08(水) 09:37:48.99ID:kEoXgNLC
gotoとかwwww
って思った人いるんだろうか
2017/11/08(水) 10:35:10.40ID:FLS9cqpb
switch である必要ないな
2017/11/08(水) 11:33:23.57ID:2d9va5Xh
>>34
ああ、素人はgoto嫌うよな

>>35
もちろん必要は無い
テーブルよりは色々な面でマシってだけ
普通に if ( '0' <= c && c <= '9' ) で良い
一目で意味がわかるし高速
2017/11/08(水) 12:27:45.50ID:2VVChtYT
&&って条件分岐が入るけど、本当に高速?
2017/11/08(水) 12:44:08.80ID:FLS9cqpb
そこはctypeで判定だね
2017/11/08(水) 13:01:31.63ID:2VVChtYT
>>37
とおもってアセンブリ吐かせてみたら、すごかった。
48引いた上で、符号なしで10未満か判定してるので、
余分な条件分岐してなかった。
2017/11/08(水) 13:02:27.97ID:xvDlz0If
>>37
&& では分岐しなかった。
'0' <= c && c <= '9' を clang で -O3 付きでコンパイルしてみたらこうなった。

addl $-48, %eax
cmpl $10, %eax
setb %al

賢いな!
直後に分岐するなら結果をレジスタに書き込む必要はないから実質的に二命令だ。
2017/11/08(水) 13:37:52.71ID:TZ5JAUzS
俺の知識も時代遅れになったな。シンプル伊豆ベスト。
2017/11/08(水) 18:14:28.55ID:xvDlz0If
もっと >>40 を高速化できないかと思って考えてみたが、
'0' を引くんじゃなくて 0x30 と xor を取ってから 10 より小さいか比較するっていうのでもいける。

ただ、最近はビット演算が算術命令より速いとも限らないみたいなんだよね〜
2017/11/08(水) 18:22:33.84ID:8jdacwiA
>>42
まるで昔は速かったかのようだ
2017/11/08(水) 18:37:11.31ID:xvDlz0If
>>42-43
Z80 ですら足し算と XOR は 1 クロックだったわ。 スマソ
2017/11/08(水) 18:43:03.66ID:u4hO2YM0
ん?
8086はビット演算の方が速いぞ
2017/11/08(水) 18:57:26.39ID:GPQLPiKH
>>21
> 仕様として「両方で停止は問題ない」よな?
相談者でないとわからん
途中に'\0'があるケースについては書いてないから

> そもそも相談者の仕様がおかしい
それはお前が決める話じゃない
2017/11/08(水) 18:59:47.82ID:GPQLPiKH
>>22
> ショートサーキット前提の記述をよしとするかどうかはわからん
if(p != 0 && *p != '\0')
みたいなのは普通に書かない?
2017/11/08(水) 19:03:40.31ID:CwKlKlOQ
>>47
俺は書くけど それを"普通"とまで言い切ってしまって良いという自信はない
2017/11/08(水) 19:14:43.13ID:u4hO2YM0
>>46
わからないならだまってれば
正確な要求仕様がわからない事くらい誰でもわかる

両方でとまる関数は片方で止まる関数の機能を含むので
問題になる場面は普通は考えられない
質問に書いてない、文字列の途中にNULL文字とか
いうアホな事を心配しない限り
2017/11/08(水) 19:18:16.64ID:u4hO2YM0
全角数字の方がまだ可能性がある
2017/11/08(水) 19:42:17.13ID:GPQLPiKH
>>49
こういう思い込みの激しい奴が要らんバグを作り込むんだよな...
2017/11/08(水) 19:51:21.87ID:CyIcapPx
isdigit関連で性能測ってみた。
環境: Core i7-2600 / gcc 6.4 (-O2)
rund() & 0xff の値で条件分岐して、真ならさらに rand() を呼ぶ、を10億回ループ。
条件式はASCII前提。

数字: 条件式 < int配列ルックアップ < isdigit
英字: 条件式 <= int配列ルックアップ < isalpha
数字英字: int配列ルックアップ < 条件式 < isalnum

ロケールの影響か、isalphaなどはisdigitより遅い。
char配列ルックアップはint配列より遅い。
奇妙なことに、配列ルックアップでも、数字だけより、英字も入ってくると遅くなる。なぜだ。
5352
垢版 |
2017/11/08(水) 19:54:52.03ID:CyIcapPx
あ、ごめん、rand() 呼ぶ分、数字 < 英字 < 英数字の順で遅くなるの、当然だった。
2017/11/08(水) 20:30:53.41ID:u4hO2YM0
最速なら前スレの>>995>>997

>>997は演算の依存性が高いので
>>995の方が少し速いかな?
まあコンパイラや環境依存でしょう

x64前提なら、
64bit一気に持ってきて偶数奇数桁に分けて、
LEAで5倍してシフトして足すとか
AVXで乗算してから水平演算とか
色々と考えられるけど
まあ一応このスレのC言語の範囲で
2017/11/08(水) 20:49:19.11ID:QAR8Spec
このスレの結論はこれか。
10000*a[0]+10000*a[1]+1000*a[3]+100*a[4]+10*a[6]+a[7]-5333328;

これより速くする方法あるのか
2017/11/08(水) 21:08:26.39ID:CwKlKlOQ
何時の間に判定せずにすむようになったんだ
2017/11/08(水) 21:11:25.51ID:u4hO2YM0
前スレの>>997が質問者だから
フォーマットは固定と思われる
2017/11/08(水) 21:12:49.95ID:u4hO2YM0
さすがに '0' * 111111 をコンパイル時に計算しないコンパイラは無いと思うので
このままで良い気はする
当然こちらの方が意味が分かりやすい
2017/11/08(水) 21:14:04.15ID:u4hO2YM0
( ) を色々とかえて時間を測ってみたけどほとんど同じ
やっぱりLEAを多用してる
VS2017の64bit Releaseビルドの場合
2017/11/08(水) 21:39:10.43ID:u4hO2YM0
VPMOVZXBD xmm0, a
VPMADFWD xmm0, xmm0, [掛け算テーブル]
VPHADDD xmm0, xmm0, xmm0
VPHADDD xmm0, xmm0, xmm0
2017/11/08(水) 21:40:02.30ID:u4hO2YM0
AVXが使えるならこれ
2017/11/08(水) 21:42:47.06ID:u4hO2YM0
微妙に間違った
メモリが連続してれば複数同時に出来る
連続してなくても複数同時にやった方が速い
2017/11/08(水) 21:43:54.20ID:YMDhJx7T
>>29でメモリアクセスに言及されてる話の流れの中で
10億回ループがいちいちキャッシュクリアされてるのかが気になる
2017/11/08(水) 21:49:19.34ID:u4hO2YM0
普通はキャッシュに入ったままだが、
処理次第で可能性が無いことはない
他のキャッシュを汚染する可能性もある
HTTなどでは特に

他に良い方法が有るのにわざわざ面倒なテーブルにする意味がわからない
2017/11/10(金) 07:46:10.46ID:F5y7yLWH
std::vector<std::string>からchar*const[]を作成するいい方法ってないですか。
newするしかないですかね。
2017/11/10(金) 10:26:44.91ID:TvDreq2K
>>65
vector<char*> に各要素 s の &s[0] を入れて済むなら new は要らなさそう。
2017/11/10(金) 20:15:55.61ID:MIqJX5DT
>>66
まあどうみても内部でnewしてるんだろうけど
2017/11/10(金) 21:01:13.10ID:UsP+TtJI
クラスの概念がわかりません
2017/11/10(金) 21:19:13.94ID:lLb0QJod
構造体みたいなもの
2017/11/10(金) 21:39:23.58ID:x1hu0efq
>>68
クラスは構造体に関数を追加したようなもの。
クラス内部の関数はメソッドと呼ばれる。
メソッドからは、クラスのデータとメソッドを参照できる。
データとメソッドのそれぞれの項目をクラスのメンバーと呼ぶ。
クラスの実体はインスタンスと呼ばれる。メソッドからは、thisポインターにより、クラスのインスタンスを参照できる。
メンバーは、public:、protected:、private:によってアクセスを制御できる。アクセスできないメンバーを参照するとコンパイルエラーになる。
2017/11/10(金) 22:11:59.59ID:x1hu0efq
class A
{
int a;
};
と書くとA::aは、privateになる。構造体と同じアクセスにするには
class A
{
public: int a;
};
と書かないといけない。このようにクラスのデフォルトのアクセスはprivateになり、構造体はpublicになるという違いもある。
2017/11/10(金) 22:14:05.73ID:x1hu0efq
クラスはコンストラクタと呼ばれる特殊なメソッドがあり、インスタンスの構築に使われる。
また、インスタンスが破棄されるときに、デストラクタという特殊なメソッドが呼ばれる。
2017/11/10(金) 22:17:22.95ID:x1hu0efq
コンストラクタの例。
class A
{
public:
int m_a;
A(int a) {m_a = a + 1; }
};

int main() {
A a(2);
printf("%d\n", a.m_a);
}
2017/11/10(金) 22:19:15.61ID:x1hu0efq
別のコンストラクタの例。
class A {
public: int m_a;
A(int a, int b) : m_a(a + b) { }
};
int main() {
A a(2, 3);
printf("%d\n", a.m_a);
}
2017/11/10(金) 23:02:09.42ID:4kUQXTj6
そんなの説明してやらなくてもネット上に無数の解説があるだろ。
ちゃんとした説明を読んで理解できないなら掲示板で短い説明読んだってわかりゃしねーよ。
2017/11/10(金) 23:14:40.61ID:x1hu0efq
>>75
情報が多過ぎて迷子になってるんじゃないか。マニュアル読め、規格票読め、で終わればいいのだが。
2017/11/10(金) 23:21:03.62ID:YANYSepQ
そう思うならなぜ現在地を聞く前に世界地図を渡すのか
2017/11/10(金) 23:32:23.63ID:2wx3Dyqu
>クラスは構造体に関数を追加したようなもの

こういうアホってどこにでもいるんですね
2017/11/10(金) 23:40:07.53ID:qCTAOUdD
>>78
その理解で8割がたOKだと思うのだが、何が問題なの?
2017/11/10(金) 23:46:33.90ID:4kUQXTj6
>>76
チュートリアルだってたくさんあるじゃん。
2017/11/11(土) 00:24:04.64ID:5MIg+SHx
>>79
クラスがわからんやつにこんな説明しても通じないだろ
2017/11/11(土) 00:49:17.73ID:1PUme0lw
山田さんってどんな人?と聞かれて
原子の集まりだよ。って答えるようなもの
形式的にウソじゃあないんだが
そこじゃないだろっていう
2017/11/11(土) 02:47:19.31ID:fW1Ux/Kl
純粋にC++のクラスそれ自体の概念というなら
C言語(ベース)でのオブジェクト指向プログラミングをサポートするために言語機能で用意された部品
オブジェクト指向プログラミングにおけるオブジェクト、オブジェクトの状態、
メッセージの送受信、メッセージを受けたときの振る舞いといった概念を具体化した仕組みの一例
2017/11/12(日) 13:22:39.97ID:134uacB+
記憶クラスについての質問の可能性
2017/11/12(日) 23:51:21.74ID:nDRVLcBe
実のところはOOPを知らないからクラスをどう使えばいいのかわからない/
他人の真似でなんとなく使ってるけどなぜクラスを使うのかがわからないといったあたりの話だろ
2017/11/22(水) 02:18:46.71ID:jSfISRI4
下手にクラスを説明するやつが多いせいで、コーディング経験なくても理解できる概念的なものだと思われちゃう
クラスは実用あってこそ
2017/11/22(水) 07:58:58.54ID:gxZQPw73
アニマルクラスがわんにゃー鳴くのがオブジェクト指向です
2017/11/22(水) 17:16:56.90ID:ehTxx6H6
メンバ関数を呼び出す際の
「オブジェクトにメッセージを送る」って言い回しも
C++だと分かりにくいね。

この表現がしっくりくるプログラミング言語というか
環境もあるのだろうけど。
2017/11/22(水) 17:52:35.50ID:NgxFNsMl
>>88
そういうのをベタで実現しているOO言語はないかな…
2017/11/22(水) 18:04:22.80ID:evJ3QlJY
smalltalkは?
2017/11/22(水) 20:55:50.24ID:6XHR1ElK
>>90
あれも結局、関数(メソッド)の動的なコールをそう呼ばせてるだけ
同じSmalltalkでもSmalltalk-72までさかのぼるとメッセージ送信と呼べなくもない仕組みにはなっているけど
それでもオブジェクトに(メッセージを)「送る」というよりは(トークン列を)「流し込む」って感じかと

まあ、ともあれC++の「オブジェクト指向」を説明するときには「メッセージを送る」とかはすっかり忘れていいよ
そもそもC++の設計者の提唱するオブジェクト指向は「抽象データ型(端的にはユーザー定義の型)」を
Simulaという言語から拝借した「クラス」という言語機能で実現することが主軸のアイデアなので
http://www.stroustrup.com/whatis.pdf
2017/11/22(水) 21:08:20.60ID:Rn9KsJdK
言語の意味論とそれを実現するメカニズムは別物だから、
仕組みがどうなっているかから考察するのは無粋だと思うけどなぁ。

まあ C++ は低水準レイヤでの仕組みを意識せざるを得ない、
意味論とメカニズムが不可分なデザインではあるから概念としてのメッセージ指向よりも
メカニズムに意識が引きずられてしまうというのは確かにあるかもしれない。
2017/11/22(水) 21:21:24.87ID:3PrpHuiB
メソッド呼び出しってメッセージパッシング感すげー出てない?
2017/11/22(水) 21:28:03.86ID:+hB2MqUt
>それでもオブジェクトに(メッセージを)「送る」というよりは(トークン列を)「流し込む」って感じかと

違いがわからないw
2017/11/22(水) 22:33:35.60ID:2YdhEIzW
>>93
メッセージパッシング言うなら、何かが静的に決定してる時点で興醒めだよ
http://wiki.c2.com/?AlanKayOnMessaging
2017/11/22(水) 23:02:11.68ID:XGz0BDt0
>>95
C++のポリモーフィックなメソッドは動的ディスパッチだろう
2017/11/22(水) 23:09:00.03ID:NgxFNsMl
>>91
>抽象データ型
これがすべてなのに、どうしてメッセージ駆動の話が今でももちきりなのだろうか?
2017/11/23(木) 08:26:45.55ID:Qr4pYIOt
>>96
C++に「動的なものは何もない」という主張ではなく
「静的に決まる何かが一つでもある」時点でそれをメッセージングに例えるのは興醒めという意味

少なくともケイは彼のOOPにおけるメッセージングを「遅延結合の徹底」の目的で提案している
http://d.hatena.ne.jp/katzchang/touch/20080807/p2
「私が考えるOOPはメッセージング、状態処理のローカルでの保有・保護・隠蔽、
そして全ての物に対する強力な遅延束縛、これだけだ。
これはSmalltalkとLISPだけが実現できている。他のシステムでも可能かもしれないが、私は知らない。」

つまるところ、これはすなわち、SmalltalkやLispみたいな変態言語でもなければ、
(あるいはアクター機構のように、並列化を意識して本当にメッセージを送るのでもなければ)
無理して「メッセージパッシング」なんてたとえる必要は無いんやで、という話でしかない
2017/11/23(木) 08:27:38.45ID:Qr4pYIOt
>>97
まったくもってその通り
2017/11/23(木) 14:15:04.16ID:76J8bh8G
Cのキャストについて教えてください

int a,b;
long c;

の条件下で、a+b 、a*100+b*100(a*100、b*100のどちらもlong型になる)
がそれぞれlong型の解になるような場合のキャストとしては

1 c=(long)a+b;
2 c=(long)a+(long)b;

3 c=(long)a*100+b*100
4 c=(long)a*100+(long)b*100

とそれぞれ、どの記載が正しいのでしょうか?
2017/11/23(木) 14:19:02.83ID:5K7m7Mmt
>a*100、b*100のどちらもlong型になる

intでは表せなくてlongが必要
って意味なら3以外
2017/11/23(木) 14:20:46.83ID:76J8bh8G
ありがとうございます。
1と3は似ていますが1はa,bそれぞれキャストされるが
3ではb*100はキャストされずint型で計算されてしまう、ということなのですね
2017/11/24(金) 16:57:14.87ID:L5ESShiZ
よろしかったら教えてください

  if(a==0){ }

と記述するのにfor文では
  
  for(i=0;1<100;i++){}

と書き、for(i==0;i<100;i++){}

と書かないのはなぜでしょうか?(==の使い方)
2017/11/24(金) 17:05:28.65ID:ELoh0Abo
>>103
代入と比較は違う。
105デフォルトの名無しさん
垢版 |
2017/11/24(金) 17:07:52.77ID:QRhLqwOG
スーパー初心者か?
forでも書いてもいい。だが意味がないか低い。
「=」は代入だが「==」は代入でない。
2017/11/24(金) 17:08:50.74ID:L5ESShiZ
片山先生、ありがとうございました!
そういうことなのですね。理解できました、いつもありがとうございます!
2017/11/24(金) 17:38:47.92ID:lG8HVUMw
わかってる人にとってはクソみたいな質問だけど、
数学だと代入 (定義) するっていうのと等しいっていうのは区別がはっきりしないので、
そういうメンタルモデルで考えてると混乱しちゃうってのはわからんでもない。

とはいうものの、よっぽど出来の悪い入門書でもそこらへんわからんようなのは無いと思うんだが、
どういう学び方をしてるんだかちょっと疑問。
2017/11/24(金) 17:51:57.71ID:L5ESShiZ
なんかすみません
ネットで優しそうなサイトで進めてます
2017/11/28(火) 12:50:21.53ID:bi1wDt8X
数学のイコールには比較(の結果等しい)の意味しかないだろう
Pascalみたいに代入が:=なら良かったのに
2017/11/28(火) 12:57:44.05ID:cL+Re6N7
プログラムを記述する際、等しいかを比較するより、代入のほうが頻度が高いから
Cでは多く入力するであろう代入側を 1文字にして そうでない側を 2文字にした
って聞いたことがある
2017/11/28(火) 13:22:50.66ID:8wOk3LC1
Fortranだって代入は=だから、Cで採用されたのも仕方ない

とはいえ、文字数ごときにこだわらずに、:=を採用してくれていたらタラレバ
2017/11/28(火) 13:44:24.58ID:9QEYjjOS
力添えを頂きたい。
SunAwt系のソフト内で表示されているテキストを取得したいんだが、尻尾も掴めず困り果て、どうすれば良いか全く分からない状態。
何かヒントを頂けないだろうか。
2017/11/28(火) 13:50:31.60ID:1OfFiaid
>>112
別のプロセスから取得するって意味?
2017/11/28(火) 18:08:18.05ID:9QEYjjOS
>>113
YES。
別プロセスからテキストを取りたい。
他の例えばIEやハンドルが取れる様なソフト内の文字ならgettextやcom操作で取ったりできるがSun系のソフトは同じ様にはいかず、メモリを読むのかどうすればいいのか、知識が足りなくて検索も上手に出来ず...頭打ち状態。
何か足掛かりになる物を教えて頂きたい。
2017/11/29(水) 00:32:03.31ID:/GAULuFW
>>114
試したことないけどこれは?
http://www.oracle.com/technetwork/articles/javase/index-jsp-136191.html
2017/11/29(水) 13:08:28.50ID:GlJ85cMo
#include<stio.h>
int main(){
int i,num[5];

for(i=0;i<5;i++){
printf("***\n");
scanf("%*c%d"&num[i]);
}
}

実行し、num[]に、10、20,30,40,50と入力すると
num[0]の値は0、num[1]は20、その後50まで代入されてます
num[0]に10が代入されないのは何故なのでしょうか?
2017/11/29(水) 13:26:13.79ID:NrhyqkWd
>>116
"%*c"のせいじゃね
2017/11/29(水) 13:36:20.41ID:GlJ85cMo
>>117
そうでした。ありがとうございました。
2017/11/30(木) 14:49:53.66ID:t+LxFq0J
テフ?
2017/12/01(金) 03:20:07.32ID:VClmrWfc
boost::qiでマルチバイト文字を扱うにはどうすればいいんですかね
2017/12/01(金) 12:48:46.21ID:UzEJxhfp
5人の生徒に3教科のテストをし、その点数を入力する
入力後、
          テストA  テストB  テストC
 0点〜19点    0人    0人    0人
20点〜39点    0人    0人    0人
40点〜59点    2人    0人    1人
・・・
80点〜100点   1人    3人    2人

と集計する方法に悩んでいます。
どういう考え方が考えられますか?
2017/12/01(金) 13:06:08.20ID:p7Y4uOcI
>>120
char_に替わるパーサー書けばいいんじゃないかね
マルチバイトの最初の文字を認識する自作パーサーをmb1、マルチバイト文字のパーサーをmbcharとして
mbchar = (mb1 >> char_) || char_;
とか?
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。