if(!(c == 'y' || c == 'Y'))
return; if((c != 'y') && (c != 'Y'))
return;合ってますが、ド・モルガンの法則の法則でまとめてあるので、個人的には変えなくてもいいかなー。
length = (length < BUFSIZE) ? length : BUFSIZE; if(length >= BUFSIZE){
length = BUFSIZE;
}少し惜しくて、直感的に左より右の値のほうが大きい方がわかりやすいので、こちらのほうがおすすめです。 考え方は問題ないです。
if(BUFSIZE <= length){
length = BUFSIZE;
}flag = flag ? 0 : 1; flag = flag ? 1 : 0;これ、結果が逆になってません?確実に0もしくは1が保証されているならば、ビット反転使ってflag = ~flagでいいです。
boolがサポートされている言語ならば、flag=!flagでOKです。
quote = (*line == '"') ? 1 : 0; if(*line == '"'){
quote = 1;
}
else{
quote = 0;
}標準関数で書けるところは標準関数で書いたほうがよいです。共通認識ですし、口頭でも話しましたが、バグが少なくなるので。
quote = strcmp(*line, '"') == 0? 1 : 0; if(val & 1)
bit = 1;
else
bit = 0; if (val & 1){
bit = 1;
}
else{
bit = 0;
}ビット演算なので、結果をそのまま格納して問題ないです。
budougumi0617@~/git/newface (master@newface)
$ cat bit.c
#include<stdio.h>
int main(int argc, char const* argv[])
{
int val = 0;
int bit = 0;
int directbit = 0;
if (val & 1){
bit = 1;
}
else{
bit = 0;
}
directbit = (val&1);
printf("val = %d, bit = %d, directbit = %d\n", val, bit, directbit);
val = 1;
if (val & 1){
bit = 1;
}
else{
bit = 0;
}
directbit = (val&1);
printf("val = %d, bit = %d, directbit = %d\n", val, bit, directbit);
return 0;
}
budougumi0617@~/git/newface (master@newface)
$ ./a.out
val = 0, bit = 0, directbit = 0
val = 1, bit = 1, directbit = 1 int read(int* ip){
scanf("%d",ip);
return *ip;
}
insert(&graph[vert],read(&val),read(&ch));insert文が評価された後にread()を二回呼び出してそれぞれの変数の中身を変えているため、正しい値が入らないのではないか。
関数スタックに積まれてLIFO(Last In First Out)するので、readが2回評価されたあとにinsertが評価されます。
https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%BC%E3%83%AB%E3%82%B9%E3%82%BF%E3%83%83%E3%82%AF
問題点というと、scanfで数字以外が呼ばれたとき、そのまま失敗して0, 0が引数になりそうですね。
budougumi0617@~/git/newface (master@newface)
$ cat insert.cpp
#include<cstdio>
#include<iostream>
int read(int *ip) {
scanf("%d", ip);
return *ip;
}
void printValues(int i, int j) {
std::cout << "i = " << i << ", j = " << j << std::endl;
}
int main(int argc, char const* argv[])
{
int i(0);
int j(0);
printValues(read(&i), read(&j));
int n(1);
// printf("%d, %d\n", n++, n++);
return 0;
}
budougumi0617@~/git/newface (master@newface)
$ g++ insert.cpp
budougumi0617@~/git/newface (master@newface)
$ ./a.out
invalid value
i = 0, j = 0 n = 1;
printf("%d,%d\n",n++,n++)できるだけ多くのコンパイラで試してみて、実際にどうなるか確認すること
2,1 ←自分で実効した結果はこれでした
1,1 後の二つは予想です 1,2
同じ行で同じ変数をインクリメントするのは未定義動作です。(たしか) 警告も出ます。
insert.cpp:20:25: warning: multiple unsequenced modifications to 'n' [-Wunsequenced]
printf("%d, %d\n", n++, n++);スタックで積まれた順に評価されて、二回目のインクリメントの結果を最初のn++で表示したんですかね?
if (istty(stdin));
else if (istty(stdout));
else if(istty(stderr));
else return(0); if (istty(stdin));
else if (istty(stdout));
else if(istty(stderr));
else{
return(0);
}または
if (istty(stdin) || istty(stdout) || istty(stderr))
else{
return(0);
}原則{}は省略しないほうがよいです。
if (istty(stdin) || istty(stdout) || istty(stderr)){
// Do nothing.
}else{
return(0);
}if(retval != SUCCESS)
{
return(retval); //� ←return(retval);とreturn retval;の違いはありますか?
}
/*All went well!*/
return SUCCESS;return retval; //SUCCESSと等しくても等しくなくても結局retvalを返すのでは?または
if(retval == SUCCESS){
eturn SUCCESS;
}
else{
return (retval);
}return retval;で良いと思います。()の有無は基本的に関係ないです。
for(k = 0; k++ < 5; x += dx)
scanf("%lf", &dx); for(k = 0; k < 5; k++){
scanf("%lf", &dx);
x += dx;
}よいと思います。
int count = 0;
while (count < total){
count++;
if(this.getName(count) == nametable.userName()){
return(true);
}
}for(int i = 0; i < total; i++){
if(this.getName(i) == nametable.userName()){
return(true);
}
}2016年なのでStream使ってください(最低でもforeach)。
// precondition
// List<String> names;
//
// public String getName(int i) {
// return i < names.size() ? names.get(i) : null;
// }
public boolean ansewrByForeach() {
for (String name : this.names) {
if (name == nametable.userName()) {
return true;
}
}
return false;
}
public boolean ansewrByStarem() {
return names.stream().anyMatch(n -> n == nametable.userName());
}#define ISDIGIT(c) ((c >= 0) && (c <= 9)) ? 1:0マクロの中で引数が複数回評価される場合は、意図した動きと違う結果となる事がある。
(本書に他の例を使ってこの説明が出てきていました。+-*/%などをマクロ定義で使用する際に意図しない動きをするのは理解できたが、 上記のように単純な比較ではどのような場合に予想と違う動きをするのかがまだ理解できていません。)
ISDIGITが"一桁である"かどうかを返すマクロならば-10 < c < 10が範囲な気がしますが、
一番問題なのはマクロはコンパイル時に展開されるので、引数にインクリメントなんかを使っていると、2回インクリメントされますね。
budougumi0617@~/git/newface (master@newface)
$ cat macro.c
#include<stdio.h>
#define ISDIGIT(c) ((c >= 0) && (c <= 9)) ? 1:0
int main(int argc, char const* argv[])
{
int n = 0;
printf("Result is %d\n", '\t');
printf("Result is %d\n", ISDIGIT('\t'));
printf("Result is %d\n", ISDIGIT("test"));
printf("Result is %d\n", ISDIGIT(n++));
printf("n = %d\n", n);
return 0;
}
budougumi0617@~/git/newface (master@newface)
$ ./a.out
Result is 9
Result is 1
Result is 0
Result is 1
n = 2
プログラマー的にはn++は一度しかしていないのに、n=2になりました。
あとはマクロはなんでも受け入れるので、charでも文字列でもなんでも受け入れますね。
#define FT2METER 0.3048
#define METER2FT 3.28084
#define MI2FT 5280.0
#define MI2KM 1.609344
#define SQMI2SQKM 2.589988enum{
FT_TO_METER = 0.3048, /*1フィートをメートルに換算*/
METER_TO_FT = 3.28084, /*1メートルをフィートに換算*/
MI_TO_FT = 5280.0, /*1マイルをフィートに換算*/
MI_TO_KM = 1.609344, /*1マイルをキロメートルに換算*/
SQMI_TO_SQKM = 2.589988 /*1平方マイルを平方キロメートルに換算*/
}const doubleが妥当かと思われます。厳密に言うとそれぞれに関係はないので、同じenumにするのはちょっと違うかなと思います。
const double FT2METER = 0.3048;
const double METER2FT = 3.28084;
... void dict :: insert(string& w)
// wが辞書にあれば1を、なければ0を返すコメントの意味とコードがあっていないのではないか。
回答は正解だと思います。ただ、
void dict::insert(string& w) // これはC++の記法ですが、::の前後にスペースがあるとコンパイルエラーです。 if(n > MAX || n % 2 > 0) //偶数のテストn > MAXについてコメントで触れていない また右辺だけのコードの場合、偶数のテストとわざわざコメントしなくても理解できる。
OR評価なので、nがMAX以上だった場合は奇数でもtrueですね。なので、これもコメントがロジックと異なる気がします。
//メッセージを出力
//1行出力するたびに行カウンタを加算
void write_message(){
//カウンタをインクリメント
line_number = line_number +1;
fprintf(fout,"%d &s/n%d %s/n%d %s/n",
line_number,HEADER,
line_number +1, BODY,
line_number +2, TRAILER);
//行カウンタをインクリメント
line_number = line_number +2;
}最初に行カウンタを加算することをコメントで説明しているので、コードの途中でいちいち書く必要はない。「行カウンタ」か「カウンタ」で言葉を統一すべきではないか。
OKだと思います。加えるならば、一度に3行出力することを関数のコメントに書いておいてほしいですね。