C言語なら俺に聞け 142 [無断転載禁止]©2ch.net
■ このスレッドは過去ログ倉庫に格納されています
>>567
>>559のレスの中の「早く」の使い方は自然だと思うが…。
日本語学校の1年目に、どう教わったの? >>569
朝鮮語か日本語かには関係ない
電気屋のルールだ >>555
>>546にはそのstrncpy()が書かれているが? PHPしかできないザコだったけどC言語が楽しい
Cのスタンダードなコーディングスタイルってないですか?
インデントにタブ使ってたりifに{}使ってなかったりするコードをよく見かけますけど >>573
C言語 コーディングスタイル
でググれ
あと結果の報告は要らん
と言うか報告するな
理由は>>574に書いてある >>573
ほんまC言語楽しいよな
俺もC#かWeb系スクリプト言語しか使ったことなかったんだが >>579
いやタブ1つにして表示幅はスペース4つ分だ。 >>576
ああ。もうこのスレはスペース開けるか開けないか改行するかしないか何文字にするか中括弧はどうするか行末にバックスラッシュ入れて次行に書くか書かないかgotoどうするか等の話で延々と10年ぐらい費やされるんだろうな。
もちろんエディタの話に飛び火してviがvimがemacsがとなる。 プログラム終了前にfree()が必要かどうかを忘れちゃいかん。 ちょっと教えてくださいとあるHPから抜粋
意味が分からないので解説お願いします
私が負荷した文は<< >>で囲みます
struct Person {
char name[20];
int sex;
// char sex;
int age;
double height;
double weight;
} person_s; <<←今までの自分の認識:Person構造体のインスタンスperson_sを生成 しかしこの認識は後述@でpがインスタンスであると推定できることから間違っていると推定できる>>
<< person_sは構造体宣言の為の鋳型と推定 しかし様々なプログラムをチェックするとここでインスタンス宣言している例も見受けられる >>
<< 変数が構造体宣言の為の鋳型なのかインスタンスなのかはコンパイラが記述から自動判断???>>
person_s p; << ←pがPerson構造体のインスタンスであることは後述@のメンバ呼び出しで推定できる >>
とかけば、不要な宣言を減らすことができます。
構造体メンバの初期化
各メンバの初期化方法として次のようなものがあります
person_s p = {"Tom", 0, 20, 175.2, 66.5}; <<←構造体宣言鋳型person_sを使用しpをインスタンス宣言??>>
// または
person_s p; << 構造体宣言鋳型person_sを使用しpをインスタンス宣言?? >>
p.name = "Tom"; << この記述でpが構造体Personのインスタンスであると推定できる ・・・@ >>
p.sex = 0;
<< person_sは構造体宣言の鋳型 pはインスタンスであると推定できるが >>
<< 何故ダイレクトにPersonを使ってpを宣言しないのか? >>
<< 何故person_sなどという変数を使って間接的に宣言するのか? >>
<< うんちくきぼんぬ >> struct Person の前に typedef がありそうな雰囲気 C++ならtypedefなくても可
多分.cppでビルド通したんだろうね >>589
後の句 person_s を型名として使ってるんで typedef は必須じゃない?
(strust 省略の Person で宣言してるのとは違う) >>590
C++ではtypedefは不要だよ(別にあっても構わないけど)
structとclassはメンバーのデフォルト設定がpublicかprivateかという違いを除けば構文的には全く同じように使える
structで継承することすら出来る >>592
論点はそこじゃなくて
struct Person { };
Person p;
が C++ では文法として通るのは指摘の通り
質問元の記述では
struct Person { } person_s;
person_s p;
こうなってるから、これじゃ C++ の文法でも通らないでしょうよ ってことで 通るよ
class宣言ではいちいちtypedefなど使わないのと同じように構造体でもtypedefは省略するのが一般的
むしろ先頭の構造体テンプレート名を省略して最後の型名だけ宣言する場合も多い https://ideone.com/e1pLf2
通ったっけ? って確認コード
インスタンスとtypedef の区別つく? structが省略可能になってtypedefしなくなったのを
typedefが省略可能と間違って覚えてるんじゃないだろうか >>594
>>595 を見る限り通らないようだね 型名のエイリアス宣言と その型のインスタンスの生成
typedef を省略した場合には、全く同じ記述になるんだけど
後者のインスタンスの生成で翻訳してるぜ コーディングスタイルってたくさんあるんですね
とりあえず検索したらエリートの人達が使ってそうなものを集めてみました
C Coding Standard - CMU (ECE)
https://users.ece.cmu.edu/~eno/coding/CCodingStandard.html
GNU Coding Standards
https://www.gnu.org/prep/standards/html_node/Writing-C.html
NASA C Style Guide
http://homepages.inf.ed.ac.uk/dts/pm/Papers/nasa-c-style.pdf
C Coding Style - GNOME Developer Center
https://developer.gnome.org/programming-guidelines/stable/c-coding-style.html.en
CERT C コーディングスタンダード
https://www.jpcert.or.jp/sc-rules/
Linux kernel coding style
https://www.kernel.org/doc/html/v4.10/process/coding-style.html
どれも難しそうなのでコーディングスタイル見るのやめようと思います。
githubで適当に見ても全然統一されてないし
とりあえずインデントは空白8個で{}を省略しないルールだけにしたいと思います。 空白8個なのはメモ帳で見た時にこのくらいだから合わせてるだけです 書いてりゃわかると思うけど8は多すぎ
単に昔のシステムがそうだったと言うだけのことだから4とか2でいいと思う >>573
会社や複数人作業ならそれにあわせる
一人で書く分には何でもいいだろ
なんなら、PHPで使ってたスタイルでいいだろ
ってか、PHPの時はどうしてたんだよ >>609
クリックしたら画面の中心を移動させる。 >>610
一応クリックするとある境界線付近を拡大するようにプログラムに書いてるのですが... >>612
環境によって座標系が違うのかも知れない。ずらす値を変えてみては? >>609
単調になるのは k のループ回数が少ないせいでは >>613
変えても同じでした
>>614
>>615
なるほど!家に帰ったらやって見ます! >>594
変数宣言が全てtypedefになるなんて狂気な言語
実例を教えてくれ 俺はこの書き方
if (condition) {
}
else {
} ソース整形ツールの動作オプションの数で眩暈がするぜw ■■たびたびお世話になります なにが悪いのかご指摘おねがいします■■
struct I2C_MEM
{
char DEV_ADR ;
char REG_ADR ;
char DATA[4] ;
} static I2C_MEM[2] ;
task02_tst ( struct I2C_MEM *aaa )
{
char i,a[2],b[2],c[2];
i = 0 ;
while ( i <= 1 )
{
aaa -> DEV_ADR ;
a[i] = *aaa ; // データタイプがインコンパチでエラーになる char DEV_ADR を参照してくれない?
aaa -> REG_ADR ;
b[i] = *aaa ; // データタイプがインコンパチでエラーになる char REG_ADR を参照してくれない?
aaa -> DATA ;
c[i] = *aaa // データタイプがインコンパチでエラーになる char DATA を参照してくれない?
p += 1 ;
i += 1 ;
}
} ↑単純に関数内で構造体のデータにポインタ+インデックスでアクセスしたい 間違い発見
p += 1 ; は aaa += 1 ; に置き換えてください >>622
何がしたいのかわからない。
代入の左辺は右辺と互換性のある型じゃないといけないし、配列まるごとの代入はできない。
まずは代入の型をそろえないと。 char型のデータを代入したいのなら、両辺の型をcharにしないといけないよ。 >>622
> aaa -> DEV_ADR ;
> a[i] = *aaa ;
例えばこの部分は a[i] = aaa->DEV_ADR; という処理を意図してるのではないかと思う
ただし aaa->DATA のところは char* 型になるので char 型の c[i] に代入できない >>622
エスパーするとたぶんこう言うことだと思う
task02_tst ( struct I2C_MEM *aaa ){
int i;
char a[2],b[2],c[2];
for(i = 0; i < 2; i++){
a[i] = aaa[i].DEV_ADR;
b[i] = aaa[i].REG_ADR;
c[i] = aaa[i].DATA; // ここは >>627 の言う通りなにをしたいのかよくわからん
}
} 初心者相手に表記法を変えると理解しにくいかも。
本質から外れた部分が目についてしまうからね。
int i = 0;
while ( i <= 1 )
{
a[i] = aaa -> DEV_ADR ; // ポインタaaaが指す構造体の DEV_ADR メンバの値
b[i] = aaa -> REG_ADR ; // ポインタaaaが指す構造体の REG_ADR メンバの値
c[i] = aaa -> DATA ; // c[i] の型と DATA メンバの型が違うからエラー
aaa += 1 ;
i += 1 ;
}
てな感じかと。
>>627-628 をまとめただけ、だけど。 >>629
c を char *c[2] で宣言しておけばなんとかなるね。 皆様 どうもありがとうございます
とりあえず代入の書き方が知りたかっただけでありまして
ちなみにインデックスを使用した配列メンバーのアクセスなんだけど
c[i] = aaa -> DATA +0 ;
d[i] = aaa -> DATA +1 ;
e[i] = aaa -> DATA +2 ;
f[i] = aaa -> DATA +3 ;
こんな書き方ってできるの? ポインタを返す場合はそういう書き方
aaa->DATA+3
ポインタの指してる先を求めたい場合は
aaa->DATA[3]
左辺が何を要求しているのか(どういうものを操作したいのか)を頭の中で整理せずに
記述法だけを即物的にトレースするのはとてもまずい task02_tst()の呼び出しが
task02_tst(I2C_MEM)なのか
task02_tst(&I2C_MEM[1])なのかわからん
前者と仮定するとDEV_ADRにアクセスする方法は
1. (*(aaa + i)).DEV_ADR
2. aaa[i].DEV_ADR
3. (aaa + i)->DEV_ADR
なんかが考えられるけど(2は1の糖衣構文)、ドットとアローそれぞれの
左側の違いを理解しないと先には進めないよ >>631
意図が分からないからマトモに答えられない
実際に数字入れて教えてくれ
例えば>>622はI2C_MEM = {4, 8, {0, 1, 2, 3}} でa,b,cはどうなるの? ちょっと質問です
↓下記のようなwhileの中身を複製するために使う実体化されない変数iをコンパイラ制御のための変数と明示する書き方ってあるんですか?
task02_tst ( I2C_MEM_typ *p , char i)
{
char i ;
i = 0 ;
while ( i < 2 )
{
p = p + i ;
a[i] = p -> DEV_ADR ;
b[i] = p -> REG_ADR ;
c[i][0] = p -> DATA[0] ;
c[i][1] = p -> DATA[1] ;
c[i][2] = p -> DATA[2] ;
c[i][3] = p -> DATA[3] ;
}
} task02_tst ( I2C_MEM_typ *p )
{
char i ;
i = 0 ;
while ( i < 2 )
{
p = p + i ;
a[i] = p -> DEV_ADR ;
b[i] = p -> REG_ADR ;
c[i][0] = p -> DATA[0] ;
c[i][1] = p -> DATA[1] ;
c[i][2] = p -> DATA[2] ;
c[i][3] = p -> DATA[3] ;
}
}
に修正します task02_tst ( I2C_MEM_typ *p )
{
char i ;
i = 0 ;
while ( i < 2 )
{
p = p + i ;
a[i] = p -> DEV_ADR ;
b[i] = p -> REG_ADR ;
c[i][0] = p -> DATA[0] ;
c[i][1] = p -> DATA[1] ;
c[i][2] = p -> DATA[2] ;
c[i][3] = p -> DATA[3] ;
i += 1 ;
}
}
に修正します >>636
先ず日本語をなんとかした方がいい
『whileの中身を複製する』とはどういうことか?
『実体化されない変数』とは何か?
『コンパイラ制御のための変数』とは何か? こんな感じで構造体をインデックスで指定した転送命令にコンパイルする意図で書いています
p = p + i ; //*実体化されない(マシンコード化されない)コード
mov a[0] , [構造体I2C_MEMの基底番地+0]
mov b[0] , [構造体I2C_MEMの基底番地+1]
mov c[0][0] , [構造体I2C_MEMの基底番地+2]
:
mov c[0][3] , [構造体I2C_MEMの基底番地+5]
i += 1 ; //*実体化されない(マシンコード化されない)コード
p = p + i ; //*実体化されない(マシンコード化されない)コード
mov a[1] , [構造体I2C_MEMの基底番地+6]
mov b[1] , [構造体I2C_MEMの基底番地+7]
mov c[1][0] , [構造体I2C_MEMの基底番地+8]
:
mov c[1][3] , [構造体I2C_MEMの基底番地+11]
i += 1 ; //*実体化されない(マシンコード化されない)コード
・・・で意図通りコンパイルしてくれるわけですが
実体化されない(メモリー空間またはレジスタファイルにアサインされない)char iの意味が
希薄になるのでコンパイラに対する変数だよと明示(コンパイラ&設計者に)したいのだが
そんな書き方ある?ということでありまして 多少は意図した記述に沿って機械語出力するだろうけど、
保障されてるわけでもないし、最適化他でどうなるかもわからん
「機械語でこうなって欲しい」という目的を達成させるならその部分を機械語で書くか、
(環境によるだろうけど)その部分だけをインラインアセンブラにする うーーん・・・
volatileは最適化抑止(消すなー!)のための記述と認識しているんですが
volatileの逆の機能が欲しいんですよね 実体化するなー!ってやつです volatile揮発性の当初の意図は
70年代コンピュータでの磁気コアメモリに置いておく、程度なんじゃあねえの 実体化するな=機械語としてコードにおくな
ということは、言語上での変数を一切使わずに繰り返し展開するような
テンプレートやマクロでメタプログラミングしたい って話になるが・・・
#define IMP(idx) do { \
a[idx] = p[idx].DEV_ADR; \
b[idx] = p[idx].REG_ADR; \
:
: 以下同じ様に記述
:
c[idx][3] = p[idx].DATA[3] ; } whle(0)
IMP(0);
IMP(1);
IMP(2);
変数を使ってループできないから 繰り返し分リテラルを手で並べる必要あるしー
正直ほめられたやりかたじゃないと思うわ 実体化させたく無いものを記述?
…スラ二本じゃダメなのか? そういう話ではないでしょ
そもそもループによるコードのキャストは
記述を短縮化するのが目的なんだから
キャストのためのループであることをコンパイラに
推論させるための変数指定の仕組みがあるのかな?ってはなし まあ 指定しなくても現状でコンパイラは推論してるけれどもねw
なんかキモチ悪いといえばキモチ悪いんで指定できればうれしいってだけです なんかすぐ出てこないところをみると
そこらへんはコンパイラまかせなのね 返答が幾つもついてるのに出てこないとか言っちゃうのは見たいものしか見ない人の典型だね 一から10まで足し合わせるプログラムを教えてください。 >>657
#include <stdio.h>
int main(void) {
int i, n = 0;
for (i = 1; i <= 10; ++i) n += i;
printf("%d\n", n);
return 0;
} 人に思いを正しく伝えられない奴がうまくプログラミングできるとは思えないけど大丈夫なんだろう 俺は逆だと思っている。
人に上手く思いを伝えられないからこそ、
表現手段を駆使して伝えようと努力するんだよな。
絵とか音楽とか、クリエイターってそんな生き物。 >>661
> 絵とか音楽とか、クリエイターってそんな生き物。
全然違う
あいつらは自分の思いを伝えられるのは自分の表現法方だけだと思ってる
絵を描く奴で説明文を書いて思いを伝えるやつなんていないだろ >>645
メモリマップドI/Oに使える。特定のアドレスを読むとキーボードで入力した文字が読めるとか、そういうやつ。
読んだ直後に内容が変わる可能性があるので volatile でないとまずい。 共有メモリとか mmap() して複数のプロセスまたはスレッドがアクセスする領域も同じか。
あれ? こんなのちょっと前に話題にならなかったか? ちょっとお尋ねします
char *a ; と記述すると
↓
char a ; 実体化
int (&a) ; 非実体化(コンパイラが使用する変数)
が生成される
*の概念が無いと
char a ; 実体化
int a_point ; 実体化(アドレス長=intとする)
a_point = &a ; 実体化
例えばこう書くことになる
ポインタは関数内で宣言できる
その場合そのポインタの寿命は関数内に限定される
こんな感じの認識であってますか? 実体化とか 非実体化とかの オレオレ用語は何を意図してるのかわからん >>667
ということはプログラム内でユニークな名前をつけなければならないということですね? ■ このスレッドは過去ログ倉庫に格納されています