Skip to content

Instantly share code, notes, and snippets.

@budougumi0617
Last active October 4, 2016 11:28
Show Gist options
  • Save budougumi0617/493eee5dc6fe128701c9f83054dfd244 to your computer and use it in GitHub Desktop.
Save budougumi0617/493eee5dc6fe128701c9f83054dfd244 to your computer and use it in GitHub Desktop.
AnswerToNewface
#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;
}
#include<stdio.h>
int main(int argc, char const* argv[])
{
int n = 0;
n = 1?20;
printf("%d\n",n);
return 0;
}
#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;
}
#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;
}
// © 2016- @budougumi0617
using Microsoft.VisualStudio.TestTools.UnitTesting;
//using MonoBrickFirmware.Movement;
using Moq;
namespace budougumi0617
{
/// <summary>
/// Sample test code for EV3 software on Visual Studio 2015.
/// </summary>
/// <remarks>
/// Need to add reference to below assembly.
/// - MonoBrickFirmware.dll
/// We can get DLL file from below site.
/// http://www.monobrick.dk/software/ev3firmware/
/// </remarks>
/// <seealso cref="https://github.com/Larsjep/monoev3"/>
/// <seealso cref="http://www.monobrick.dk/MonoBrickFirmwareDocumentation/index.html"/>
[TestClass]
public class MonoBrickFirmwareWithMoqTest
{
[TestMethod, Description("Confirm Moq is able to use instead of MonoBrickFirmware Class.")]
[TestCategory("Sample")]
public void SampleTest()
{
sbyte expected = 33;
// Stub of Motor by Moq.
var mock = new Mock<MonoBrickFirmware.Movement.Motor>();
// Set behavior to Stub instance.
// System.NotSupportedException : Invalid setup on a non-virtual (overridable in VB) member:m => m.GetSpeed()
mock.Setup(m => m.GetSpeed()).Returns(expected);
var motor = mock.Object;
Assert.AreEqual(expected, motor.GetSpeed());
}
}
}
/**
* @file
* @par File Name:
* List.java
* @author budougumi0617
* @date Created on 2016/08/28
*/
package practice;
import java.util.Arrays;
import java.util.List;
public class SampleOneEight {
List<String> names;
class NameTable {
public String userName() {
return "Bob";
}
}
public SampleOneEight() {
names = Arrays.asList("Alice", "Bob", "Charley", "Dorothy", "Edy");
}
public String getName(int i) {
return i < names.size() ? names.get(i) : null;
}
public boolean ansewrByForLoop() {
int total = names.size();
NameTable nametable = new NameTable();
for (int i = 0; i < total; i++) {
if (this.getName(i) == nametable.userName()) {
return (true);
}
}
return false;
}
public boolean ansewrByForeach() {
NameTable nametable = new NameTable();
for (String name : this.names) {
if (name == nametable.userName()) {
return true;
}
}
return false;
}
public boolean ansewrByStarem() {
NameTable nametable = new NameTable();
return names.stream().anyMatch(n -> n == nametable.userName());
}
public static void main(String[] args) {
SampleOneEight list = new SampleOneEight();
System.out.println("result = " + list.ansewrByForLoop());
System.out.println("result = " + list.ansewrByForeach());
System.out.println("result = " + list.ansewrByStarem());
}
}

問題1-4:次のそれぞれのコードを改良せよ

(1)

if(!(c == 'y' || c == 'Y'))
     return;

回答

     if((c != 'y') && (c != 'Y'))
      return;

Comment

合ってますが、ド・モルガンの法則の法則でまとめてあるので、個人的には変えなくてもいいかなー。


(2)

length = (length < BUFSIZE) ? length : BUFSIZE;

回答

     if(length >= BUFSIZE){
      length = BUFSIZE;
     }

Comment

少し惜しくて、直感的に左より右の値のほうが大きい方がわかりやすいので、こちらのほうがおすすめです。 考え方は問題ないです。

   if(BUFSIZE <= length){
     length = BUFSIZE;
   }

(3)

flag = flag ? 0 : 1;

回答

     flag = flag ? 1 : 0;

Comment

これ、結果が逆になってません?確実に0もしくは1が保証されているならば、ビット反転使ってflag = ~flagでいいです。 boolがサポートされている言語ならば、flag=!flagでOKです。


(4)

quote = (*line == '"') ? 1 : 0;

回答

     if(*line == '"'){
      quote = 1;
     }
     else{
      quote = 0;
     }

Comment

標準関数で書けるところは標準関数で書いたほうがよいです。共通認識ですし、口頭でも話しましたが、バグが少なくなるので。

quote = strcmp(*line, '"') == 0? 1 : 0;

(5)

   if(val & 1)
    bit = 1;
   else
    bit = 0;

回答

     if (val & 1){
      bit = 1;
     }
     else{
      bit = 0;
     }

Comment

ビット演算なので、結果をそのまま格納して問題ないです。

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

問題1-5:次の部分の問題点は何か

 int read(int* ip){
  scanf("%d",ip);
  return *ip;
 }
 insert(&graph[vert],read(&val),read(&ch));

回答

insert文が評価された後にread()を二回呼び出してそれぞれの変数の中身を変えているため、正しい値が入らないのではないか。

Comment

関数スタックに積まれて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

問題1-6:様々な評価順によって生成される可能性のある出力を全て列挙せよ

 n = 1;
 printf("%d,%d\n",n++,n++)

できるだけ多くのコンパイラで試してみて、実際にどうなるか確認すること

回答

 2,1 ←自分で実効した結果はこれでした

 1,1 後の二つは予想です 1,2

Comment

同じ行で同じ変数をインクリメントするのは未定義動作です。(たしか) 警告も出ます。

insert.cpp:20:25: warning: multiple unsequenced modifications to 'n' [-Wunsequenced]
    printf("%d, %d\n", n++, n++);

スタックで積まれた順に評価されて、二回目のインクリメントの結果を最初のn++で表示したんですかね?


問題1-7 以下のC/C++のコードをもっと簡潔に書き直せ。

(1)

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);
}

Comment

原則{}は省略しないほうがよいです。

if (istty(stdin) || istty(stdout) || istty(stderr)){
  // Do nothing.  
}else{
 return(0);
}

(2)

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);

  }

Comment

return retval;で良いと思います。()の有無は基本的に関係ないです。


(3)

for(k = 0; k++ < 5; x += dx)
  scanf("%lf", &dx);

回答

   for(k = 0; k < 5; k++){
    scanf("%lf", &dx);
    x += dx;
   }

Comment

よいと思います。


問題1-8 次のjavaコードの間違いを見つけて、慣用句的なルールを使って書き直せ。

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);
 }
}

Comment

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());
}

問題1-9 次のマクロ定義の問題点を指摘せよ。

#define ISDIGIT(c) ((c >= 0) && (c <= 9)) ? 1:0

回答

マクロの中で引数が複数回評価される場合は、意図した動きと違う結果となる事がある。

(本書に他の例を使ってこの説明が出てきていました。+-*/%などをマクロ定義で使用する際に意図しない動きをするのは理解できたが、 上記のように単純な比較ではどのような場合に予想と違う動きをするのかがまだ理解できていません。)

Comment

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でも文字列でもなんでも受け入れますね。


問題1-10 潜在的な間違いを最小限に食い止めるには、次の定義をどのように書き直したらいいだろうか。

#define FT2METER    0.3048
#define METER2FT    3.28084
#define MI2FT       5280.0
#define MI2KM       1.609344
#define SQMI2SQKM   2.589988

回答

enum{
 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平方マイルを平方キロメートルに換算*/
}

Comment

const doubleが妥当かと思われます。厳密に言うとそれぞれに関係はないので、同じenumにするのはちょっと違うかなと思います。

const double FT2METER = 0.3048;
const double METER2FT = 3.28084;
...

問題1-11 以下のコメントについてコメントせよ。

(1)

 void dict :: insert(string& w)

  // wが辞書にあれば1を、なければ0を返す

回答

コメントの意味とコードがあっていないのではないか。

コメント

回答は正解だと思います。ただ、

void dict::insert(string& w) // これはC++の記法ですが、::の前後にスペースがあるとコンパイルエラーです。

(2)

  if(n > MAX || n % 2 > 0) //偶数のテスト

回答

n > MAXについてコメントで触れていない また右辺だけのコードの場合、偶数のテストとわざわざコメントしなくても理解できる。

Comment

OR評価なので、nMAX以上だった場合は奇数でもtrueですね。なので、これもコメントがロジックと異なる気がします。


(3)

  //メッセージを出力
  //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;
}

回答

  最初に行カウンタを加算することをコメントで説明しているので、コードの途中でいちいち書く必要はない。「行カウンタ」か「カウンタ」で言葉を統一すべきではないか。

Comment

OKだと思います。加えるならば、一度に3行出力することを関数のコメントに書いておいてほしいですね。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment