NekoC

猫でもわかるC言語の個人的なまとめ資料

View on GitHub

11_高度なプログラミング.md

ポインタを返す関数

サンプルコード


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

char *mystrcat(char *str1, char *str2);

int _tmain(int argc, _TCHAR* argv[])
{
	char str1[16] = "abc";
	char str2[16] = "def";

	printf("%s\n", mystrcat(str1, str2));
	return 0;
}

char *mystrcat(char *str1, char *str2){
	char *ptr;
	int n = 0;

	ptr = str1 + strlen(str1);
	while (*(ptr + n) = *(str2 + n)){
		n++;
	}

	return str1;
}

出力結果


abcdef

サンプルコード2

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

char* mystrcat(char* str1, char* str2);

int main(){

	char str1[32] = "Hello, ";
	char str2[16] = "World!\n";

	printf(mystrcat(str1, str2));
	return 0;
}

char *mystrcat(char* str1, char* str2){
	char *aorg;
	aorg = str1;
	while (*str1){
		str1++;
	}
	while (*str1++ = *str2++);

	return aorg;
}

出力結果

Hello, World!

関数へのポインタ

関数のアドレス

pritf("main関数のアドレス = %p\n",main);
pritf("func関数のアドレス = %p\n",func);

関数へのポインタ


int (*ptr)(); //intは戻り値の型

サンプルコード

#include <stdio.h>

int main(){
	int myFunc(char*,char*);//プロトタイプ宣言
	int(*ptr)(char*, char*); // 関数へのポインタ

	ptr = myFunc;

	(*myFunc)("田中", "学生");
	(*ptr)("小西", "会社員");
	myFunc("佐藤", "自衛官");

	return 0;
}

int myFunc(char *str1, char *str2){
	printf("%sさんは、%sです。\n", str1, str2);
	return 0;
}

出力結果

田中さんは、学生です。
小西さんは、会社員です。
佐藤さんは、自衛官です。

関数のポインタの配列

サンプルプログラム

#include <stdio.h>
#include <stdlib.h>
#include "Calcarea.h"

int main(){
	double(*func[3])() = { triangle, trapezoid, circle };
	char ret[8];
	int funcNo;

	while (1){
		printf("Which figure you want calcrate area?\n"
			"1: triangle 2: trapezoid 3: circle 4: exit\n");
		gets_s(ret);
		if (ret[0]<'0' || ret[0] > '3'){
			printf("番号が不正です。\n");
			continue;
		}
		ret[1] = '\0';
		funcNo = atoi(ret);
		if (funcNo == 0){
			break;
		}
		double area = func[funcNo - 1]();
		printf("面積は%fです。\n", area);
	}
		return 0;
}

出力結果


Which figure you want calcrate area?
1: triangle 2: trapezoid 3: circle 4: exit
1
Calculate the area of ??the triangle.
input Base value ... 10
input height value ... 2
面積は10.000000です。
Which figure you want calcrate area?
1: triangle 2: trapezoid 3: circle 4: exit
2
Calculate the area of ??the trapezoid.
input upperBase value ... 5
input bottom value ... 2
input height value ... 8
面積は28.000000です。
Which figure you want calcrate area?
1: triangle 2: trapezoid 3: circle 4: exit
0

可変個の引数を持つ関数の作成

  1. stdarg.hをincludeする。
  2. 関数の形はint func(int arg, ...);
  3. 関数内でva_list型変数(ポインタ)を宣言する。
  4. va_start(3.で宣言したポインタ、オプション引数の型);va_end(3.で宣言したポインタ)という2つのマクロで挟まれた部分で、オプション引数を取得する。
  5. 最初のオプション引数は「va_arg(3.で宣言したポインタ,オプション引数の型);」というマクロで取得する。
    • va_argマクロをもう一度呼び出すと次のオプション引数を受け取ることが可能。

サンプルコード

#include <stdio.h>
#include <stdarg.h>

int myfunc(int a, ...);

int main(){
	int wa;

	wa = myfunc(4, 1, 2, 3, 4);
	printf("wa = %d\n", wa);
	wa = myfunc(2, 100, -45);
	printf("wa = %d\n", wa);

	return 0;
}

int myfunc(int x, ...){
	va_list ptr;
	int i, sum = 0;

	va_start(ptr, x);
	for (i = 0; i < x; i++){
		sum += va_arg(ptr, int);
	}
	va_end(ptr);

	return sum;
}

出力結果

wa = 10
wa = 55

サンプルコード2

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

char* myfunc(char*, ...);

int main(){

	char str1[256] = "Today is "; /*十分な余白を確保しておく*/
	char *str2 = "sunny, but";
	char *str3 = "I don't know what the weather is tommorow\n";
	myfunc(str1, str2, str3,"");
	printf(str1);
	return 0;
}

char* myfunc(char* p, ...){
	va_list ptr;
	char *str;

	if (p[0] == '\0'){
		return p;
	}

	va_start(ptr, p);
	while (1){
		str = va_arg(ptr, char *);
		if (str[0] == '\0'){
			break;
		}
		strcat_s(p, 256,str);
		}
	va_end(ptr);
	return p;
}

出力結果

Today is sunny, butI don't know what the weather is tommorow