Salvador del lenguaje C (función y recursividad--4)

contenido

1.1: Funciones de biblioteca

Ejercicio 1: escribe una función para intercambiar el contenido de dos variables enteras Ejercicio 2: escribe una función para determinar si un número es primo o no

Ejercicio 2: Escribe una función para determinar si un número es primo o no

Ejercicio 3: escriba una función que implemente una búsqueda binaria de una matriz ordenada de enteros.

2.1: Llamadas anidadas y acceso encadenado de funciones

2.2 Ejercicio: ¿Cuál es la salida del siguiente código?

3.1: Declaración de función + importación de biblioteca estática

4.1: Recursión e Iteración

Ejercicio 4.1: Tome un valor entero (sin signo) e imprima sus bits en orden

 Ejercicio 4.2: Escribe una función que no permita la creación de variables temporales, encuentra la longitud de una cadena

4.3: Encuentra el factorial de n (siempre que conozcas la fórmula matemática, es código recursivo)

4.4: Encuentra el n-ésimo número de Fibonacci (la suma de los dos primeros números es igual al tercer número)


1.1: Funciones de biblioteca

Cada programador puede utilizarlo durante el desarrollo, para apoyar la portabilidad y mejorar la eficiencia del programa. Por lo tanto, la biblioteca básica del lenguaje C proporciona una serie de funciones de biblioteca similares, lo cual es conveniente para que los programadores desarrollen software, mejoren la eficiencia del desarrollo y estandaricen el código.

1.2: Funciones personalizadas

Al igual que las funciones de biblioteca, las funciones personalizadas tienen nombres de función, tipos de valor de retorno y parámetros de función. Pero la diferencia es que todos estos están diseñados por nosotros. Esto les da a los programadores mucho espacio para jugar.


Ejercicio 1: escribe una función para intercambiar el contenido de dos variables enteras Ejercicio 2: escribe una función para determinar si un número es primo o no

当实参传给形参的时候,形参是实参的一份临时拷贝,对形参的修改不会影响实参



void swap2(int* pa, int* pb)
{
	int tmp = *pa;
	*pa = *pb;
	*pb = tmp;
}

int main()
{
	int a = 0;
	int b = 0;
	scanf("%d %d", &a, &b);

	printf("交换前:a=%d,b=%d\n", a, b);

	int* p1 = &a;
	int* p2 = &b;

  swap2(&a, &b);

	printf("交换后:a=%d,b=%d\n", a, b);

	return 0;
}

La llamada por referencia es una forma de llamar a una función pasando la dirección de memoria de una variable creada fuera de la función al parámetro de función.

Este método de pasar parámetros permite que la función establezca una conexión real con las variables fuera de la función, es decir, la función puede operar directamente las variables fuera de la función.


Ejercicio 2: Escribe una función para determinar si un número es primo o no

int is_prime(int n)
{
	int j = 0;
	for (j = 2; j <= n-1; j++)
	{
		if (n % j == 0)
		{
			return 0;
		}
	}
	return 1;
}

int main()
{
	//打印100~200之间的素数
	int i = 0;
	for (i = 100; i <= 200; i++)
	{
		//判断i是否为素数
		if (is_prime(i) == 1)
		{
			printf("%d ", i);
		}
	}
	return 0;
}

Ejercicio 3: escriba una función que implemente una búsqueda binaria de una matriz ordenada de enteros.

int binary_search(int arr[], int k, int sz)
{
	int left = 0;
	int right = sz - 1;

	while (left<=right)
	{
		int mid = left + (right - left) / 2;
		if (arr[mid] < k)
		{
			left = mid + 1;
		}
		else if (arr[mid] > k)
		{
			right = mid - 1;
		}
		else
		{
			return mid;
		}
	}

	return -1;//找不到
}


int main()
{
	//
	//数组在传参的时候,传递不是整个数组,传递是数组首元素的地址
	//
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int k = 0;
	scanf("%d", &k);//要查找的元素
	int sz = sizeof(arr) / sizeof(arr[0]);
	int ret = binary_search(arr, k, sz);
	if (-1 == ret)
		printf("找不到\n");
	else
		printf("找到了,下标是:%d\n", ret);

	return 0;
}


2.1: Llamadas anidadas y acceso encadenado de funciones

Las funciones se pueden llamar anidadas (por ejemplo, la función principal llama a otras funciones) y no se pueden definir anidadas

void test()
{
}


int main()
{
   return 0;    可以
}



int main()
{
     void test()
{

}

   return 0;    不可以
}

Acceso encadenado (pasar el valor de retorno de una función como argumento a otra función)

int main()
{
	//int len = strlen("abcdef");
	//printf("len = %d\n", len);
    
    上面两句代码可以写成:

	printf("len = %d\n", strlen("abcdef"));

	return 0;
}

2.2 Ejercicio: ¿Cuál es la salida del siguiente código?

int main()
{
	
	printf("%d", printf("%d", printf("%d", 43)));

	return 0;
}

Respuesta: 4321

Explicación: Primero imprime 43, (el valor de retorno de printf es de tipo int, printf devuelve el número de caracteres impresos), luego devuelve 2,1 a su vez


3.1: Declaración de función + importación de biblioteca estática

//int Add(int x,int y);   //让编译器不再报警告,相当于告诉编译器我这里有一个Add函数
                          //返回类型int,函数名Add,函数参数int x,int y



int main()
{
	int a = 10;
	int b = 20;
	int sum = Add(a, b);//函数的使用
	printf("%d\n", sum);
	return 0;
}

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

La función Agregar está después de la función principal, el compilador no encuentra la función Agregar de la función principal e informa una advertencia.

Para que el compilador no informe, necesitamos escribir una declaración de función antes de la función principal

También podemos crear un nuevo archivo de encabezado Add.h y poner la declaración de la función en el archivo de encabezado

No queremos exponer el código escrito por nosotros mismos, podemos compilar el archivo fuente en una biblioteca estática (haga clic con el botón derecho en el archivo fuente -> propiedades)

La biblioteca estática almacena información binaria, busque el archivo Add.lib y el archivo Add.h

Use la función Agregar para no exponer los archivos de origen escritos por usted mismo, pero también permita que otros los usen

#include "add.h" //包含头文件

#pragma comment(lib, "add.lib")//导入静态库

Lo mismo es cierto para las funciones de biblioteca (¡has aprendido a usarlas! A continuación, escribe un compilador)


4.1: Recursión e Iteración

¿Qué es la recursividad?

El truco de programación de un programa que se llama a sí mismo se llama recursión.

Por lo general, un problema grande y complejo se transforma en un problema similar de menor escala para resolver.

Una pequeña cantidad de código resuelve múltiples operaciones repetidas y reduce la cantidad de código

Principal forma recursiva de pensar: hacer pequeñas las cosas grandes

Dos condiciones necesarias para la recursividad

1: Hay una restricción Cuando se cumple esta restricción, la recursividad no continuará.

2: Acérquese más y más a este límite después de cada llamada recursiva .


Ejercicio 4.1: Tome un valor entero (sin signo) e imprima sus bits en orden

Por ejemplo 1234, salida 1 2 3 4

void print(int n)
{
	if (n > 9)  //1:存在限制条件,当满足这个限制条件的时候,递归便不再继续。
	{
		print(n/10);  //2:每次递归调用之后越来越接近这个限制条件。
	}
	printf("%d ", n % 10);
}


int main()
{
	unsigned int num = 0;
	scanf("%d", &num);//1234
    
    //解题步骤:
    //1234%10=4   得到4
	//1234/10=123
	//123%10=3    得到3
	//...
	//[4 3 2 1]   得到4 3 2 1
	//

	print(num);//print函数可以把num的每一位按照顺序打印出来

	return 0;
}

recursión

 volver al final de la recursividad


 Ejercicio 4.2: Escribe una función que no permita la creación de variables temporales, encuentra la longitud de una cadena

 No use recursividad, escritura general


int my_strlen(char* str)
{
	int count = 0;//统计字符的个数
	while (*str != '\0')
	{
		count++;
		str++;
	}
	return count;
}


int main()
{
	char arr[] = "abcd";
	//char* str = arr;
	int len = my_strlen(arr);
	printf("%d\n", len);
	return 0;
}

usar recursividad

//my_strlen("abcdef")
//1+my_strlen("bcdef")
//1+1+my_strlen("cdef")
//1+1+1+ my_strlen("def")
//1+1+1+1+ my_strlen("ef")
//1 + 1 + 1 + 1 +1+my_strlen("f")
//1 + 1 + 1 + 1 + 1 + 1+ my_strlen("")
//1 + 1 + 1 + 1 + 1 + 1 + 0 = 6


int my_strlen(char* str)
{
	if (*str != '\0')
		return 1 + my_strlen(str+1);
	else
		return 0;
}

int main()
{
	char arr[] = "abcd";
	//char* str = arr;
	int len = my_strlen(arr);
	printf("%d\n", len);
	return 0;
}

 


4.3: Encuentra el factorial de n (siempre que conozcas la fórmula matemática, es código recursivo)

   Cuando n<=1, n =1;

   n!=nx(n-1) cuando n>1

int fac1(int n)
{
	if (n <= 1)
		return 1;
	else
		return n * fac(n - 1);  
}

int fac(int n)
{
	int i = 0;
	int ret = 1;
	for (i = 1; i <= n; i++)
	{
		ret = ret * i;
	}
	return ret;                 //非递归,迭代
}

int main()
{
	int n = 0;
	scanf("%d", &n);
	int ret = fac(n);
	printf("%d\n", ret);

	return 0;
}

4.4: Encuentra el n-ésimo número de Fibonacci (la suma de los dos primeros números es igual al tercer número)

递归
int fib(int n)

	if (n <= 2)
		return 1;
	else
		return fib(n - 1) + fib(n - 2);
}

int main()
{
	int n = 0;
	scanf("%d", &n);
	int ret = fib(n);
	printf("%d\n", ret);
	return 0;
}

Cuando el número de Fibonacci requerido es muy grande, el proceso de cálculo repetido también es muy grande. En este momento, el algoritmo recursivo no es tan bueno. Para calcular el número de Fibonacci 50, el compilador necesita ejecutarlo durante mucho tiempo.

Para resolver F(n), F(n-1) y F(n-2) deben calcularse primero, F(n-1) y F(n-2) deben calcularse, y F(n-3) y F debe calcularse primero (n-4). . . . . . Y así sucesivamente, hasta que F(1) y F(0) deban calcularse primero, y luego invertirse para obtener los resultados de F(n-1) y F(n-2), de modo que F(n) requiera muchos cálculos repetidos. valores a calcular, causando una gran pérdida de tiempo. La complejidad temporal del algoritmo aumenta exponencialmente con el aumento de N, y la complejidad temporal es O(2^n), es decir, 2 elevado a la n-ésima potencia

非递归
int fib(int n)
{
	int a = 1;
	int b = 1;
	int c = 1;

	while (n>2)
	{
		c = a + b;
		a = b;
		b = c;
		n--;
	}

	return c;
}


int main()
{
	int n = 0;
	scanf("%d", &n);
	int ret = fib(n);
	printf("%d\n", ret);
	return 0;
}

 Comience el cálculo desde n(>2) y use los dos números F(n-1) y F(n-2) para calcular el resultado, lo que evita muchos cálculos repetidos y su eficiencia es mucho más rápida que la recursiva. algoritmo, la complejidad temporal del algoritmo es proporcional a n, es decir, la complejidad temporal del algoritmo es O(n).

Supongo que te gusta

Origin blog.csdn.net/weixin_63543274/article/details/123287040
Recomendado
Clasificación