| 情報学部 | 菅沼ホーム | 全体目次 | 演習解答例 | 付録 | 索引 |

y = sqrt(x);
#include <math.h> double sqrt(double x) x : 倍精度浮動小数点数
double x = 3.14; double y = sqrt(x); // double y = sqrt(3.14) としても良い
double d_data;
int i_data;
char c_data[10];
scanf("%lf %d %s", &d_data, &i_data, c_data); 3.141592654 123 abc
3.141592654 123 abc
double d_data;
int i_data;
char c_data[10];
・・・・・
printf("結果は %f %10.3f %d %5d %s %c\n", d_data, d_data, i_data, i_data, c_data, c_data[1]);
結果は 3.141593 3.142 123 123 abc b
#include <stdio.h>
int main()
{
double x[2];
int y;
char str[10];
scanf("%lf %lf %d %s", &x[0], &x[1], &y, str);
printf("result %s %.4f %c %f%6d\n", str, x[0], str[2], x[1], y);
return 0;
}
result printf 3.1416 i 2.500000 123
/****************************/
/* 文字列操作の例 */
/* coded by Y.Suganuma */
/****************************/
#include <stdio.h>
#include <string.h>
int main()
{
// 現在の文字列の内容を出力
char abc[] = "abc";
printf("-abc- %s\n", abc); // 文字列として出力
printf("-abc- "); // 1文字ずつ出力
int i1;
for (i1 = 0; i1 < 3; i1++)
printf("%c", abc[i1]);
printf("\n");
// 文字列の長さ
int len1, len2, len3;
char *defgh = "defgh"; // 警告メッセージ(この表現は,避けた方が良い)
char emp[20] = "";
len1 = strlen(abc);
len2 = strlen(defgh);
len3 = strlen(emp);
printf("各文字列の長さ %d %d %d\n", len1, len2, len3);
// 文字列のコピー
char *str = strcpy(emp, abc);
len1 = strlen(emp);
printf("-str- %s -emp- %s 長さ %d\n", str, emp, len1);
// 文字列の比較
int c1 = strcmp(emp, abc);
int c2 = strcmp(emp, defgh);
printf("-empとabc- %d -empとdefgh- %d\n", c1, c2);
// 文字列の結合
str = strcat(emp, " ");
str = strcat(emp, defgh);
len1 = strlen(emp);
printf("-str- %s -emp- %s 長さ %d\n", str, emp, len1);
// 文字列の検索
str = strstr(emp, "ef");
len1 = strlen(str);
printf("-str- %s 長さ %d -emp- %s\n", str, len1, emp);
return 0;
}
-abc- abc -abc- abc 各文字列の長さ 3 5 0 -str- abc -emp- abc 長さ 3 -empとabc- 0 -empとdefgh- -1 -str- abc defgh -emp- abc defgh 長さ 9 -str- efgh 長さ 4 -emp- abc defgh
---------------------(C++)string クラス-------------------------
/****************************/
/* 文字列操作の例(C++) */
/* coded by Y.Suganuma */
/****************************/
#include <iostream>
#include <string>
using namespace std;
int main()
{
// 現在の文字列の内容を出力
string abc = "abc";
cout << "-abc- " << abc << endl; // 文字列として出力
cout << "-abc- "; // 1文字ずつ出力
for (int i1 = 0; i1 < 3; i1++)
cout << abc[i1];
cout << endl;
// 文字列の長さ
string defgh = "defgh";
string emp = "";
int len1 = abc.size();
int len2 = defgh.size();
int len3 = emp.size();
cout << "各文字列の長さ " << len1 << " " << len2 << " " << len3 << endl;
// 文字列のコピー
emp = abc.assign(abc);
len1 = emp.size();
cout << "-emp- " << emp << " 長さ " << len1 << endl;
// 文字列の比較
cout << boolalpha << "emp == abc ? " << (emp == abc) << endl;
cout << "emp >= defgh ? " << (emp >= defgh) << endl;
// 文字列の結合
string str = emp + " " + defgh;
len1 = str.size();
cout << "-str- " << str << " 長さ " << len1 << endl;
// 文字列の検索
int n = str.find("ef");
cout << (n+1) << " 番目以降の文字列 " << str.substr(5) << endl;
return 0;
}
-abc- abc -abc- abc 各文字列の長さ 3 5 0 -emp- abc 長さ 3 emp == abc ? true emp >= defgh ? false -str- abc defgh 長さ 9 6 番目以降の文字列 efgh
----------------------(C++)string クラス終わり--------------------
関数の型 関数名 ( 引数リスト )
例 : constexpr int func(・・・・・)
/****************************/
/* nの階乗の計算 */
/* coded by Y.Suganuma */
/****************************/
#include <stdio.h>
int main()
{
/*
データの入力
*/
int n;
printf("nの値を入力して下さい ");
scanf("%d", &n);
/*
階乗の計算
*/
double kai = 1.0; /* 初期設定 */
int i1;
for (i1 = 1; i1 <= n; i1++)
kai *= (double)i1;
/*
結果の出力
*/
printf(" %dの階乗は=%f\n", n, kai);
return 0;
}
/****************************/
/* nの階乗の計算 */
/* coded by Y.Suganuma */
/****************************/
#include <stdio.h>
double kaijo(int);
int main()
{
/*
データの入力
*/
int n;
printf("nの値を入力して下さい ");
scanf("%d", &n);
/*
階乗の計算
*/
double kai = kaijo(n);
/*
結果の出力
*/
printf(" %dの階乗は=%f\n",n,kai);
return 0;
}
/**************************/
/* mの階乗 */
/* m : データ */
/* return : mの階乗 */
/**************************/
double kaijo(int m)
{
double s = 1.0;
int i1;
for (i1 = 1; i1 <= m; i1++)
s *= (double)i1;
return s;
}
printf(" %dの階乗は=%f\n", n, kaijo(n));
/****************************/
/* nの階乗の計算 */
/* coded by Y.Suganuma */
/****************************/
#include <stdio.h>
int kaijo(int);
int main()
{
/*
データの入力
*/
int n;
printf("nの値を入力して下さい ");
scanf("%d", &n);
/*
階乗の計算
*/
int kai = kaijo(n);
/*
結果の出力
*/
printf(" %dの階乗は=%d\n", n, kai);
return 0;
}
/**************************/
/* mの階乗 */
/* m : データ */
/* return : nの階乗 */
/**************************/
int kaijo(int m)
{
int s;
if (m > 1)
s = m * kaijo(m-1); /* 自分自身を呼んでいる */
else
s = 1;
return s;
}
/****************************/
/* nCrの計算 */
/* coded by Y.Suganuma */
/****************************/
#include <stdio.h>
double kaijo(int);
int main()
{
/*
データの入力
*/
int n, r;
printf("nとrの値を入力して下さい ");
scanf("%d %d", &n, &r);
/*
nCrの計算と出力
*/
double sn = kaijo(n);
double sr = kaijo(r);
double snr = kaijo(n-r);
printf(" %dC%dは=%f\n", n, r, sn/(sr*snr));
return 0;
}
/**************************/
/* mの階乗 */
/* m : データ */
/* return : nの階乗 */
/**************************/
double kaijo(int m)
{
double s = 1.0;
int i1;
for (i1 = 1; i1 <= m; i1++)
s *= (double)i1;
return s;
}
[記憶クラス] [型修飾]データ型 変数名, 配列名, 関数名, ・・・
const int n = 10; double x[n];
y = ::x;
01 /**********************************/
02 /* 変数の有効範囲(同じファイル) */
03 /* coded by Y.Suganuma */
04 /**********************************/
05 #include <stdio.h>
06
07 void sub3(void);
08
09 extern int j; // 26 行目で宣言された j
10
11 void sub1(void)
12 {
13 extern int i; // 25 行目で宣言された i
14 int k = 3;
15 printf("%d %d %d\n", i, j, k);
16 }
17
18 void sub2(void)
19 {
20 int i = 5;
21 int k = 6;
22 printf("%d %d %d\n", i, j, k);
23 }
24
25 int i = 1;
26 int j = 2;
27
28 int main()
29 {
30 sub2();
31 sub1();
32 sub3();
33
34 return 0;
35 }
36
37 void sub3(void)
38 {
39 int k = 7;
40 printf("%d %d %d\n", i, j, k);
41 }
5 2 6 1 2 3 1 2 7
------------------------file 1----------------------------
/************************************/
/* 変数の有効範囲(別々のファイル) */
/* coded by Y.Suganuma */
/************************************/
void sub1(void);
void sub2(void);
void sub3(void);
int i = 1;
int j = 2;
int main()
{
sub2();
sub1();
sub3();
return 0;
}
------------------------file 2----------------------------
#include <stdio.h>
void sub1(void)
{
extern int i; // file 1 で宣言された i
extern int j; // file 1 で宣言された j
int k = 3;
printf("%d %d %d\n", i, j, k);
}
------------------------file 3----------------------------
#include <stdio.h>
void sub2(void)
{
extern int j; // file 1 で宣言された j
int i = 5;
int k = 6;
printf("%d %d %d\n", i, j, k);
}
------------------------file 4----------------------------
#include <stdio.h>
void sub3(void)
{
extern int i; // file 1 で宣言された i
extern int j; // file 1 で宣言された j
int k = 7;
printf("%d %d %d\n", i, j, k);
}
01 /*******************************/
02 /* C/C++における変数の有効範囲 */
03 /* coded by Y.Suganuma */
04 /*******************************/
05 #include <stdio.h>
06
07 int x = 10; // 以下に記述されたすべての関数で有効
08
09 int main()
10 {
11 int x = 20; // main 関数内で有効
12 int y; // main 関数内で有効
13
14 y = ::x; // 7 行目の x を参照( C では許されない)
15 printf("x %d y %d\n", x, y);
16
17 if (x > 5) {
18 int y = 30; // 18,19 行目だけで有効
19 printf("x %d y %d\n", x, y);
20 }
21
22 printf("x %d y %d\n", x, y);
23
24 for (int x = 1; x <= 3; x++) { // x は 24 ~ 27 行目で有効
// この表現は,C では許されない
25 int y = x + 1; // 25,26 行目だけで有効
26 printf("x %d y %d\n", x, y);
27 }
28
29 printf("x %d y %d\n", x, y);
30
31 return 0;
32 }
x 20 y 10 x 20 y 30 x 20 y 10 x 1 y 2 x 2 y 3 x 3 y 4 x 20 y 10
namespace 名前空間名 { リスト };
namespace name1
{
int func1( ・・・ ) { ・・・ }
・・・・・
}; x = name1::func1( ・・・ );
#include <stdio.h>
namespace Test1 {
void print(int k1, int k2)
{
printf("%d %d\n", k1, k2);
}
}
namespace Test2 {
void print(int k1, int k2)
{
printf("%d / %d", k1, k2);
}
}
/****************/
/* main program */
/****************/
int main()
{
Test1::print(10, 20);
Test2::print(10, 20);
return 0;
}
10 20 10 / 20
/****************/
/* main program */
/****************/
using namespace Test1;
int main()
{
print(10, 20);
Test2::print(10, 20);
return 0;
}
01 {
02 ・・・
03 int a = 1;
04 int b = 5;
05 int n = sub(a, &b);
06 ・・・
07 }
08 int sub(int a, int *c) // int* c でも可,c には b のアドレスのコピー
09 {
10 ・・・
11 *c = 10; // 4 行目の b の値を変更
12 ・・・
13 a = 100; // 3 行目の a の値は変化しない
14 ・・・
15 }
/****************************/
/* 複数結果の受け渡し */
/* coded by Y.Suganuma */
/****************************/
#include <stdio.h>
int sub(int, int, int *); // int* でも可
int n; /* 以下の関数にすべて有効 */
int main()
{
/*
データの入力
*/
int a, b;
printf("a,b,及び,nの値を入力して下さい ");
scanf("%d %d %d", &a, &b, &n);
/*
関数の呼び出し
*/
int res;
int ind = sub(a, b, &res); /* 変数resはアドレス渡し */
/*
結果の出力
*/
if (ind == 0)
printf("n %d result %d\n", n, res);
else
printf("n = 0 (n %d)\n", n);
return 0;
}
/*****************************/
/* (a+b)/nの計算 */
/* a,b : データ */
/* res : 計算結果 */
/* return : =0 : normal */
/* =1 : n = 0 */
/*****************************/
int sub(int a, int b, int *res) // int* res でも可
{
extern int n;
int ind;
if (n == 0) {
ind = 1;
n = 100;
}
else {
ind = 0;
*res = (a + b) / n;
}
return ind;
}
n 3 result 2 n = 0 (n 100)
/****************************/
/* 複数結果の受け渡し */
/* coded by Y.Suganuma */
/****************************/
#include <stdio.h>
void sub(int, int, int *, int *);
int n; /* 以下の関数にすべて有効 */
int main()
{
/*
データの入力
*/
int a, b;
printf("a,b,及び,nの値を入力して下さい ");
scanf("%d %d %d", &a, &b, &n);
/*
関数の呼び出し
*/
int res, ind;
sub(a, b, &res, &ind);
/*
結果の出力
*/
if (ind == 0)
printf("n %d result %d", n, res);
else
printf("n = 0 (n %d)\n", n);
return 0;
}
/**************************/
/* (a+b)/nの計算 */
/* a,b : データ */
/* res : 計算結果 */
/* ind : =0 : normal */
/* =1 : n = 0 */
/**************************/
void sub(int a, int b, int *res, int *ind)
{
extern int n;
if (n == 0) {
*ind = 1;
n = 100;
}
else {
*ind = 0;
*res = (a + b) / n;
}
}
/****************************/
/* 複数結果の受け渡し */
/* coded by Y.Suganuma */
/****************************/
#include <stdio.h>
int *sub(int, int);
int n; /* 以下の関数にすべて有効 */
int main()
{
/*
データの入力
*/
int a, b;
printf("a,b,及び,nの値を入力して下さい ");
scanf("%d %d %d", &a, &b, &n);
/*
関数の呼び出し
*/
int *res = sub(a, b); /* resに結果が入る */
/*
結果の出力
*/
if (res[0] == 0)
printf("n %d result %d", n, res[1]);
else
printf("n = 0 (n %d)\n", n);
delete [] res;
return 0;
}
/**************************************/
/* (a+b)/nの計算 */
/* a,b : データ */
/* return : res[0] : =0 : normal */
/* =1 : n = 0 */
/* res[1] : 計算結果 */
/**************************************/
int *sub(int a, int b)
{
extern int n;
int *res = new int [2];
if (n == 0) {
res[0] = 1;
n = 100;
}
else {
res[0] = 0;
res[1] = (a + b) / n;
}
return res;
}
/****************************/
/* 複数結果の受け渡し */
/* coded by Y.Suganuma */
/****************************/
#include <stdio.h>
void sub(int, int, int *);
int n; /* 以下の関数にすべて有効 */
int main()
{
/*
データの入力
*/
int a, b;
printf("a,b,及び,nの値を入力して下さい ");
scanf("%d %d %d", &a, &b, &n);
/*
関数の呼び出し
*/
int res[2];
sub(a, b, res);
/*
結果の出力
*/
if (res[0] == 0)
printf("n %d result %d", n, res[1]);
else
printf("n = 0 (n %d)\n", n);
return 0;
}
/***********************************/
/* (a+b)/nの計算 */
/* a,b : データ */
/* res : res[0] : =0 : normal */
/* =1 : n = 0 */
/* res[1] : 計算結果 */
/***********************************/
void sub(int a, int b, int *res) // void sub(int a, int b, int res[]) でも可
{
extern int n;
if (n == 0) {
res[0] = 1;
n = 100;
}
else {
res[0] = 0;
res[1] = (a + b) / n;
}
}
int func(int, int = 5, char * = "test");
func(x) func(x, 10);
func(x, 5, "test") func(x, 10, "test");
01 /****************************/
02 /* デフォルト引数 */
03 /* coded by Y.Suganuma */
04 /****************************/
05 #include <stdio.h>
06
07 void sub(int, int = 5, FILE * = stdout);
08
09 int main()
10 {
11 sub(10); // sub(10, 5, stdout)と解釈,標準出力
12 sub(10, 10); // sub(10, 10, stdout)と解釈,標準出力
13 sub(10, 20, stdout); // 標準出力
14 FILE *out = fopen("test.txt", "w");
15 sub(10, 30, out); // ファイル test.txt へ出力
16 fclose(out);
17 return 0;
18 }
19
20 /*********************************/
21 /* 整数の足し算 */
22 /* x,y : データ */
23 /* fp : 出力先 */
24 /*********************************/
25 void sub(int x, int y, FILE *fp)
26 //void sub(int x, int y = 5, FILE *fp = stdout)
27 {
28 fprintf(fp, "結果は=%d\n", x+y);
29 }
int sub(・・・, int c[], ・・・) // int sub(・・・, int *c, ・・・) でも可
{
・・・
}
int main {
int b[5];
・・・
n = sub(・・・, b, ・・・);
・・・
}
/****************************/
/* 1次元配列の受け渡し */
/* coded by Y.Suganuma */
/****************************/
#include <stdio.h>
void wa(int, int*, int*, int*);
int main()
{
int a[2][3] = {{1, 2, 3}, {4, 5, 6}}, b[3];
/*
関数の呼び出し
*/
wa(3, &(a[0][0]), &(a[1][0]), b); /* 1行目と2行目のベクトル和の計算 */
/*
結果の出力
*/
int i1;
for (i1 = 0; i1 < 3; i1++)
printf("%d ", b[i1]);
printf("\n");
return 0;
}
/***********************************/
/* n次元ベクトルの和 */
/* n : 次元数 */
/* a,b : 和を計算するベクトル */
/* c : 計算結果が入るベクトル */
/***********************************/
void wa(int n, int* a, int* b, int* c)
{
int i1;
for (i1 = 0; i1 < n; i1++)
c[i1] = a[i1] + b[i1];
}
5 7 9
---------------------(C++11)初期化子リストの受け渡し-------------------------
/****************************/
/* 初期化子リストの受け渡し */
/* coded by Y.Suganuma */
/****************************/
#include <iostream>
#include <vector>
using namespace std;
void wa(vector<pair<int, int>>, int *);
int main()
{
int res[2] = {0};
vector<pair<int, int>> v {{1, 2}, {3, 4}, {5, 6}};
cout << "v";
for (auto x : v)
cout << " (" << x.first << ", " << x.second << ")";
cout << endl;
wa(v, res);
// wa({{1, 2}, {3, 4}, {5, 6}}, res); // 初期化子リスト
cout << " result " << res[0] << " " << res[1] << endl;
return 0;
}
/*********************************************/
/* ペアの和 */
/* r[0] : vector の各要素の first の和 */
/* r[1] : vector の各要素の second の和 */
/*********************************************/
void wa(vector<pair<int, int>> v, int *r)
{
for (auto x : v) {
r[0] += x.first;
r[1] += x.second;
}
}
v (1, 2) (3, 4) (5, 6) result 9 12
----------------------(C++11)初期化子リストの受け渡し--------------------
int b[4][10];
int sub(・・・, int c[][10], ・・・)
int sub(・・・, int (*c)[10], ・・・)
C = AB, cij = Σkaikbkj k = 1, ・・・, m
/**********************************/
/* 2次元配列の受け渡し(方法1) */
/* coded by Y.Suganuma */
/**********************************/
#include <stdio.h>
void seki(int, int, int, double [][3], double [][2], double [][2]);
int main()
{
/*
関数の呼び出し
*/
double a[2][3] = {{1.0, 2.0, 3.0}, {4.0, 5.0, 6.0}};
double b[3][2] = {{1.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}};
double c[2][2];
seki(2, 3, 2, a, b, c);
/*
結果の出力
*/
int i1;
for (i1 = 0; i1 < 2; i1++) {
int i2;
for (i2 = 0; i2 < 2; i2++)
printf("%f ", c[i1][i2]);
printf("\n");
}
return 0;
}
/**************************************/
/* 行列の積 */
/* n,m,l : 次元数 */
/* a : n x m */
/* b : m x l */
/* c : 計算結果が入る行列,n x l */
/**************************************/
void seki(int n, int m, int l, double a[][3], double b[][2], double c[][2])
{
int i1, i2, i3;
for (i1 = 0; i1 < n; i1++) {
for (i2 = 0; i2 < l; i2++) {
c[i1][i2] = 0;
for (i3 = 0; i3 < m; i3++)
c[i1][i2] += a[i1][i3] * b[i3][i2];
}
}
}
1 2 4 5
/**********************************/
/* 2次元配列の受け渡し(方法2) */
/* coded by Y.Suganuma */
/**********************************/
#include <stdio.h>
void seki(int, int, int, double**, double**, double**);
int main()
{
/*
領域の確保と値の設定
*/
double **a = new double* [2];
double **b = new double* [3];
double **c = new double* [2];
for (int i1 = 0; i1 < 2; i1++) {
c[i1] = new double [2];
if (i1 == 0)
a[i1] = new double [3] {1, 2, 3};
else
a[i1] = new double [3] {4, 5, 6};
}
for (int i1 = 0; i1 < 3; i1++) {
if (i1 == 0)
b[i1] = new double [2] {1, 0};
else if (i1 == 1)
b[i1] = new double [2] {0, 1};
else
b[i1] = new double [2] {0, 0};
}
/*
関数の呼び出し
*/
seki(2, 3, 2, a, b, c);
/*
結果の出力
*/
for (int i1 = 0; i1 < 2; i1++) {
for (int i2 = 0; i2 < 2; i2++)
printf("%f ", c[i1][i2]);
printf("\n");
}
return 0;
}
/**************************************/
/* 行列の積 */
/* n,m,l : 次元数 */
/* a : n x m */
/* b : m x l */
/* c : 計算結果が入る行列,n x l */
/**************************************/
void seki(int n, int m, int l, double **a, double **b, double **c)
{
for (int i1 = 0; i1 < n; i1++) {
for (int i2 = 0; i2 < l; i2++) {
c[i1][i2] = 0;
for (int i3 = 0; i3 < m; i3++)
c[i1][i2] += a[i1][i3] * b[i3][i2];
}
}
}
/**********************************/
/* 2次元配列の受け渡し(方法3) */
/* coded by Y.Suganuma */
/**********************************/
#include <stdio.h>
void seki(int, int, int, double *, double *, double *);
int main()
{
/*
関数の呼び出し
*/
double a[2][3] = {{1.0, 2.0, 3.0}, {4.0, 5.0, 6.0}};
double b[3][2] = {{1.0, 0.0}, {0.0, 1.0}, {0.0, 0.0}};
double c[2][2];
seki(2, 3, 2, &a[0][0], &b[0][0], &c[0][0]);
/*
結果の出力
*/
int i1, i2;
for (i1 = 0; i1 < 2; i1++) {
for (i2 = 0; i2 < 2; i2++)
printf("%f ", c[i1][i2]);
printf("\n");
}
return 0;
}
/**************************************/
/* 行列の積 */
/* n,m,l : 次元数 */
/* a : n x m */
/* b : m x l */
/* c : 計算結果が入る行列,n x l */
/**************************************/
void seki(int n, int m, int l, double *a, double *b, double *c)
{
int i1, i2, i3;
for (i1 = 0; i1 < n; i1++) {
for (i2 = 0; i2 < l; i2++) {
c[l*i1+i2] = 0;
for (i3 = 0; i3 < m; i3++)
c[l*i1+i2] += a[m*i1+i3] * b[l*i3+i2]; /* 添え字に注意 */
}
}
}
int (*sub)(double, char *)
int add(int a, int b)
{
return a + b;
}
int main()
{
int (*fun)(int, int) = &add;
printf("和 %d\n", fun(2, 3));
return 0;
}
xn+1 = xn - f(xn) / f'(xn)
/****************************/
/* 関数名の受け渡し */
/* coded by Y.Suganuma */
/****************************/
#include <stdio.h>
double newton(double(*)(double), double(*)(double),
double, double, double, int, int *);
double snx(double);
double dsnx(double);
int main()
{
double eps1 = 1.0e-7;
double eps2 = 1.0e-10;
double x0 = 0.0;
int max = 20, ind;
double x = newton(snx, dsnx, x0, eps1, eps2, max, &ind);
printf("ind=%d x=%f f=%f df=%f\n",ind,x,snx(x),dsnx(x));
return 0;
}
/*****************************************************/
/* Newton法による非線形方程式(f(x)=0)の解 */
/* fn : f(x)を計算する関数名 */
/* dfn : f(x)の微分を計算する関数名 */
/* x0 : 初期値 */
/* eps1 : 終了条件1(|x(k+1)-x(k)|<eps1) */
/* eps2 : 終了条件2(|f(x(k))|<eps2) */
/* max : 最大試行回数 */
/* ind : 実際の試行回数 */
/* (負の時は解を得ることができなかった) */
/* return : 解 */
/*****************************************************/
#include <math.h>
double newton(double(*f)(double), double(*df)(double),
double x0, double eps1, double eps2, int max, int *ind)
{
double x1 = x0;
double x = x1;
int sw = 0;
*ind = 0;
while (sw == 0 && *ind >= 0) {
sw = 1;
*ind += 1;
double g = (*f)(x1);
if (fabs(g) > eps2) {
if (*ind <= max) {
double dg = (*df)(x1);
if (fabs(dg) > eps2) {
x = x1 - g / dg;
if (fabs(x-x1) > eps1 && fabs(x-x1) > eps1*fabs(x)) {
x1 = x;
sw = 0;
}
}
else
*ind = -1;
}
else
*ind = -1;
}
}
return x;
}
/************************/
/* 関数値(f(x))の計算 */
/************************/
double snx(double x)
{
double y = exp(x) - 3.0 * x;
return y;
}
/********************/
/* 関数の微分の計算 */
/********************/
double dsnx(double x)
{
double y = exp(x) - 3.0;
return y;
}
ind=5 x=0.619061 f=0.000000 df=-1.142816
---------------------(C++11)関数オブジェクトとラムダ式-------------------------
/******************************/
/* 関数オブジェクトとラムダ式 */
/* coded by Y.Suganuma */
/******************************/
#include <stdio.h>
#include <math.h>
class Snx
{
public:
double operator() (double x)
{
return (double)(exp(x) - 3.0 * x);
}
};
class DSnx
{
public:
double operator() (double x)
{
return (double)(exp(x) - 3.0);
}
};
double newton1(auto, auto, double, double, double, int, int *); // ラムダ式
double newton2(Snx, DSnx, double, double, double, int, int *); // 関数オブジェクト
int main()
{
double eps1 = 1.0e-7;
double eps2 = 1.0e-10;
double x0 = 0.0;
int max = 20, ind;
// ラムダ式
auto snx1 = [](double x){ return exp(x) - 3.0 * x; };
auto dsnx1 = [](double x){ return exp(x) - 3.0; };
double x = newton1(snx1, dsnx1, x0, eps1, eps2, max, &ind);
printf("ind=%d x=%f f=%f df=%f\n",ind, x, snx1(x), dsnx1(x));
// 関数オブジェクト
Snx snx2;
DSnx dsnx2;
x = newton2(snx2, dsnx2, x0, eps1, eps2, max, &ind);
printf("ind=%d x=%f f=%f df=%f\n",ind, x, snx2(x), dsnx2(x));
return 0;
}
/*****************************************************/
/* Newton法による非線形方程式(f(x)=0)の解 */
/* fn : f(x)を計算する関数 */
/* dfn : f(x)の微分を計算する関数 */
/* x0 : 初期値 */
/* eps1 : 終了条件1(|x(k+1)-x(k)|<eps1) */
/* eps2 : 終了条件2(|f(x(k))|<eps2) */
/* max : 最大試行回数 */
/* ind : 実際の試行回数 */
/* (負の時は解を得ることができなかった) */
/* return : 解 */
/*****************************************************/
// ラムダ式
double newton1(auto f, auto df, double x0, double eps1, double eps2, int max, int *ind)
{
double x1 = x0;
double x = x1;
int sw = 0;
*ind = 0;
while (sw == 0 && *ind >= 0) {
sw = 1;
*ind += 1;
double g = f(x1);
if (fabs(g) > eps2) {
if (*ind <= max) {
double dg = df(x1);
if (fabs(dg) > eps2) {
x = x1 - g / dg;
if (fabs(x-x1) > eps1 && fabs(x-x1) > eps1*fabs(x)) {
x1 = x;
sw = 0;
}
}
else
*ind = -1;
}
else
*ind = -1;
}
}
return x;
}
// 関数オブジェクト
double newton2(Snx f, DSnx df, double x0, double eps1, double eps2, int max, int *ind)
{
double x1 = x0;
double x = x1;
int sw = 0;
*ind = 0;
while (sw == 0 && *ind >= 0) {
sw = 1;
*ind += 1;
double g = f(x1);
if (fabs(g) > eps2) {
if (*ind <= max) {
double dg = df(x1);
if (fabs(dg) > eps2) {
x = x1 - g / dg;
if (fabs(x-x1) > eps1 && fabs(x-x1) > eps1*fabs(x)) {
x1 = x;
sw = 0;
}
}
else
*ind = -1;
}
else
*ind = -1;
}
}
return x;
}
----------------------(C++11)関数オブジェクトとラムダ式終わり--------------------
/****************************/
/* 関数名の配列 */
/* coded by y.suganuma */
/****************************/
#include <stdio.h>
/*
FP は 2 つの int の引数を受け取り,int を返す関数へのポインタであると宣言
*/
typedef int (*FP) (int, int);
/*
4つの関数を宣言
*/
int add(int, int);
int sub(int, int);
int mul(int, int);
int div(int, int);
int main()
{
int i1, x = 12;
FP f_tb[] = {&add, &sub, &mul, &div}; /* 関数へのポインタ配列 */
for (i1 = 0; i1 < 4; i1++)
printf("result %d\n", f_tb[i1](x, i1+1));
return 0;
}
/********/
/* 加算 */
/********/
int add(int x, int y)
{
return (x + y);
}
/********/
/* 減算 */
/********/
int sub(int x, int y)
{
return (x - y);
}
/********/
/* 乗算 */
/********/
int mul(int x, int y)
{
return (x * y);
}
/********/
/* 除算 */
/********/
int div(int x, int y)
{
return (x / y);
}
result 13 result 10 result 36 result 3
データ型 &別名 = 式;
int &y = x;
x = 10; y = 10;
const
/****************************/
/* 参照渡し */
/* coded by Y.Suganuma */
/****************************/
#include <stdio.h>
void sub(int &, int, int *, char *&, char *, char *);
int main()
{
int x = 10, y = 20, z = 0;
char *d1 = new char[6] {'d', 'a', 't', 'a', '1'};
char *d2 = new char[6] {'d', 'a', 't', 'a', '2'};
char d3[6] = "data3";
printf("x %d y %d z %d d1 %s d2 %s d3 %s\n", x, y, z, d1, d2, d3);
sub(x, y, &z, d1, d2, d3);
printf("x %d y %d z %d d1 %s d2 %s d3 %s\n", x, y, z, d1, d2, d3);
return 0;
}
/********************************/
/* 参照渡しの例 */
/* a : intの参照渡し */
/* b : intのデータ渡し */
/* c : intのアドレス渡し */
/* c1 : アドレスの参照渡し */
/* c2 : アドレスの通常渡し */
/* c3 : 配列の通常渡し */
/********************************/
void sub(int &a, int b, int *c, char *&c1, char *c2, char *c3)
// void sub(const int a, ・・・) とすれば,a の値を変更できない
{
a += 5;
b += 5;
*c = a + b;
c3[1] = 'x';
c1++;
c2++;
c3++;
printf("a %d b %d c %d c1 %s c2 %s c3 %s\n", a, b, *c, c1, c2, c3);
}
x 10 y 20 z 0 d1 data1 d2 data2 d3 data3 a 15 b 25 c 40 c1 ata1 c2 ata2 c3 xta3 x 15 y 20 z 40 d1 ata1 d2 data2 d3 dxta3
/****************************/
/* 参照渡し(参照型関数) */
/* coded by Y.Suganuma */
/****************************/
#include <stdio.h>
int x = 10;
int &sub(int);
int main()
{
int y = 20;
printf("x %d y %d\n", x, y);
/*
現在の変数xの値の参照(関数を右辺)
*/
y = sub(5);
printf("x %d y %d\n", x, y);
/*
変数xに結果を代入(関数を左辺)
*/
sub(100) += 3; // 以下の 2 行でも可
// int& (*z)(int) = ⊂
// z(100) += 3;
printf("x %d y %d\n", x, y);
return 0;
}
/*********************/
/* 関数が変数xの別名 */
/*********************/
int &sub(int a)
{
x += a;
return x;
}
x 10 y 20 x 15 y 15 x 118 y 15
---------------------(C++11)右辺値参照・ムーブセマンティクス-------------------------
int x1 = 10; int& x2 = 10; // error int& x2 = x1; // 左辺値参照 int&& y1 = x1; // error int&& y2 = 20; // 右辺値参照
01 #include <iostream>
02 #include <string>
03
04 using namespace std;
05
06 class Test {
07 public:
08 int *data;
09 // コンストラクタ
10 Test() {
11 data = new int [10000];
12 cout << " (コンストラクタ)";
13 }
14 // copy コンストラクタ
15 Test(const Test& da) {
16 data = new int [10000];
17 copy(da.data, da.data+10000, data);
18 cout << " (copyコンストラクタ)";
19 }
20 // move コンストラクタ
21 Test(Test&& t)
22 {
23 data = t.data;
24 t.data = nullptr;
25 cout << " (moveコンストラクタ)";
26 }
27 // デストラクタ
28 ~Test() {
29 delete [] data;
30 }
31 };
32
33 int main()
34 {
35 // 右辺値参照
36 string&& x = "abc";
37 string y = x;
38 // string&& z = y; // エラー
39 // string&& z = x; // エラー
40 cout << "右辺値参照 x " << x << " &x " << &x << " y " << y << " &y " << &y << endl;
41 x = "xxx";
42 cout << " xを変更 x " << x << " &x " << &x << " y " << y << " &y " << &y << endl;
43 y = "yyy";
44 cout << " yを変更 x " << x << " &x " << &x << " y " << y << " &y " << &y << endl;
45 // move
46 string m3 = "abc";
47 string m4 = m3;
48 cout << "m3 を m4 に代入(普通)m3 " << m3 << " &m3 " << &m3 << " m4 " << m4 << " &m4 " << &m4 << endl;
49 // move(m3); // 何も起こらない
50 string m5 = move(m3);
51 cout << "m3 を m5 に代入(move)m3 " << m3 << " &m3 " << &m3 << " m5 " << m5 << " &m5 " << &m5 << endl;
52 // 右辺値参照の利用
53 cout << "tm を宣言";
54 Test tm{}; // Test tm = Test();
55 tm.data[10] = 10;
56 cout << " tm.data[10] = " << tm.data[10] << endl;
57
58 cout << "tm を t1 に代入,tm の data 変更";
59 Test t1 = tm;
60 tm.data[10] = 20;
61 cout << " t1.data[10] = " << t1.data[10] << " tm.data[10] = " << tm.data[10] << endl;
62
63 cout << "tm を move し t2 へ";
64 Test t2 = move(tm); // tmpは以後使用しない
65 cout << " t2.data[10] = " << t2.data[10] << " tm.data = nullptr\n";
66
67 return 0;
68 }
右辺値参照 x abc &x 0x61fe88 y abc &y 0x61fea0
xを変更 x xxx &x 0x61fe88 y abc &y 0x61fea0
yを変更 x xxx &x 0x61fe88 y yyy &y 0x61fea0
m3 を m4 に代入(普通)m3 abc &m3 0x61feb8 m4 abc &m4 0x61fed0 m3 を m5 に代入(move)m3 &m3 0x61feb8 m5 abc &m5 0x61fee8
tm を宣言 (コンストラクタ) tm.data[10] = 10 tm を t1 に代入,tm の data 変更 (copyコンストラクタ) t1.data[10] = 10 tm.data[10] = 20 tm を move し t2 へ (moveコンストラクタ) t2.data[10] = 20 tm.data = nullptr
----------------------(C++11)右辺値参照・ムーブセマンティクス終わり--------------------
int main()
add 2 3
int main ( int argc, char *argv[], char *envp[] )
/******************************/
/* main関数の引数(数字の和) */
/* coded by Y.Suganuma */
/******************************/
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
/*
引数の内容の出力
*/
printf(" 引数の数 %d\n",argc);
printf(" プログラム名 %s\n",argv[0]);
int i1, k, sum = 0;
for (i1 = 1; i1 < argc; i1++) {
k = atoi(argv[i1]); /* 文字を整数に変換 */
printf(" %d 番目の引数 %d\n", i1+1, k);
sum += k;
}
/*
結果の表示
*/
printf("結果=%d\n", sum);
return 0;
}
引数の数 3
プログラム名 test
2 番目の引数 2
3 番目の引数 3
結果=5
/*******************************/
/* main関数(環境変数の出力) */
/* coded by Y.Suganuma */
/*******************************/
#include <stdio.h>
int main(int argc, char *argv[], char *envp[])
{
int i1 = 0;
while (envp[i1] != NULL) {
printf("%d %s\n", i1+1, envp[i1]);
i1++;
}
return 0;
}
/****************************/
/* 関数名のオーバーロード */
/* coded by Y.Suganuma */
/****************************/
#include <stdio.h>
/****************/
/* 文字列の出力 */
/****************/
void print(char* moji)
{
printf("%s\n", moji);
}
/*****************/
/* double の出力 */
/*****************/
void print(double dbd)
{
printf("%f\n", dbd);
}
/**************/
/* int の出力 */
/**************/
void print(int ind)
{
printf("%d\n", ind);
}
/********/
/* main */
/********/
int main()
{
// 以下,データの型に対応した関数が選択される
print("moji-retu");
print(3.14);
print(100);
return 0;
}
moji-retu 3.140000 100
inline int sub(int x, ・・・)
/*********************************/
/* インライン関数と#defineマクロ */
/* coded by Y.Suganuma */
/*********************************/
#include <stdio.h>
#include <math.h>
#include <time.h>
#define ookisa(x, y) sqrt(x * x + y * y) /* マクロによる計算 */
inline double length1(double, double);
double length2(double, double);
int main()
{
double a = 3.0;
double b = 4.0;
double x;
long i1;
clock_t c1, c2;
/*
マクロによる計算
*/
c1 = clock();
for (i1 = 0; i1 < 1000000; i1++)
x = ookisa(a, b);
c2 = clock();
printf("計算時間は %f 秒です(マクロ)\n", (double)(c2-c1)/CLOCKS_PER_SEC);
/*
インライン関数
*/
c1 = c2;
for (i1 = 0; i1 < 1000000; i1++)
x = length1(a, b);
c2 = clock();
printf("計算時間は %f 秒です(インライン関数)\n", (double)(c2-c1)/CLOCKS_PER_SEC);
/*
普通の関数
*/
c1 = c2;
for (i1 = 0; i1 < 1000000; i1++)
x = length2(a, b);
c2 = clock();
printf("計算時間は %f 秒です(普通の関数)\n", (double)(c2-c1)/CLOCKS_PER_SEC);
return 0;
}
/***************************/
/* sqrt(x*x+y*y)(inline) */
/* x,y : 2つのデータ */
/* return : 結果 */
/***************************/
inline double length1(double x, double y)
{
return sqrt(x * x + y * y);
}
/*******************************/
/* sqrt(x*x+y*y)(普通の関数) */
/* x,y : 2つのデータ */
/* return : 結果 */
/*******************************/
double length2(double x, double y)
{
return sqrt(x * x + y * y);
}
計算時間は 35 秒です(マクロ) 計算時間は 39 秒です(インライン関数) 計算時間は 40 秒です(普通の関数)
/****************************/
/* 例外処理 */
/* coded by Y.Suganuma */
/****************************/
#include <iostream>
#include <math.h>
using namespace std;
void sq(double x, double y)
{
if (x < 0.0 && y < 0.0) {
char *str = "両方とも負\n";
throw str;
}
else if (x < 0.0 || y < 0.0) {
char *str = "片方が負\n";
throw str;
}
double z = sqrt(x+y);
cout << z << endl;
}
int main()
{
try {
double x, y;
cout << "1 つ目のデータは? ";
cin >> x;
cout << "2 つ目のデータは? ";
cin >> y;
sq(x, y);
}
catch (char *str)
{
cout << str;
}
return 0;
}
1.73205 両方とも負
/****************************/
/* 例外処理 */
/* coded by Y.Suganuma */
/****************************/
#include <iostream>
#include <math.h>
#include <string.h>
using namespace std;
class Negative {
public:
char *str;
double x, y;
Negative(char *str, double x, double y) {
this->str = new char [100];
strcpy(this->str, str);
this->x = x;
this->y = y;
}
void message(int sw) {
if (sw == 0)
cout << " 1 番目の値を正にして再実行しました\n";
else
cout << " データを修正してください\n";
}
};
void sq(double x, double y)
{
if (x < 0.0 && y < 0.0)
throw Negative("両方とも負\n", x, y);
else if (x < 0.0 || y < 0.0)
throw Negative("片方が負\n", x, y);
double z = sqrt(x+y);
cout << z << endl;
}
int main()
{
try {
double x, y;
cout << "1 つ目のデータは? ";
cin >> x;
cout << "2 つ目のデータは? ";
cin >> y;
sq(x, y);
}
catch (Negative &ng)
{
cout << ng.str;
if (ng.y > 0.0) {
ng.message(0);
sq(-ng.x, ng.y);
}
else
ng.message(1);
}
return 0;
}
片方が負
1 番目の値を正にして再実行しました
1.73205 ---------------------(C++11)例外処理-------------------------
int function( ・・・・・ ) noexcept
{
・・・・・
} ----------------------(C++11)例外処理終わり--------------------
| 情報学部 | 菅沼ホーム | 全体目次 | 演習解答例 | 付録 | 索引 |