カテゴリー
C

独習C#第3版、P448匿名メソッドは値を返せる

using System;

namespace Chapter01All
{
    class TokumeiMethod
    {
        //デリゲートの宣言
        delegate int CountIt(int limit);
        delegate int CountThat(int limit);
        delegate int CountThis(int limit);
        static void Main()
        {
            //単なるstatic methodの起動
            Console.WriteLine(Count(5));

            //delegateを使ったCountメソッドの起動
            CountIt Cnt = Count;
            Console.WriteLine(Cnt(10));

            //もう一度delegateを使ってCountメソッドの起動
            CountThat count = Count;
            Console.WriteLine(count(15));

            //匿名メソッドを使うと
            CountThis cnt = delegate (int l)
            {
                int wa = 0;
                for (int i = 0; i <= l; i++)
                {
                    Console.Write(i);
                    if (i != l)
                        Console.Write("+");
                    wa += i;
                }
                Console.Write(" = ");
                return wa;
            };
            Console.WriteLine(cnt(20));

        }
        static int Count(int Limit)
        {
            int w = 0;
            for (int i = 0; i <= Limit; i++)
            {
                Console.Write(i);
                if (i != Limit)
                    Console.Write("+");
                w += i;
            }
            Console.Write(" = ");
            return w;
        }
    }
}
カテゴリー
C

独習C#第3版、デリゲート 匿名メソッド

using System;

namespace Chapter01All
{
    class TokumeiMethod
    {
        delegate void CountIt();
        static void Main()
        {
            Count(5);
        }
        static void Count(int Limit)
        {
            for (int i = 0; i < Limit; i++)
                Console.Write(i + " ");
            Console.WriteLine();
        }
    }
}
using System;

namespace Chapter01All
{
    class TokumeiMethod
    {
        //デリゲートの宣言
    delegate void CountIt(int limit);
        static void Main()
        {
            //delegateを使ったCountメソッドの起動
            CountIt Cnt = Count;
            Cnt(10);

            //単なるstatic methodの起動
            Count(5);
        }
        static void Count(int Limit)
        {
            for (int i = 0; i < Limit; i++)
                Console.Write(i + " ");
            Console.WriteLine();
        }
    }
}
using System;

namespace Chapter01All
{
    class TokumeiMethod
    {
        //デリゲートの宣言
        delegate void CountIt(int limit);
        delegate void CountThat(int limit);
        delegate void CountThis(int limit);
        static void Main()
        {
            //単なるstatic methodの起動
            Count(5);

            //delegateを使ったCountメソッドの起動
            CountIt Cnt = Count;
            Cnt(10);

            //もう一度delegateを使ってCountメソッドの起動
            CountThat count = Count;
            count(15);

            //匿名メソッドを使うと
            CountThis cnt = delegate (int l)
            {
                for (int i = 0; i < l; i++)
                    Console.Write(i + " ");
                Console.WriteLine();
            };
            cnt(20);

        }
        static void Count(int Limit)
        {
            for (int i = 0; i < Limit; i++)
                Console.Write(i + " ");
            Console.WriteLine();
        }
    }
}

最終は匿名メソッドを使ったデリゲートまで行くのですが、単純にstaticな関数から、delegateを使って、最後は匿名メソッドを使った、delegateまで行ってみました。

カテゴリー
C

独習C#第3版P443、デリゲート(マルチキャスト)

using System;

namespace Chapter01All
{
    delegate void Calcs(ref int a, ref int b);
    class DeleGateSample
    {
        void Kasan(ref int a, ref int b)
        {
            a += b;
        }
        void Genzan(ref int a, ref int b)
        {
             a -= b;
        }
        void Kakezan(ref int a, ref int b)
        {
            a *= b;
        }
        void Warizan(ref int a, refint b)
        {
            a /= b;
        }

        static void Main()
        {
            Calcs = Op;
            Calcs kasan = Kasan;
            Calcs genzan = Genzan;
            Calcs kakezan = Kakezan;

            int a = 10; int b = 20;
            Op = kasan;
            Op += genzan;
            Op(ref a, ref b);       //a+b=>30, 30-b=>10
            Console.WriteLine(a);

            int c = 100; int d = 200;
            Op = genzan;
            Op += kakezan;
            Op(ref c, ref d);       //c-d=>-100, -100*200=>-20000
            Console.WriteLine(c);

        }
    }
}

デリゲートを使う理由。その1)デリゲートはイベントをサポートするから。その2)コンパイル時に実行するメソッドが決まっていなくても、実行時に特定できる。

カテゴリー
C

独習C#第3版P442、インスタンスメソッドにデリゲートを設定する

using System;

namespace Chapter01All
{
    delegate int Calcs(int a, int b);
    class DeleGateSample
    {
        int Kasan(int a, int b)
        {
            return a + b;
        }
        int Genzan(int a, int b)
        {
            return a - b;
        }
        int Kakezan(int a, int b)
        {
            return a * b;
        }
        int Warizan(int a, int b)
        {
            return a / b;
        }

        static void Main()
        {
            DeleGateSample sobj = new DeleGateSample();
            
            Calcs Op = sobj.Kasan;
            Console.WriteLine(Op(10, 20));

            Op = sobj.Genzan;
            Console.WriteLine(Op(10, 20));

            Op = sobj.Kakezan;
            Console.WriteLine(Op(10, 20));

            Op = sobj.Warizan;
            Console.WriteLine(Op(10, 20));

            Calcs[] Ope = new Calcs[] {sobj.Kasan, sobj.Genzan, sobj.Kakezan, sobj.Warizan };
            for(int i=0; i<Ope.Length; i++)
            {
                Console.WriteLine(Ope[i](10, 20));
            }

        }
    }
}

デリゲートを個別に書く場合と、配列に書く場合の比較。

カテゴリー
C

独習C#第3版P438、デリゲート

using System;

namespace Chapter01All
{
    delegate int Calcs(int a, int b);
    class DeleGateSample
    {
        static int Kasan(int a, int b)
        {
            return a + b;
        }
        static int Genzan(int a, int b)
        {
            return a - b;
        }
        static int Kakezan(int a, int b)
        {
            return a * b;
        }
        static int Warizan(int a, int b)
        {
            return a / b;
        }

        static void Main()
        {
            Calcs Op = new Calcs(Kasan);
            Console.WriteLine(Op(10, 20));

            Op = Genzan;
            Console.WriteLine(Op(10, 20));

            Op = Kakezan;
            Console.WriteLine(Op(10, 20));

            Op = Warizan;
            Console.WriteLine(Op(10, 20));
        }
    }
}

 例としてやって見ましたが、これだとあまりやる意味がないようにも思います。例えば、Opを配列にしてしまうと少しは意味があるようにも思えますが。

using System;

namespace Chapter01All
{
    delegate int Calcs(int a, int b);
    class DeleGateSample
    {
        static int Kasan(int a, int b)
        {
            return a + b;
        }
        static int Genzan(int a, int b)
        {
            return a - b;
        }
        static int Kakezan(int a, int b)
        {
            return a * b;
        }
        static int Warizan(int a, int b)
        {
            return a / b;
        }

        static void Main()
        {
            Calcs[] Ope = new Calcs[] {Kasan, Genzan, Kakezan, Warizan };
            for(int i=0; i<Ope.Length; i++)
            {
                Console.WriteLine(Ope[i](10, 20));
            }
        }
    }
}
カテゴリー
C

C言語による実用アルゴリズム入門、リスト処理の写経

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct person {
	char name[40];
	int age;
	struct person* next;
}Person;

void ls_addFirst(const char* nm, int ag);
void ls_add(Person* pos, const char* nm, int ag);
void ls_addLast(const char* nm, int ag);
void ls_removeFirst(void);
void ls_remove(Person* pos);
void ls_removeLast(void);
Person* ls_end(void);
Person* psn_malloc(const char* nm, int ag);
Person* ls_find(const char* ss);
void disp_all(void);

Person head;

int main(void) {
	Person* p;
	head.next = NULL;
	printf("----------ls_addFirst,ls_addLAst\n");
	ls_addFirst("山田次郎", 22);
	ls_addFirst("山田一郎", 11);
	ls_addLast("山田三郎", 33);
	ls_addLast("山田四郎", 44);
	disp_all();

	printf("----------ls_find,ls_add\n");
	p = ls_find("山田次郎");
	if (p != NULL) ls_add(p, "追加五郎", 55);
	disp_all();

	printf("-----------ls_remove,ls_removeFirst,ls_removeLast\n");
	p = ls_find("山田次郎");
	if (p != NULL) ls_remove(p);
	ls_removeFirst();
	ls_removeLast();
	disp_all();

	return 0;
}

void ls_addFirst(const char* nm, int ag) {
	ls_add(&head, nm, ag);
}

void ls_add(Person* pos, const char* nm, int ag) {
	Person* dt;
	if (pos == NULL) return;
	dt = psn_malloc(nm, ag);
	dt->next = pos->next;
	pos->next = dt;
}

void ls_addLast(const char* nm, int ag) {
	if (head.next == NULL) ls_addFirst(nm, ag);
	else
		ls_add(ls_end(), nm, ag);
}

void ls_removeFirst(void) {
	ls_remove(&head);
}

void ls_remove(Person* pos) {
	Person* tmp;
	if (pos == NULL) return;
	if (pos->next == NULL)return;
	tmp = pos->next;
	pos->next = pos->next->next;
	free(tmp);
}

void ls_removeLast(void) {
	Person* p;
	if (head.next == NULL) return;
	for (p = &head; p->next->next != NULL; p = p->next) 
		;
	free(p->next);
	p->next = NULL;
}

Person* ls_end(void) {
	Person* p;
	if (head.next == NULL) return NULL;
	for (p = head.next; p->next != NULL; p = p->next) 
		;
	return p;
}

Person* psn_malloc(const char* nm, int ag) {
	Person* p;
	if ((p = (Person*)malloc(sizeof(Person))) == NULL) {
		printf("メモリを確保できません。\n"); exit(1);
	}
	strcpy_s(p->name, nm);
	p->age = ag;
	p->next = NULL;
	return p;
}

Person* ls_find(const char* ss) {
	Person* p;
	for (p = head.next; p != NULL; p = p->next) {
		if (strcpy_s(p->name, ss) == 0) return p;
	}
	return NULL;
}

void disp_all() {
	Person* p;
	for (p = head.next; p != NULL; p = p->next)
		printf("%s: %d\n", p->name, p->age);
}

 ネタ本との実行画面が合わないので、(二番目のブロック、途中に追加するところ)どっか間違っていると思われます。また、ネタ本ではchar *nmのようになってますが、VS2019ではconstを付けないとコンパイル通りません。それ以外は、今のところC++と違いなく、コンパイル出来ているようです。もう一つ、strcpyがエラーになって、strcpy_sを使うようにとのエラーのように思えました。constはイメージ的には分かりますが、strcpy_sは、違いが何処にあるんでしょうか?

間違っていたところが分かりました。ls_findが違ってました。strcpy_sでなくて、strcmpでした。

カテゴリー
C C++

VS2019でC++とCの違いはどれ程あるんでしょうか?

ネタ本は、林晴比古さんの「C言語による実用アルゴリズム入門」です。

// ConsoleApplication2.cpp : このファイルには 'main' 関数が含まれています。プログラム実行の開始と終了がそこで行われます。
//

#include <iostream>

int gcd(int a, int b) {
    while (a != b) {
        if (a > b) a = a - b; else b = b - a;
    }
    return a;
}

int gcd2(int a, int b) {
    int w;
    while (b != 0) {
        w = a % b;
        a = b; b = w;
    }
    return a;
}

int main()
{
    int a = 128; int b = 72;
    printf("整数%d, 整数%d, の最大公約数=%d", a, b, gcd(a, b));
}

拡張子はcppになってますが、後はCのネタ本に出来るだけ近くしてます。

カテゴリー
C++

望洋先生のC++入門、線形リスト

lists.h

#pragma once

#include <stdio.h>
#include <string.h>

class Link {
	friend class List;
	Link* next;
	char item[20];

public:
	Link(const char* x = "") { 
		strcpy_s(item, x);
		next = NULL;
	}
	Link* Next(void) { return (next); }
	void LinkPrint(void) { printf("%s\n", item); }
};

class List {
protected:
	Link* first;
	Link* last;
public:
	List(void) { first = last = new Link; }
	~List() { Clear(); delete first; }
	List& Insert(const Link&);
	List& Append(const Link&);
	List& Delete(void);
	List& Remove(void);
	List& Clear(void);
	void Print(void);
};

list.cpp

#include <stdio.h>
#include "list.h"

//-----先頭に要素を追加-----
List& List::Insert(const Link& x)
{
	Link* ptr = first;
	first = new Link;
	*first = x;
	first->next = ptr;
	return (*this);
}

//-----末尾に要素を追加-----
List& List::Append(const Link& x)
{
	Link* ptr = last;
	*ptr = x;
	last = new Link;
	ptr->next = last;
	return (*this);
}

//----先頭要素を削除-----
List& List::Delete(void)
{
	if (first != last) {
		Link* ptr = first->next;
		delete first;
		first = ptr;
	}
	return (*this);
}

//-----末尾要素を削除-----
List& List::Remove(void)
{
	if (first != last) {
		Link* now = first;
		Link* pre = last;
		while (now->next != last) {
			pre = now;
			now = now->next;
		}
		pre->next = last;
		delete now;
	}
	return (*this);
}

//-----全要素を削除-----
List& List::Clear(void)
{
	Link* ptr = first;
	while (ptr != last) {
		Link* next = ptr->next;
		delete ptr;
		ptr = next;
	}
	first = last;
	return (*this);
}

//-----全要素を表示-----
void List::Print(void)
{
	puts("===== リ ス ト 一 覧=====");
	int no = 1;
	Link* ptr = first;
	while (ptr != last) {
		printf("%d : ", no++);
		ptr->LinkPrint();
		//putchar('\n');
		ptr = ptr->next;
	}
}

実行部分

#include "list.h"

int main()
// ConsoleApplication1.cpp : このファイルには 'main' 関数が含まれています。プログラム実行の開始と終了がそこで行われます。
//
{
	List L7;

	L7.Append(Link("柴田"));
	L7.Insert(Link("大賀"));
	L7.Append(Link("具島"));
	L7.Append(Link("増田"));
	L7.Append(Link("鈴木"));
	L7.Print();
	L7.Remove();
	L7.Print();
	L7.Insert(Link("伊藤"));
	L7.Print();
	L7.Delete();
	L7.Print();
	L7.Clear();
	L7.Print();
	return (0);
}
カテゴリー
C++

C++コード張り付けてみる

#pragma once

#include <stdio.h>
#include <string.h>

class Link {
	friend class List;
	Link* next;
	char item[20];

public:
	Link(const char* x = "") { 
		strcpy_s(item, x);
		next = NULL;
	}
	Link* Next(void) { return (next); }
	void LinkPrint(void) { printf("%s\n", item); }
};

class List {
protected:
	Link* first;
	Link* last;
public:
	List(void) { first = last = new Link; }
	~List() { Clear(); delete first; }
	List& Insert(const Link&);
	List& Append(const Link&);
	List& Delete(void);
	List& Remove(void);
	List& Clear(void);
	void Print(void);
};
カテゴリー
C++

C++コード張り付けてみる、utf-8ふぁいるだったら

#pragma once

#include <stdio.h>
#include <string.h>

class Link {
	friend class List;
	Link* next;
	char item[20];

public:
	Link(const char* x = "") { 
		strcpy_s(item, x);
		next = NULL;
	}
	Link* Next(void) { return (next); }
	void LinkPrint(void) { printf("%s\n", item); }
};

class List {
protected:
	Link* first;
	Link* last;
public:
	List(void) { first = last = new Link; }
	~List() { Clear(); delete first; }
	List& Insert(const Link&);
	List& Append(const Link&);
	List& Delete(void);
	List& Remove(void);
	List& Clear(void);
	void Print(void);
};
inserted by FC2 system