1. 程式人生 > >第八,九章

第八,九章

這一章主要講了字串操作庫函式 其中以前沒太知道的strtok字串分隔函式(很有用。) strchr(查詢第一個字元出現的位置) strncat,strncpy等等。

然後介紹了指標 (包括了void*指標(以前我都不知道有著玩意。。超級有用)指向函式的指標(以前覺得根本沒啥用。。現在發現真是有大用處。。都想看看侯傑的書,自己實現一部分STL的功能了。。))

還有memset為什麼不能賦值整數。。寫了一部分習題之後才明白 memset的實現是按位元組賦值的。。整數是4個位元組的。。

學的東西還是非常有用的 。 真的補充了不少以前沒學好和沒注意到的知識點。

貼幾個比較有意思的習題 

/* 描述
填寫記憶體交換函式 SwapMemory,使得程式輸出指定結果
*/
#include <iostream>
using namespace std;
void SwapMemory(void * m1, void * m2, int size)
{
	char* p = new char;
	for (int i = 0; i < size; i++) {
		*p = *((char*)m1+i);
		*((char*)m1 + i) = *((char*)m2 + i);
		*((char*)m2 + i) = *p;
	}
}

void PrintIntArray(int * a, int n)
{
	for (int i = 0; i < n; ++i)
		cout << a[i] << ",";
	cout << endl;
}

int main()
{
	int a[5] = { 1,2,3,4,5 };
	int b[5] = { 10,20,30,40,50 };
	SwapMemory(a, b, 5 * sizeof(int));
	PrintIntArray(a, 5);
	PrintIntArray(b, 5);
	char s1[] = "12345";
	char s2[] = "abcde";
	SwapMemory(s1, s2, 5);
	cout << s1 << endl;
	cout << s2 << endl;
	return 0;
}


/*
  6:指標練習:Memcpy之二
  此題要求完成任意型別的變數之間的拷貝(而且變數之間有可能共佔一片記憶體區域)
  我自己寫的是開一個新的記憶體區域 先把一個變數內容拷貝過去 在拷貝到dest..
  後來發現有個更好的寫法 就是比較ori 和 dest陣列
  從而決定是從前往後還是從後往前拷貝
  貼自己的程式碼了。。
*/
#include <iostream>
using namespace std;
void Memcpy(void * src, void * dest, int size)
{
	char* a = (char*)malloc(size * sizeof(char));
	/* 防止院陣列和目標記憶體有重疊 */
	for (int i = 0; i < size; i++) {
		a[i] = *((char*)src + i);
	}
	for (int i = 0; i < size; i++) {
		*((char*)dest + i) = a[i];
	}
	free(a);
}

void Print(int * p, int size)
{
	for (int i = 0; i < size; ++i)
		cout << p[i] << ",";
	cout << endl;
}

int main()
{
	int a[10];
	int n;
	cin >> n;
	for (int i = 0; i < n; ++i)
		cin >> a[i];
	int b[10] = { 0 };
	Memcpy(a, b, sizeof(a));
	Print(b, n);

	int c[10] = { 1,2,3,4,5,6,7,8,9,10 };
	Memcpy(c, c + 5, 5 * sizeof(int)); //將c的前一半拷貝到後一半 
	Print(c, 10);

	char s[10] = "123456789";
	Memcpy(s + 2, s + 4, 5); //將s[2]開始的5個字元拷貝到s[4]開始的地方 
	cout << s << endl;

	char s1[10] = "123456789";
	Memcpy(s1 + 5, s1 + 1, 4); //將s1[5]開始的4個字元拷貝到s1[1]開始的地方 
	cout << s1 << endl;


	return 0;
}

/*
  7:指標練習:MyMax
  編寫一個 MyMax函式,可以用來求任何陣列中的最大值 使得程式按要求輸出(我只能說void*指標和指向函式的指標太強大了。。)
*/
#include <iostream>
using namespace std;
void* MyMax(void* a, int width, int len, int(*p)(void*, void*)) {
	char*q = (char*)a;
	void * Max;
	Max = a;
	for (; len--; q += width) {
		if (p(Max, q) < 0) {
			Max = q;
		}
	}
	return Max;
}
int Compare1(void * n1, void * n2)
{
	int * p1 = (int *)n1;
	int * p2 = (int *)n2;
	return ((*p1) % 10) - ((*p2) % 10);
}
int Compare2(void * n1, void * n2)
{
	int * p1 = (int *)n1;
	int * p2 = (int *)n2;
	return *p1 - *p2;
}
#define eps 1e-6
int	Compare3(void * n1, void * n2)
{
	float * p1 = (float *)n1;
	float * p2 = (float *)n2;
	if (*p1 - *p2 > eps)
		return 1;
	else if (*p2 - *p1 > eps)
		return -1;
	else
		return 0;
}

int main()
{
	int t;
	int a[10];
	float d[10];
	cin >> t;
	while (t--) {
		int n;
		cin >> n;
		for (int i = 0; i < n; ++i)
			cin >> a[i];
		for (int i = 0; i < n; ++i)
			cin >> d[i];
		int * p = (int *)MyMax(a, sizeof(int), n, Compare1);
		cout << *p << endl;
		p = (int *)MyMax(a, sizeof(int), n, Compare2);
		cout << *p << endl;
		float * pd = (float *)MyMax(d, sizeof(float), n, Compare3);
		cout << *pd << endl;
	}
	return 0;
}