Bootstrap

习题20240715~16

一、使用C语言写出数组指针,指针数组,函数指针,指针函数的定义和使用示例。

指针数组

一个数组中保存的元素都是指针,称为指针数组。
int *p[10]

#include <stdio.h>


int main() {
	int a[] = { 1,2,3,4,5 };
	int b[] = { 6,7,8,9,0};
	int c[] = { 1,2,3,4,5 };

	int* arr[] = { a,b,c };

	for (int i = 0; i < 3; i++) {
		for (int j = 0; j < 5; j++) {
			printf("%d", *(arr[i] + j));
		}
		printf("\n");
	}
}

数组指针

数组指针是指向数组的指针,用来存放数组的地址。
int (*p)[10]

#include <stdio.h>


int main() {
	int a[3][4] = { 0,1,2,3,4,5,6,7,8,9,10,11 };
	int(*p)[4];
	p = a;
	for (int i = 0; i < 3; i++) {
		for(int j = 0; j < 4; j++) {
			printf("%2d   ", *(*(p + i) + j));
		}
		printf("\n");
	}
}

函数指针

函数指针是指向函数的指针变量。

#include <iostream>

int add(int x, int y) {
	return x + y;
}

int substract(int x, int y) {
	return x - y;
}

int (*p)(int, int);
int main() {
	

	p = add;
	printf("相加:%d\n", p(1, 2));

	p = substract;
	printf("相减:%d\n", p(2, 1));
}


指针函数

一个返回指向函数的指针的函数。

#include <iostream>

int add(int x, int y) {
	return x + y;
}

int substract(int x, int y) {
	return x - y;
}

int(* a())(int, int) {
	return add;
}

int(*b(int chose))(int, int) {
	if (chose == 1) {
		return substract;
	}
}


int main() {
	int(*p)(int, int);
	p = a();
	printf("%d\n", p(2, 1));

	p = b(1);
	printf("%d\n", p(2, 1));
	
}

二、使用C语言实现一个单向链表,实现初始化节点,增添节点(头插法和尾插法),删除节点,显示节点功能。

#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <assert.h>
using namespace std;

typedef struct LNode {
	int data;
	struct LNode* next;
}*LinkNode;
//初始化
void InistLinkNode(LinkNode& L) {
	L = (LNode*)malloc(sizeof(LNode));
	L->next = NULL;
}

//头插法
void InsertLinkNode(LinkNode& L) {
	LNode* s;
	int x, Length;
	printf("请输入你要插入的元素个数:");
	scanf("%d", &Length);
	printf("请输入你要插入的元素:\n");
	for (int j = 0; j < Length; j++) {
		s = (LNode*)malloc(sizeof(LNode));
		scanf("%d", &x);
		s->data = x;
		s->next = L->next;
		L->next = s;
	}
}
//尾插法
void TailInsertLinkNode(LinkNode& L) {
	LNode* s, * r;
	int x, Length;
	r = L;
	printf("请输入你要插入的元素个数:");
	scanf("%d", &Length);
	printf("请输入你要插入的元素:\n");
	for (int j = 0; j < Length; j++) {
		s = (LNode*)malloc(sizeof(LNode));
		scanf("%d", &x);
		s->data = x;
		r->next = s;
		r = s;
	}
	printf("\n");
	r->next = NULL;
}

//输出单链表
void PrintLinkNode(LinkNode& L) {
	LNode* s = L->next;
	printf("单链表元素如下:\n");
	while (s != NULL) {
		printf("%d", s->data);
		s = s->next;
	}
	printf("\n");
}

//删除节点
void DeleteLinkNode(LinkNode& L) {
	int x, j = 0, e;
	printf("请输入你要删除的元素位序:\n");
	scanf("%d", &x);
	LNode* p = L;
	while (p != NULL && j < x - 1) {
		p = p->next;
		j++;
	}
	if (p == NULL) {
		printf("不存在要删除的元素");
	}
	if (p->next == NULL) {
		printf("不存在要删除的元素");
	}
	LNode* q = p->next;
	e = q->data;
	p->next = q->next;
	free(q);
}

三、写出委托(delegate)的定义,和委托的使用示例

C#中的委托类似于C和C++中的指针,delegate是存有对某个方法的引用的一种引用类型变量,可在运行时改变。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;

public delegate void HelloDelegate();
internal class Program
{
    static void Main(string[] args)
    {
        HelloDelegate helloDelegate = new HelloDelegate(Hello);
        helloDelegate += World;
        helloDelegate.Invoke();

        Console.WriteLine("-----------");

        helloDelegate -= World;
        helloDelegate.Invoke();
    }
    public static void Hello() => Console.WriteLine("你好啊");
    public static void World() => Console.WriteLine("世界");
}

四、写出Action,Func,Predicate的功能定义,并给出示例,并使用表格形式区分三者在参数,返回值,参数个数,使用场景上的异同点。

Action

表示无参、无返回值的泛型委托。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection.Metadata.Ecma335;

void SayHello()
{
    Console.WriteLine("Hello World");
}
Action noPara = SayHello;

noPara();

Func

表示无参、返回值为int的泛型委托。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection.Metadata.Ecma335;

static int Test1()
{
    return 2;
}


    Func<int> a = Test1;
    Console.WriteLine(a());

Predicate

表示传入参数为int,返回值为bool型的泛型委托。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection.Metadata.Ecma335;

static bool FindPoints (int a)
{
    return a >= 60;
}

Predicate<int> predicate = FindPoints;
Console.WriteLine(predicate(69));
委托类型参数返回值参数个数使用场景
Action0~16观察者模式
Funcint0~16观察者模式
Predicateintbool1观察者模式

五、思考:Func能否完全兼容Predicate,Predicate存在的意义?

Func不能完全兼容Predicate,Predicate是对Func<T,bool>的简化。

;