!extend:checked:vvvvv:1000:512
(新スレ立ての際上記コマンドを2行書き込んでください)
C言語の話題のみ取り扱います C++の話題はC++スレへ
質問には最低限の情報(ソース/コンパイラ/OS)を付ける
数行で収まらないソースは以下を適当に使ってURLを晒す
https://paiza.io/
https://ideone.com/
http://codepad.org/
C11
http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1570.pdf
C99
http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf
http://kikakurui.com/x3/X3010-2003-01.html
C FAQ 日本語訳
http://www.kouno.jp/home/c_faq/
JPCERT C コーディングスタンダード
https://www.jpcert.or.jp/sc-rules/
※前スレ
C言語なら俺に聞け 156
https://mevius.5ch.net/test/read.cgi/tech/1601271690/
VIPQ2_EXTDAT: checked:vvvvv:1000:512:: EXT was configured
C言語なら俺に聞け 157
■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん (ワッチョイ 0345-kMi9)
2021/06/28(月) 11:22:51.50ID:so+vl3vs0635デフォルトの名無しさん (ワッチョイ 1fbd-SDcz)
2021/09/20(月) 19:57:31.48ID:LO5PkHvF0 >>633
前スレより
975 デフォルトの名無しさん (ワッチョイ b363-19dE) sage 2021/06/21(月) 23:06:35.04 ID:jHz8GYW10
// b.c
int b[] = {123, 456};
// a.c
#include <stdio.h>
int a[] = {123, 456};
int main()
{
extern int *b;
printf("val b\n");
printf("%d\n", *(b + 1));
// printf("val a\n");
// printf("%d\n", *(a + 1));
return 0;
}
こういう分割ソースをコンパイル、リンクして実行すると、何も表示無しで終了する
デバッガー使って実行してみると、SEGVになってる
前スレより
975 デフォルトの名無しさん (ワッチョイ b363-19dE) sage 2021/06/21(月) 23:06:35.04 ID:jHz8GYW10
// b.c
int b[] = {123, 456};
// a.c
#include <stdio.h>
int a[] = {123, 456};
int main()
{
extern int *b;
printf("val b\n");
printf("%d\n", *(b + 1));
// printf("val a\n");
// printf("%d\n", *(a + 1));
return 0;
}
こういう分割ソースをコンパイル、リンクして実行すると、何も表示無しで終了する
デバッガー使って実行してみると、SEGVになってる
636ハノン ◆QZaw55cn4c (ワッチョイ 9f47-o3tO)
2021/09/20(月) 20:10:17.55ID:+hQanlE40 >>634
>ミスする可能性が上がるから各コードでexternせずに必要ならヘッダに書いてもらえってことじゃね?
そうそう、extern による宣言と定義とが食い違うとエラーがでますから、そのためのヘッダの分離ということですね
>そもそもexternなんてextern "C"以外滅多に使わないけどな
関数の宣言は extern 省略可能ですし、ライブラリ側で共用のメモリを確保することは滅多にないです私は
>ミスする可能性が上がるから各コードでexternせずに必要ならヘッダに書いてもらえってことじゃね?
そうそう、extern による宣言と定義とが食い違うとエラーがでますから、そのためのヘッダの分離ということですね
>そもそもexternなんてextern "C"以外滅多に使わないけどな
関数の宣言は extern 省略可能ですし、ライブラリ側で共用のメモリを確保することは滅多にないです私は
637621 (アウアウウー Sa5b-XGHE)
2021/09/20(月) 23:40:17.11ID:y5y6BCAna >>635
これは関数のスコープに書かなくても(ファイルスコープでも)同じじゃない?
これは関数のスコープに書かなくても(ファイルスコープでも)同じじゃない?
638621 (アウアウウー Sa5b-XGHE)
2021/09/21(火) 00:23:33.65ID:7n0ZYlgRa639デフォルトの名無しさん (ワッチョイ 1fbd-SDcz)
2021/09/21(火) 00:26:56.39ID:aEoN/PBD0 >>637
同じですね
そもそもexternを明示的に書く必要がある状況って、
あるソースで定義されているグローバル変数を他のソースに公開して使えるようにするために、
ヘッダにextern int a;のように書いておいて、他のソースにはそれを#includeさせる
(すると他のソースでは余計な領域が確保されない)
のパターンが基本だと思っています
だからそもそもブロックスコープでexternするのってなんで? 覗き魔? って思ってしまう
同じですね
そもそもexternを明示的に書く必要がある状況って、
あるソースで定義されているグローバル変数を他のソースに公開して使えるようにするために、
ヘッダにextern int a;のように書いておいて、他のソースにはそれを#includeさせる
(すると他のソースでは余計な領域が確保されない)
のパターンが基本だと思っています
だからそもそもブロックスコープでexternするのってなんで? 覗き魔? って思ってしまう
640デフォルトの名無しさん (ワッチョイ 1745-I/Yj)
2021/09/21(火) 03:22:03.74ID:rkkhSUpi0 ブロックスコープ内でexternはK&R C時代の名残で今は完全に無意味
641デフォルトの名無しさん (ワッチョイ 1745-I/Yj)
2021/09/21(火) 03:23:48.34ID:rkkhSUpi0 関数原型でのexternは単項プラスみたいなもん
staticじゃないよと強調する反対語
staticじゃないよと強調する反対語
642ハノン ◆QZaw55cn4c (ワッチョイ 9f47-o3tO)
2021/09/21(火) 03:36:19.96ID:9i80hc760 >>639
>ヘッダにextern int a;のように書いておいて、他のソースにはそれを#includeさせる
「他のソース」でないソースも、そのヘッダを #include しておけばダチェックにもなるし
>ヘッダにextern int a;のように書いておいて、他のソースにはそれを#includeさせる
「他のソース」でないソースも、そのヘッダを #include しておけばダチェックにもなるし
643デフォルトの名無しさん (ワッチョイ f737-tt/w)
2021/09/21(火) 19:14:32.01ID:8eqDWQ5I0644621 (アウアウウー Sa5b-XGHE)
2021/09/21(火) 22:41:16.78ID:rS8f3YVDa // b.c
char a[] = { 0, 1 };
// a.c
int main()
{
__extern int *a;
__printf("%d\n", a[1]):
__return 0;
}
不勉強でした
上のコードは警告もなしにコンパイルが通りますね
実行すると segmentation fault ですが
リンク時はデータ型はチェックされず、名前だけで参照を解決してるのですかね……
古い仕様で、今さら変更はできないんでしょうね、チェックができたとしても
char a[] = { 0, 1 };
// a.c
int main()
{
__extern int *a;
__printf("%d\n", a[1]):
__return 0;
}
不勉強でした
上のコードは警告もなしにコンパイルが通りますね
実行すると segmentation fault ですが
リンク時はデータ型はチェックされず、名前だけで参照を解決してるのですかね……
古い仕様で、今さら変更はできないんでしょうね、チェックができたとしても
645デフォルトの名無しさん (ワッチョイ 1745-I/Yj)
2021/09/21(火) 22:46:25.12ID:rkkhSUpi0 型システムを持たずラベルの綴りのみを手がかりに参照解決するリンカを操るツールの1つだからねCは
リンカにあれもこれもと機能を持たせるのはメインフレームのファイルシステムにあれもこれも持たせようとしたVSAMの再来だ
インフラ的なものにアプリの都合を無闇に押しつけるべきではないことを歴史から学ぶべきだぞ
リンカにあれもこれもと機能を持たせるのはメインフレームのファイルシステムにあれもこれも持たせようとしたVSAMの再来だ
インフラ的なものにアプリの都合を無闇に押しつけるべきではないことを歴史から学ぶべきだぞ
646はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 9f3e-IhC7)
2021/09/21(火) 23:19:06.05ID:tYtQqya30 C には「プロトタイプ (関数原型) を持たない関数宣言」があって、
関数の型が曖昧なまま関数が存在することだけを宣言できる。
プロトタイプ (プロトタイプ宣言) がある場合にはその関数を呼出すにあたって実引数と仮引数の間では代入と同じ規則
で (可能な場合には) 暗黙の型変換が適用されるが、プロトタイプがない場合には
既定の実引数拡張 (可変長引数に実引数を渡すときと同じ規則) が適用されて実引数と仮引数の辻褄が
あってないときは未定義という扱いになる。
更には C89 は暗黙の関数宣言という規則があって (C99 では廃止されている)
関数を呼出そうとした時点で関数が宣言されていない場合には実引数の型から一定の規則に基づいて
関数の型を推測し、関数が宣言されたかのように振る舞うことになっている。
なので関数宣言が存在しなくても二度以上の関数呼出しの型に矛盾があれば検出はされる。
もちろん関数定義の実体と辻褄があってなかったらそれは未定義だけど。
このあたりのクソみたいな規則は「C++ では採用しなかった仕様」として D&E でちょっと触れられてる。
関数の型が曖昧なまま関数が存在することだけを宣言できる。
プロトタイプ (プロトタイプ宣言) がある場合にはその関数を呼出すにあたって実引数と仮引数の間では代入と同じ規則
で (可能な場合には) 暗黙の型変換が適用されるが、プロトタイプがない場合には
既定の実引数拡張 (可変長引数に実引数を渡すときと同じ規則) が適用されて実引数と仮引数の辻褄が
あってないときは未定義という扱いになる。
更には C89 は暗黙の関数宣言という規則があって (C99 では廃止されている)
関数を呼出そうとした時点で関数が宣言されていない場合には実引数の型から一定の規則に基づいて
関数の型を推測し、関数が宣言されたかのように振る舞うことになっている。
なので関数宣言が存在しなくても二度以上の関数呼出しの型に矛盾があれば検出はされる。
もちろん関数定義の実体と辻褄があってなかったらそれは未定義だけど。
このあたりのクソみたいな規則は「C++ では採用しなかった仕様」として D&E でちょっと触れられてる。
647デフォルトの名無しさん (ワッチョイ 1745-I/Yj)
2021/09/21(火) 23:25:07.21ID:rkkhSUpi0 > 実引数の型から一定の規則に基づいて関数の型を推測し
func(1);
↓
int func();
func("string");
↓
int func();
こうなるだけで推測なんて気の利いたことはしないよ
func(1);
↓
int func();
func("string");
↓
int func();
こうなるだけで推測なんて気の利いたことはしないよ
648621 (アウアウウー Sa5b-XGHE)
2021/09/21(火) 23:27:49.11ID:rS8f3YVDa プロトタイプ宣言は C++からの逆輸入だからな….
その昔の Cったら
その昔の Cったら
649はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 9f3e-IhC7)
2021/09/21(火) 23:34:12.47ID:tYtQqya30 >>647
あ、ほんまやな。
仕様上のルールは「extern int func(); が書かれていたものとみなす」というだけで、
具体的なチェックをどこまでするかは処理系次第 (たぶんあまり真面目にやってなかったと思うけど) だな。
あ、ほんまやな。
仕様上のルールは「extern int func(); が書かれていたものとみなす」というだけで、
具体的なチェックをどこまでするかは処理系次第 (たぶんあまり真面目にやってなかったと思うけど) だな。
650デフォルトの名無しさん (ワッチョイ ff46-bwRU)
2021/09/22(水) 05:28:22.60ID:iWoXuoBc0651デフォルトの名無しさん (ワッチョイ 9fad-QxrA)
2021/09/22(水) 14:25:23.40ID:Te29kBsr0 どうだったっけなあ?
652はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 9f3e-IhC7)
2021/09/22(水) 14:32:16.52ID:1hd+XsHu0 The C programming language (いわゆる K&R 第一版) の
APPENDIX A 8.3 Declarators を見る限りでは
引数リストが空の形式しかないように見える。
関数であるということは宣言できるが型チェックはガバガバっぽい。
D&E の 2.6 静的タイプチェック の項では
> C with Classes のシンタクスとルールはその後 ANSI C の規格にも採用されたが
> C with Classes の最初の実装の時点ですでに完全な形をしていた。
という一文があるので C の型チェックは C++ (の前身である C with Classes)
からの影響ということで間違いないと思う。
APPENDIX A 8.3 Declarators を見る限りでは
引数リストが空の形式しかないように見える。
関数であるということは宣言できるが型チェックはガバガバっぽい。
D&E の 2.6 静的タイプチェック の項では
> C with Classes のシンタクスとルールはその後 ANSI C の規格にも採用されたが
> C with Classes の最初の実装の時点ですでに完全な形をしていた。
という一文があるので C の型チェックは C++ (の前身である C with Classes)
からの影響ということで間違いないと思う。
653デフォルトの名無しさん (エムゾネ FFbf-hED7)
2021/09/22(水) 14:42:52.46ID:KzVGjGnLF 初耳だわ
はちみつは何歳?
はちみつは何歳?
654デフォルトの名無しさん (ワッチョイ bfe7-I/Yj)
2021/09/22(水) 15:34:35.81ID:p7uTNZa70 47歳くらいだと思う
655ハノン ◆QZaw55cn4c (ワッチョイ 9f47-o3tO)
2021/09/22(水) 17:51:09.10ID:z5uxQYPx0 >>644
そのコード、仮に a.c で
extern int *a;
ではなくて
extern char *a;
であってもセグフォが出ると思います、試してませんけど‥‥
なにか二重に勘違いしてませんか?それとも私が二重に勘違いしているのか?
そのコード、仮に a.c で
extern int *a;
ではなくて
extern char *a;
であってもセグフォが出ると思います、試してませんけど‥‥
なにか二重に勘違いしてませんか?それとも私が二重に勘違いしているのか?
656はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 9f3e-IhC7)
2021/09/22(水) 18:02:31.76ID:1hd+XsHu0 >>655
配列として定義したものをポインタとして宣言するのは間違いだな。
配列として定義したものをポインタとして宣言するのは間違いだな。
657はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 9f3e-IhC7)
2021/09/22(水) 18:04:06.47ID:1hd+XsHu0 FAQ に書いてあったわ。
http://www.c-faq.com/aryptr/aryptr1.html
http://www.c-faq.com/aryptr/aryptr1.html
658デフォルトの名無しさん (ブーイモ MM8f-liuG)
2021/09/22(水) 18:35:41.60ID:Il91zgnyM 47歳
研究部門に所属
趣味は手芸
研究部門に所属
趣味は手芸
659621 (アウアウウー Sa5b-XGHE)
2021/09/22(水) 19:31:52.27ID:u8cZI69ma >>655
ありがとうございます
はい、char と char でもダメですね
データ型がことなれば、リンケージできないのではと思い実験してみました
定義側でメモリに配置されているのは値で、extern宣言で参照する側が期待するのはポインタが配置されていることなのでうまくいきませんね(違うかな)
ありがとうございます
はい、char と char でもダメですね
データ型がことなれば、リンケージできないのではと思い実験してみました
定義側でメモリに配置されているのは値で、extern宣言で参照する側が期待するのはポインタが配置されていることなのでうまくいきませんね(違うかな)
661デフォルトの名無しさん (ワッチョイ 9f69-5MQP)
2021/09/23(木) 08:15:49.41ID:0q4HMCJB0 >>638
変数に対しても型情報付加したマングリングするぐらいかねぇ?
変数に対しても型情報付加したマングリングするぐらいかねぇ?
663ハノン ◆QZaw55cn4c (ワッチョイ 9f47-o3tO)
2021/09/23(木) 10:02:57.46ID:HaJtCNmP0664ハノン ◆QZaw55cn4c (ワッチョイ 9f47-o3tO)
2021/09/23(木) 13:38:03.01ID:HaJtCNmP0 >>658
ほとんどプロの人‥‥完璧なアマは私くらいですか
ほとんどプロの人‥‥完璧なアマは私くらいですか
665はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 9f3e-IhC7)
2021/09/23(木) 16:56:05.29ID:pKS1sRJG0 COFF フォーマットを見てるんだが、
関数が返す値の型を格納するところは有っても引数の型については無いみたいだ。
http://delorie.com/djgpp/doc/coff/symtab.html
ヘッダファイルで型情報をやりとりする前提なんだな。
ELF だとたぶん詳細な型も入れられそうな雰囲気があるんだけど複雑でようわからん……。
関数が返す値の型を格納するところは有っても引数の型については無いみたいだ。
http://delorie.com/djgpp/doc/coff/symtab.html
ヘッダファイルで型情報をやりとりする前提なんだな。
ELF だとたぶん詳細な型も入れられそうな雰囲気があるんだけど複雑でようわからん……。
666デフォルトの名無しさん (ワッチョイ d31b-QjBH)
2021/09/24(金) 19:26:12.39ID:bEXGgTP60 もしかしてc言語って新たにブロック文つくったら構造体の二重定義って可能になるんですか?
試しに
{
struct a{};
{
struct a{};
}
}
ってcompiler explorerで打ち込んだらcompile通りました。
こんなの初耳です。
ちなみに同じブロック文で二重定義したらcompile errorが起こりました。
試しに
{
struct a{};
{
struct a{};
}
}
ってcompiler explorerで打ち込んだらcompile通りました。
こんなの初耳です。
ちなみに同じブロック文で二重定義したらcompile errorが起こりました。
667ハノン ◆QZaw55cn4c (ワッチョイ b247-+9yW)
2021/09/24(金) 20:31:56.55ID:B0dAhYuN0 >>659
今回の例でもわかるように、無節操にバンバン extern 宣言を複数の C ソースファイルのあちこちに混入させるのは非常にマズイので、
普通はサブモジュールの extern 宣言だけを別のファイルにまとめておいて、そのサブモジュールを使用するソースで #include するのが標準的です
この extern 宣言だけをまとめたファイルを特にヘッダファイルと呼びます
https://ideone.com/rdbae2
実体を定義したサブモジュールもヘッダを #include するようにしておけば、ヘッダの誤りも検出することができます
なにかこういう基本文法を終えた後に位置するべき基本的な作法集をまとめたアドバンス教科書、みたいなものはないものでしょうか?
今回の例でもわかるように、無節操にバンバン extern 宣言を複数の C ソースファイルのあちこちに混入させるのは非常にマズイので、
普通はサブモジュールの extern 宣言だけを別のファイルにまとめておいて、そのサブモジュールを使用するソースで #include するのが標準的です
この extern 宣言だけをまとめたファイルを特にヘッダファイルと呼びます
https://ideone.com/rdbae2
実体を定義したサブモジュールもヘッダを #include するようにしておけば、ヘッダの誤りも検出することができます
なにかこういう基本文法を終えた後に位置するべき基本的な作法集をまとめたアドバンス教科書、みたいなものはないものでしょうか?
668621 (アウアウウー Sa43-LUZf)
2021/09/24(金) 20:48:31.47ID:PKobCCv1a669ハノン ◆QZaw55cn4c (ワッチョイ b247-+9yW)
2021/09/24(金) 20:54:31.27ID:B0dAhYuN0670デフォルトの名無しさん (ワッチョイ d31b-QjBH)
2021/09/24(金) 22:23:44.15ID:bEXGgTP60671デフォルトの名無しさん (ワッチョイ d31b-QjBH)
2021/09/24(金) 22:25:13.81ID:bEXGgTP60672ハノン ◆QZaw55cn4c (ワッチョイ b247-+9yW)
2021/09/25(土) 06:49:29.05ID:YrZFQiAF0673デフォルトの名無しさん (ワッチョイ 1ee9-2Lmd)
2021/09/25(土) 11:02:06.77ID:dAtBdpVF0 >>670
> 同じ変数名が複数ソース上にあるとき現在の位置から見て最も内側のブロックで宣言されたものの方で解決するという当たり前の規則だと認識してます
その「当たり前」の規則は変数名に限ったものじゃくて構造体タグ名についても同じ規則が適用される。
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2596.pdf
6.2.1 Scopes of identifiers
> A label name is the only kind of identifier that has function scope. ...
>
> Every other identifier has scope determined by the placement of its declaration (in a declarator or
> type specifier). ...
> ...
> ... the scope of one entity (the inner scope) will end strictly before the scope of the other
> entity (the outer scope). Within the inner scope, the identifier designates the entity declared in the
> inner scope; the entity declared in the outer scope is hidden (and not visible) within the inner scope.
ただし変数名とタグ名とでは名前空間 (name space) が異なる。
> 同じ変数名が複数ソース上にあるとき現在の位置から見て最も内側のブロックで宣言されたものの方で解決するという当たり前の規則だと認識してます
その「当たり前」の規則は変数名に限ったものじゃくて構造体タグ名についても同じ規則が適用される。
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2596.pdf
6.2.1 Scopes of identifiers
> A label name is the only kind of identifier that has function scope. ...
>
> Every other identifier has scope determined by the placement of its declaration (in a declarator or
> type specifier). ...
> ...
> ... the scope of one entity (the inner scope) will end strictly before the scope of the other
> entity (the outer scope). Within the inner scope, the identifier designates the entity declared in the
> inner scope; the entity declared in the outer scope is hidden (and not visible) within the inner scope.
ただし変数名とタグ名とでは名前空間 (name space) が異なる。
674デフォルトの名無しさん (エムゾネ FF32-kEnG)
2021/09/25(土) 11:05:50.70ID:lBxoEpbFF {
int a;
{
int a;
}
}
とやってることは同じ
int a;
{
int a;
}
}
とやってることは同じ
675デフォルトの名無しさん (ワッチョイ f2a4-X0+7)
2021/09/25(土) 16:07:19.71ID:Uwq7lnPV0 >>666
二重定義じゃなくて、入れ子構造の中での定義にすぎないからでは?
イメージとしては、コンパイラとしては、外側の構造体は
struct XX_a {}
内側の構造体は
struct X_a_a{}
みたいな感じで管理してコード展開してるだけ。
二重定義じゃなくて、入れ子構造の中での定義にすぎないからでは?
イメージとしては、コンパイラとしては、外側の構造体は
struct XX_a {}
内側の構造体は
struct X_a_a{}
みたいな感じで管理してコード展開してるだけ。
676デフォルトの名無しさん (ワッチョイ d31b-QjBH)
2021/09/25(土) 16:37:10.46ID:g8iabg1P0 >>673
出典出してくださってありがとうございます
declarator内かtype specifier内かどっちかで現れたかにも関わらず識別子には同じような規則が適用されるのですね
この知見を趣味のコンパイラづくりに役立てたいと思います
ありがとうございました
出典出してくださってありがとうございます
declarator内かtype specifier内かどっちかで現れたかにも関わらず識別子には同じような規則が適用されるのですね
この知見を趣味のコンパイラづくりに役立てたいと思います
ありがとうございました
677デフォルトの名無しさん (エムゾネ FF1f-jOtc)
2021/10/04(月) 14:36:02.21ID:ly3pkK+7F int a = -4 % 3; // -1
int b = -3 % 3; // 0
int c = -2 % 3; // -2
int d = -1 % 3; // -1
int e = (-4) % 3; // -1
int f = (-3) % 3; // 0
int g = (-2) % 3; // -2
int h = (-1) % 3; // -1
これは仕様ですか?環境依存ですか?
int b = -3 % 3; // 0
int c = -2 % 3; // -2
int d = -1 % 3; // -1
int e = (-4) % 3; // -1
int f = (-3) % 3; // 0
int g = (-2) % 3; // -2
int h = (-1) % 3; // -1
これは仕様ですか?環境依存ですか?
678デフォルトの名無しさん (ワッチョイ ff69-Uy5C)
2021/10/04(月) 14:53:49.95ID:DbNnxaRn0 C90は実装による
C99は被除数と同じ符号 ((ISO/IEC 9899:1999) の 6.5.5 見ろ)ってwiki に書いてあったけど
6節の (a/b) * b + a % b === a と
整数化に際しての丸めの方向から結果的にそう解釈すればいいってことなのかな
C99は被除数と同じ符号 ((ISO/IEC 9899:1999) の 6.5.5 見ろ)ってwiki に書いてあったけど
6節の (a/b) * b + a % b === a と
整数化に際しての丸めの方向から結果的にそう解釈すればいいってことなのかな
679デフォルトの名無しさん (ワッチョイ 3337-tRNm)
2021/10/06(水) 19:35:08.68ID:7g8s0ol20 まあ環境依存だと割と困ってたので
C99でIntelの実装にあわせただけなんですけどね
C99でIntelの実装にあわせただけなんですけどね
680はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 533e-M2B7)
2021/10/07(木) 15:44:53.27ID:UkaMQ5gY0681デフォルトの名無しさん (スップ Sdea-N/QG)
2021/10/12(火) 19:07:27.42ID:4loHRlApd 配列から数個おきに取得するとき、なにかアルゴリズムとかライブラリ関数みたいなものってありませんか?
↓みたいなコードです。nが大きく、物凄い時間掛かっていて...
for(i=0; i<n; i++) a[i] = b[i*3];
↓みたいなコードです。nが大きく、物凄い時間掛かっていて...
for(i=0; i<n; i++) a[i] = b[i*3];
682デフォルトの名無しさん (ワッチョイ 5ebb-dT87)
2021/10/12(火) 19:16:28.78ID:bbG44xQB0683デフォルトの名無しさん (ワッチョイ 4a63-JSxF)
2021/10/12(火) 19:22:19.41ID:xFkpIt2+0 >nが大きく、物凄い時間掛かっていて..
オンメモリーで扱えていなさそう
オンメモリーで扱えていなさそう
684デフォルトの名無しさん (ワッチョイ 0b10-YrVY)
2021/10/12(火) 20:33:05.08ID:1lOq7tfe0 a書とb読で互いにページ追い出されてスラッシングみたいになってんのかねえ
685デフォルトの名無しさん (ワッチョイ 0b02-QN1G)
2021/10/12(火) 20:59:19.20ID:UHyGo8Qe0 それ、3個おきという意味?
686デフォルトの名無しさん (ワッチョイ 4f2c-Mxyx)
2021/10/12(火) 21:57:57.62ID:TH86hbHp0 皆様ありがとうございます、Cだとなかなか難しそうですね...
データは数百MBくらいの画像で、mallocで確保した領域にあります。
RGBRGBRGB・・・からRだけを取り出す、みたいな処理で、
頻出しそうだし何かうまい方法あるんじゃないかと思ったんですが。
データは数百MBくらいの画像で、mallocで確保した領域にあります。
RGBRGBRGB・・・からRだけを取り出す、みたいな処理で、
頻出しそうだし何かうまい方法あるんじゃないかと思ったんですが。
687デフォルトの名無しさん (ワッチョイ 4a63-JSxF)
2021/10/13(水) 00:46:23.98ID:5Y743A290 >>686
ちょっと試してみた
a[] 100MB, b[] 300MB の配列確保して、
配列bを適当に初期化したあと
a[i] = b[i*3]; を実行してみた
それしかしていないが処理は1秒程度だった
64bit環境でメモリ16GB、i7 6700k skylake 4GHz
手持ちのコンパイラは Microsoft(R) 32-bit C/C++
Optimizing Compiler Version 16.00.40219.01 for 80x86
参考になるかな
ちょっと試してみた
a[] 100MB, b[] 300MB の配列確保して、
配列bを適当に初期化したあと
a[i] = b[i*3]; を実行してみた
それしかしていないが処理は1秒程度だった
64bit環境でメモリ16GB、i7 6700k skylake 4GHz
手持ちのコンパイラは Microsoft(R) 32-bit C/C++
Optimizing Compiler Version 16.00.40219.01 for 80x86
参考になるかな
688デフォルトの名無しさん (アウアウウー Sa2f-JXsI)
2021/10/13(水) 00:54:53.24ID:MLaNN2iaa 8ビット無駄になるけど、RGBを 32ビットの整数として、>> と & では?
689デフォルトの名無しさん (アウアウウー Sa2f-JXsI)
2021/10/13(水) 00:55:52.69ID:MLaNN2iaa バイト境界より速いかも
690デフォルトの名無しさん (ワッチョイ de46-i3Db)
2021/10/13(水) 01:22:15.55ID:l1MPihFP0 単純な方法でもいうほど遅くなるわけない
最速を目指すならSIMDでやれ
最速を目指すならSIMDでやれ
691デフォルトの名無しさん (ワッチョイ 4a63-JSxF)
2021/10/13(水) 02:10:45.46ID:5Y743A290 >>686 の説明文で触れてない重たい処理があるのかもしれん
692デフォルトの名無しさん (ワッチョイ 0fbd-N/QG)
2021/10/13(水) 12:24:48.28ID:89OLuObV0 ループ内で他の事をすると格段に遅くなったので(コンパイラの最適化の関係でしょうか?)
他の処理はすべて外に出して、書いた処理だけにしてる状況です。
ちょっとした実験に使いたいコードで、装置からの出力がだいたいGByte/sくらいなので、それに追い付く処理速度が理想なんですが...
並列化勉強しないと無理ですかね...
>>687
テストまでありがとうございます、こちらでもそれくらいのオーダーでした。
環境のせいではなさそうで安心しました。
他の処理はすべて外に出して、書いた処理だけにしてる状況です。
ちょっとした実験に使いたいコードで、装置からの出力がだいたいGByte/sくらいなので、それに追い付く処理速度が理想なんですが...
並列化勉強しないと無理ですかね...
>>687
テストまでありがとうございます、こちらでもそれくらいのオーダーでした。
環境のせいではなさそうで安心しました。
693デフォルトの名無しさん (ワッチョイ 2a69-Rsiz)
2021/10/13(水) 20:54:31.47ID:B1aurOR80 他の事したらキャッシュの効率落ちるわな
GByte/sってSATA3の速度超えてる
リアルタイムに加工するのはまだまだ無理なんじゃ
GByte/sってSATA3の速度超えてる
リアルタイムに加工するのはまだまだ無理なんじゃ
694デフォルトの名無しさん (スップ Sdea-18iY)
2021/10/14(木) 07:22:07.33ID:IjEclFwpd FPGAの出番だな
695デフォルトの名無しさん (ワントンキン MM56-e7Yh)
2021/10/14(木) 08:48:28.90ID:RLbfxynZM サイズが全然違って参考にならないかもしれないけど、以前テスト用の音声データのサンプリングレート落とす時に似たような事やった時は、a[i] b[j]でi++,j+=3みたいにやった方が早かった記憶。
696デフォルトの名無しさん (ワッチョイ 4f54-e7Yh)
2021/10/14(木) 16:42:28.33ID:1iGiane/0 >>692
コード見てないからなんとも言えないけど、本当にそのループだけで1秒ってのは時間かかりすぎじゃないかな。
このコードでgcc 最適化オプションなしでも0.3秒、-O2なら0.000002秒。
5年くらい前のCore i7 3.3GHz メモリ16GB
勘違いしてないか心配だけどコード。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(){
int count = 100*1024*1024;
unsigned char *a = (unsigned char*)malloc(count * sizeof(unsigned char));
unsigned char *b = (unsigned char*)malloc(3 * count * sizeof(unsigned char));
clock_t t = clock();
for(int i = 0;i<count;i++){
a[i] = b[i*3];
}
t = clock() - t;
printf("%f\n",(double)t/CLOCKS_PER_SEC);
return 0;
}
コード見てないからなんとも言えないけど、本当にそのループだけで1秒ってのは時間かかりすぎじゃないかな。
このコードでgcc 最適化オプションなしでも0.3秒、-O2なら0.000002秒。
5年くらい前のCore i7 3.3GHz メモリ16GB
勘違いしてないか心配だけどコード。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(){
int count = 100*1024*1024;
unsigned char *a = (unsigned char*)malloc(count * sizeof(unsigned char));
unsigned char *b = (unsigned char*)malloc(3 * count * sizeof(unsigned char));
clock_t t = clock();
for(int i = 0;i<count;i++){
a[i] = b[i*3];
}
t = clock() - t;
printf("%f\n",(double)t/CLOCKS_PER_SEC);
return 0;
}
697デフォルトの名無しさん (ワッチョイ 4a63-JSxF)
2021/10/14(木) 17:04:51.16ID:LTwSvEh70 >>687 だが、正確に測定したわけではない
>物凄い時間掛かっていて...
こういう質問だったので、そんなにかからないよという程度の返事
ものすごい時間が掛かると言う処理の内容が分からないとこれ以上は・・・
>物凄い時間掛かっていて...
こういう質問だったので、そんなにかからないよという程度の返事
ものすごい時間が掛かると言う処理の内容が分からないとこれ以上は・・・
698デフォルトの名無しさん (ガックシ 06b7-i3Db)
2021/10/14(木) 18:27:12.03ID:ciTZIm8Y6 それは最適化で消えただけだ
699デフォルトの名無しさん (ワッチョイ 4f54-e7Yh)
2021/10/14(木) 18:45:28.00ID:1iGiane/0 >>698
ですよねw -O2で0.18秒。
ですよねw -O2で0.18秒。
700デフォルトの名無しさん (ワッチョイ 0b10-YrVY)
2021/10/14(木) 19:22:12.25ID:B0s+ugv/0 もしやコードとかアルゴリズムの話じゃなくて、ミリ秒単位を長いと感じるかどうかってことなのか
701デフォルトの名無しさん (ブーイモ MM76-dT87)
2021/10/14(木) 20:39:33.49ID:60mfbtKJM Gbps出したいんだから当然そうでしょ
702デフォルトの名無しさん (アウアウウー Sa2f-JXsI)
2021/10/14(木) 22:30:42.31ID:oXMWcY6Na >>698
すでに書かれてたか
すでに書かれてたか
703デフォルトの名無しさん (ワッチョイ 2b21-AnEa)
2021/10/15(金) 00:03:27.81ID:XHojpqKh0 >>699
volatileつけてM1macで-O0で0.25秒、-O2で0.05秒位だな。普通に間に合いそう。
volatileつけてM1macで-O0で0.25秒、-O2で0.05秒位だな。普通に間に合いそう。
704デフォルトの名無しさん (アウアウウー Sacf-PkDM)
2021/10/15(金) 01:46:57.39ID:vumwfiEZa まったく自信がないのにチャチャ入れるようで申し訳ないのだけど、volatile を書く位置によっても結果がことなるかなと
おそらく a の * の左側に記述したのだと思うけど、動的に確保したメモリに対して有効なのかな…
誰か詳しい人いませんか?
おそらく a の * の左側に記述したのだと思うけど、動的に確保したメモリに対して有効なのかな…
誰か詳しい人いませんか?
705はちみつ餃子 ◆8X2XSCHEME (ワッチョイ ef3e-an4T)
2021/10/15(金) 02:01:35.27ID:2ebxtk1m0 ・ volatile で修飾された変数 (メモリ領域) は初期系にとって未知の方法で更新されうるというプログラマから処理系に対するヒント
・ (未知の方法で更新されていても) 言語仕様で定めるところの抽象計算機の動作に厳密に従わなければならない
という規則なので volatile の修飾先が変数 a であってもポインタ a が指す先であってもこの場合は結果的に最適化は抑制されると思う。
・ (未知の方法で更新されていても) 言語仕様で定めるところの抽象計算機の動作に厳密に従わなければならない
という規則なので volatile の修飾先が変数 a であってもポインタ a が指す先であってもこの場合は結果的に最適化は抑制されると思う。
706デフォルトの名無しさん (アウアウウー Sacf-PkDM)
2021/10/15(金) 02:05:14.85ID:vumwfiEZa ありがとうございます
おっしゃる通りのような気がします
おっしゃる通りのような気がします
707デフォルトの名無しさん (ワントンキン MM7f-t/lv)
2021/10/15(金) 07:55:14.31ID:Svg6ZUXsM >>686
画像だけならopenCVにsplitというのがあってrgb に分割された配列を返してくれるんだけど、後のレスから察するにどんどん流し込まれて来るみたいだからそのまま使えるかわからないです。
そのsplitではインデックスの計算にOpenCLを使っていますが、もちろん他の処理にも使えるから、ソース読んでみて損は無いと思います。
画像だけならopenCVにsplitというのがあってrgb に分割された配列を返してくれるんだけど、後のレスから察するにどんどん流し込まれて来るみたいだからそのまま使えるかわからないです。
そのsplitではインデックスの計算にOpenCLを使っていますが、もちろん他の処理にも使えるから、ソース読んでみて損は無いと思います。
708デフォルトの名無しさん (ワッチョイ 9f69-tt7j)
2021/10/15(金) 08:19:09.19ID:WeKxZ2Hf0 工夫するにしてもマルチスレッドで分割するぐらいしか思い浮かばん
領域を n分割し nスレッドパラに走らせて複製
領域を n分割し nスレッドパラに走らせて複製
709デフォルトの名無しさん (ワッチョイ efe9-an4T)
2021/10/15(金) 09:12:03.80ID:+uEUiKf90 >>705-706
volatile の修飾先によってどこの最適化が抑制されるかが異なるので結果も異なるだろう。
volatile の修飾先によってどこの最適化が抑制されるかが異なるので結果も異なるだろう。
710デフォルトの名無しさん (ワッチョイ 6b01-Avck)
2021/10/15(金) 09:44:49.60ID:FX8yed990 すみません、マジの初心者で申し訳ないんですけど、
今サンプルコードを写したりしながら勉強しているんですが、
毎回#includeとかint main(void)とかって書かなくて済む方法
ってありますか?
visual studio 2019を使ってます。
良ければ誰か教えてください。
今サンプルコードを写したりしながら勉強しているんですが、
毎回#includeとかint main(void)とかって書かなくて済む方法
ってありますか?
visual studio 2019を使ってます。
良ければ誰か教えてください。
711デフォルトの名無しさん (ブーイモ MMbf-/RkZ)
2021/10/15(金) 09:58:43.65ID:5/Pqp5xeM 今後数千行、数万行のプログラムを書いていくことになるんで、int mainを自動入力させたいなんて気持ちはそのうち自動的に消えるので安心してください
712デフォルトの名無しさん (エムゾネ FFbf-mxW8)
2021/10/15(金) 10:13:57.88ID:Sjupi756F713デフォルトの名無しさん (ワッチョイ 6b01-Avck)
2021/10/15(金) 10:23:34.05ID:FX8yed990 >>712
ありがとうございます!
元々それらを使っていたのですが、今使っているサンプルコードが書かれている本が
コマンドプロンプトで実行することを想定して作られているのか、
よく途中でscanfを使って入力の読み取りをするのですが、オンライン上だとそれができないのです。
visual studio 2019で、テンプレを自分で作っておいてそれを
読み込むような技があれば教えてほしいです。
ありがとうございます!
元々それらを使っていたのですが、今使っているサンプルコードが書かれている本が
コマンドプロンプトで実行することを想定して作られているのか、
よく途中でscanfを使って入力の読み取りをするのですが、オンライン上だとそれができないのです。
visual studio 2019で、テンプレを自分で作っておいてそれを
読み込むような技があれば教えてほしいです。
714デフォルトの名無しさん (ワッチョイ 6b01-Avck)
2021/10/15(金) 10:53:31.08ID:FX8yed990 自力で調べて解決できました。
ありがとうございました。
ありがとうございました。
715デフォルトの名無しさん (ワッチョイ efe7-twAR)
2021/10/15(金) 12:55:13.67ID:/xIATXuH0 どういたしまして。 お役に立ててなによりです。
716デフォルトの名無しさん (ワッチョイ bb5f-akk3)
2021/10/16(土) 13:51:30.67ID:0CjYy/Ai0 C言語初学者です
for文を使って1からnまでの総和を求め、
さらに答えを例えばn==3なら
1+2+3=6と表示したいのですが、この表示の仕方がわかりません
ご教授お願い致します
for文を使って1からnまでの総和を求め、
さらに答えを例えばn==3なら
1+2+3=6と表示したいのですが、この表示の仕方がわかりません
ご教授お願い致します
717デフォルトの名無しさん (ワッチョイ 9fad-i7rg)
2021/10/16(土) 14:26:17.75ID:W6fuAKpz0 int i.n,x;
n=3;
x=0;
for(i=1;i<=n;i++){
x+=i;
printf("%d",i);
if(i!=n)printf("+");
}
printf("=%d¥r¥n",x);
n=3;
x=0;
for(i=1;i<=n;i++){
x+=i;
printf("%d",i);
if(i!=n)printf("+");
}
printf("=%d¥r¥n",x);
718デフォルトの名無しさん (ワッチョイ bb5f-akk3)
2021/10/16(土) 14:38:37.10ID:0CjYy/Ai0719デフォルトの名無しさん (ドコグロ MMcf-ORg4)
2021/10/16(土) 16:54:36.35ID:r+1DV466M >>717
最終行の ¥r って要るの?
最終行の ¥r って要るの?
720はちみつ餃子 ◆8X2XSCHEME (ワッチョイ ef3e-ZO17)
2021/10/16(土) 17:51:52.16ID:E+4r+lYs0 >>719
基本的には不要。
・ 改行を表すものは (C の規格の範囲内では) 文字であるかのように扱う
・ テキストモードでの入出力ではホスト環境の都合に合わせて変換してよい
ということになっていて、改行を2バイトの符号で扱うホスト環境では \n という一文字を
その2バイトに変換するのは入出力関数の仕事。
ただし、標準出力をバイナリモードで開き直している場合だとか、
改行を1バイトの符号で表すホスト環境で2バイトの符号で表す環境のために出力したい
といった事情で改行を \r\n と書くことが無いとは言い切れない。
基本的には不要。
・ 改行を表すものは (C の規格の範囲内では) 文字であるかのように扱う
・ テキストモードでの入出力ではホスト環境の都合に合わせて変換してよい
ということになっていて、改行を2バイトの符号で扱うホスト環境では \n という一文字を
その2バイトに変換するのは入出力関数の仕事。
ただし、標準出力をバイナリモードで開き直している場合だとか、
改行を1バイトの符号で表すホスト環境で2バイトの符号で表す環境のために出力したい
といった事情で改行を \r\n と書くことが無いとは言い切れない。
721デフォルトの名無しさん (ワッチョイ bb5f-an4T)
2021/10/16(土) 22:25:40.97ID:0CjYy/Ai0 質問です
入力された文字列と文字数を表示するプログラムで
Enterキーのみが入力されるまでループして入力要求をするようにしたいのですが
1〜4文字の入力はループするのですが5文字入力するとループが終わってしまいます
どうなおせばいいでしょうか?
よろしくお願いします
/*************************************/
#include <stdio.h>
#include <string.h>
int main(void){
char str[] = "Hello";
fgets(str,sizeof(str),stdin);
while (str[0] !='\n'){
if (str[0] != '\n'){
printf("文字列%s\n",str);
printf("文字数%d\n",strlen(str));
fgets(str,sizeof(str),stdin);
}else{
break;
}
}
}
/*************************************/
入力された文字列と文字数を表示するプログラムで
Enterキーのみが入力されるまでループして入力要求をするようにしたいのですが
1〜4文字の入力はループするのですが5文字入力するとループが終わってしまいます
どうなおせばいいでしょうか?
よろしくお願いします
/*************************************/
#include <stdio.h>
#include <string.h>
int main(void){
char str[] = "Hello";
fgets(str,sizeof(str),stdin);
while (str[0] !='\n'){
if (str[0] != '\n'){
printf("文字列%s\n",str);
printf("文字数%d\n",strlen(str));
fgets(str,sizeof(str),stdin);
}else{
break;
}
}
}
/*************************************/
722デフォルトの名無しさん (ワッチョイ 9f63-ZO17)
2021/10/16(土) 22:28:04.06ID:j08Y/8ma0 よく出来たクイズですね
723デフォルトの名無しさん (ワッチョイ dfbd-lptH)
2021/10/16(土) 22:33:18.38ID:N8k1BZc20 AOJかなんかですか
724デフォルトの名無しさん (ワッチョイ 9f63-ZO17)
2021/10/16(土) 22:39:04.82ID:j08Y/8ma0 >>721
>1〜4文字の入力はループするのですが5文字入力するとループが終わってしまいます
設問として、何文字までの入力を受け付けるようにし、
それを越える文字数入力された場合はどうすると指示されてます?
>1〜4文字の入力はループするのですが5文字入力するとループが終わってしまいます
設問として、何文字までの入力を受け付けるようにし、
それを越える文字数入力された場合はどうすると指示されてます?
725デフォルトの名無しさん (ワッチョイ bb5f-akk3)
2021/10/16(土) 22:43:54.01ID:0CjYy/Ai0726デフォルトの名無しさん (ワッチョイ 9f63-ZO17)
2021/10/16(土) 22:50:23.50ID:j08Y/8ma0727デフォルトの名無しさん (ワッチョイ 0f61-an4T)
2021/10/16(土) 22:59:47.56ID:g8LyFw1O0 ・str配列を大きくする
・fgetsした結果のstrに改行文字が含まれてない場合は次の改行文字までstdinを読み飛ばす
等
・fgetsした結果のstrに改行文字が含まれてない場合は次の改行文字までstdinを読み飛ばす
等
728デフォルトの名無しさん (ワッチョイ bb5f-akk3)
2021/10/16(土) 23:00:22.34ID:0CjYy/Ai0 >>726
配列の箱増やしたらループするようになりました
ありがとうございます
あと1つ問題が残っていて文字列表示のあとに改行が無駄に1つ入ってしまいます
どうにかできないでしょうか?
現状
abcde
です
したい表示
abcdeです
配列の箱増やしたらループするようになりました
ありがとうございます
あと1つ問題が残っていて文字列表示のあとに改行が無駄に1つ入ってしまいます
どうにかできないでしょうか?
現状
abcde
です
したい表示
abcdeです
729デフォルトの名無しさん (ワッチョイ 1f36-ZO17)
2021/10/16(土) 23:00:54.46ID:iHqDmbcU0 >char str[] = "Hello";
とにかくここが気持ち悪い・・・
とにかくここが気持ち悪い・・・
730デフォルトの名無しさん (ワッチョイ 9f63-ZO17)
2021/10/16(土) 23:02:15.17ID:j08Y/8ma0731デフォルトの名無しさん (ワッチョイ 8bda-diS6)
2021/10/16(土) 23:02:51.64ID:hXa8blxW0 >>729
それは別に普通では?
それは別に普通では?
732デフォルトの名無しさん (ワッチョイ 9f63-ZO17)
2021/10/16(土) 23:08:52.93ID:j08Y/8ma0 >>728
切り詰め方はこんな感じで
if (str[strlen(str) - 1] == '\n')
str[strlen(str) - 1] = 0;
↑全角空白は適当に置き換えて
切り詰め方はこんな感じで
if (str[strlen(str) - 1] == '\n')
str[strlen(str) - 1] = 0;
↑全角空白は適当に置き換えて
733デフォルトの名無しさん (ワッチョイ 3b54-t/lv)
2021/10/16(土) 23:13:30.42ID:D7GMWgGE0 Hello!って!付ければいいよ。元気が足りない。
さらにこれfgetsの動作の理解を問う良問なんだから、無駄な改行なんぞ気にする余裕があるならfretsのドキュメント読んだ方がいいぞ。
さらにこれfgetsの動作の理解を問う良問なんだから、無駄な改行なんぞ気にする余裕があるならfretsのドキュメント読んだ方がいいぞ。
734デフォルトの名無しさん (ワッチョイ 3b54-t/lv)
2021/10/16(土) 23:14:42.85ID:D7GMWgGE0 >>733
偉そうに言ってスペルミスですね。fgets です
偉そうに言ってスペルミスですね。fgets です
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 空自機レーダー照射、音声データ公開 中国 ★3 [蚤の市★]
- 日銀「歴史的」利上げ迫る 35年ぶりの年間上げ幅、0.5%の壁を突破 [蚤の市★] [蚤の市★]
- 高市早苗首相、消費税減税に後ろ向き 足かせはレジシステム? 「責任ある積極財政」期待高いが [蚤の市★]
- 【YouTuber】バイク事故で入院のゆたぼん、振込で「お見舞金」募る [muffin★]
- 低所得層のマクドナルド離れが深刻に 広がる「ファストフード格差」の真相 米国 [少考さん★]
- 堀江貴文、キャッシュレス非対応の店にモヤッ 『PayPay』立ち上げの人物にまさかの直談判「現金決済しかできないんだけど…」 [冬月記者★]
- 中国がここまで過敏になるのは日本に前科があるから。盧溝橋、満州事変。ジャップの先制攻撃は挙げればキリがないけど [472617201]
- ぶっちゃけ天のうって昭和天のうのせいで全然ありがたみないよな
- MOIWなアイドルマスターミリオンライブシアターデイズアイマスミリマスグリマスミリシタスレ
- 犬って顔くっつけて寝たがるよな
- 『猟友会がクマ駆除を嫌がるなら潰すべき。職務を放棄するハンターから免許や銃を没収して罰金を取ろう』の声、ネットで上がる [932029429]
- 【悲報】JA「全然米が売れなくて倉庫を圧迫してる。助けて!」米卸売り業者「安売りしたら赤字になる…助けて!」 [802034645]
