Primeros pasos con C++——Day6_C++ Módulo de programación funcional

1. Repasar los conocimientos básicos de funciones

 

Funciones de biblioteca

función personalizada

Escriba un programa primero, revise la función personalizada

#include <iostream>

void simple(void);
using namespace std;

int main(void)
{

    cout << "main() will call the somple() function " << endl;
    simple();

    return 0; 
}
void simple(void)
{
    cout << "I'm simple but a function." << endl;
}

Hay tres partes en una función personalizada:

Definición de función, declaración de función, llamada de función, todos son indispensables

1: Definir la función

Las funciones se dividen en las que devuelven un valor y las que no.

Si no hay valor devuelto, es una función nula. El formato general es el siguiente:

void nombre de función (lista de parámetros)

{

        declaraciones)

        return; //Se puede escribir o no, y generalmente no se escribe si no hay valor de retorno

}

La paramenterList se refiere al tipo y número de parámetros pasados ​​a la función, por ejemplo:
void cheers (int n)

{

         para(int i = 0; i <n; i++)

                cout << "¡Salud!";

        cout << endl;

}

El int aquí significa que al llamar a la función cheers, se le debe pasar un valor Int como parámetro

Una función que devuelve un valor generará un valor y lo devolverá a la función que llama. El formato general es el siguiente:

typeName functionName(paramterList)

{

         declaraciones;

        valor de retorno;

}

Para las funciones que devuelven un valor, se debe usar una declaración de devolución para devolver el valor a la función que llama.

El valor en sí puede ser una constante, una variable o una expresión, pero el tipo del resultado debe ser typeName o puede convertirse a typeName (por ejemplo, si nuestro tipo de retorno es doble, pero se devuelve una expresión int, se forzará int al tipo doble)

C++ tiene restricciones sobre el tipo de valor devuelto: no puede ser una matriz , pero puede ser de cualquier otro tipo, como un objeto de estructura, etc. (pero una matriz puede devolverse como un componente de una estructura u objeto)

La función finaliza después de ejecutar la declaración de devolución. Si una función contiene varias declaraciones de retorno, la ejecución de la función finaliza después de encontrar la primera declaración de retorno.

int mayor (int a , int b)

{

        si (a > b)

                devolver un;

        demás

                volver b;

}

2: prototipo de función y llamada de función

Mire el siguiente programa para experimentar funciones personalizadas con y sin valores de retorno

#include <iostream>

using namespace std;
void cheers(int n);//声明
double cube(double x);

int main(void)
{
    cheers(5);//调用
    
    cout << "Give me a number: " << endl;
    double side;
    cin >> side;
    
    double volume = cube(side);
    cout << side << " side cube = " << volume << endl;

    cheers(cube(2));  //自定义函数调用自定义函数,并进行double转int的操作

    return 0; 
}
void cheers(int n)      //无返回值
{
    for (int i = 0; i < n; i++)
    {
        cout << "Cheers!" << endl;
    }
}
double cube(double x)     //有返回值
{
    x = x * x * x;
    return x;
}

resultado:

¡Salud!
¡Salud!
¡Salud!
¡Salud!
¡Salud!
Dame un número:
3
cubo de 3 lados = 27
¡Salud!
¡Salud!
¡Salud!
¡Salud!
¡Salud!
¡Salud!
¡Salud!
¡Salud!

*

1) Saludos personalizados sin valor de devolución, cubo personalizado con valor de devolución

2) Tome la entrada como parámetro del cubo y devuelva el tipo doble

3) Los vítores de la función personalizada se refieren al cubo de funciones personalizadas

1) ¿Por qué necesita un prototipo?
Es por eso que debe declararlo nuevamente en el archivo de encabezado

El prototipo de función describe la estructura de la función al compilador, es decir, le dice al compilador el tipo de valor de retorno y la cantidad de tipos de parámetros de la función.

Después de que la función cube() completa el cálculo, coloca el valor de retorno en la ubicación especificada; puede ser un registro, puede ser memoria, y luego llama a la función (main()) para obtener el valor de retorno de este

El compilador de C++ no buscará más en el archivo, que es demasiado ineficiente, por lo que es mejor proporcionar un prototipo.

2) Sintaxis de Prototipos

El prototipo de función no necesita proporcionar nombres de variables, la lista de tipos es suficiente . Por ejemplo, para el prototipo cheer(), solo proporcionamos el tipo de parámetro:

saludos vacíos (int);

Por ejemplo, si vamos a cenar a un restaurante, solo necesitamos llamar y decirle al restaurante cuántas personas tenemos, qué tipo de comida comemos y cuántas personas tenemos, en lugar de decirle al restaurante el nombre de cada uno. persona.

Así que digamos el siguiente prototipo:

¡El cubo doble (doble x) se puede compilar como cubo doble (doble)!

3) La función del prototipo

Asegúrese de lo siguiente:

El compilador maneja correctamente los valores de retorno de la función;

El compilador verifica que se use el número correcto de argumentos

El compilador comprueba que los tipos de parámetros utilizados son correctos

Sin embargo, si un tipo de datos más grande se convierte en un tipo más pequeño, algunos compiladores emitirán una advertencia de que se pueden perder datos.

Por ejemplo, si 2.33E27 se convierte a tipo int, este valor no se convertirá correctamente

2. Parámetros de la función y paso por valor

C++ generalmente pasa parámetros por valor, lo que significa pasar un parámetro numérico a la función, que a su vez lo asigna a una nueva variable

Por ejemplo: doble volumen = cubo (lado);

→ lado es una variable, previamente definida como 5

El encabezado de la función del cubo es el siguiente: doble cubo (doble x)

→ Cuando se llama a la función, la función crea una nueva variable doble llamada x y la inicializa a 5

→ De esta manera, las operaciones realizadas por cube() no afectarán los datos en main().

→ El cubo usa una copia del lado, no los datos originales

La variable utilizada para recibir el valor pasado se denomina parámetro formal, como la doble x aquí

El valor pasado a la función se denomina parámetro real, como el lado original

1: múltiples parámetros

1) Si en una función se definen dos variables, aunque sean del mismo tipo, deben escribirse completas

void fifi (flotante a, flotante b)

2) Al igual que un parámetro, el nombre de la variable en el prototipo no tiene que ser el mismo que el nombre de la variable en la definición, e incluso se puede omitir, pero es mejor anotarlo, al menos saber para qué se usa.

Vea el siguiente programa: Demuestre que la modificación de los parámetros formales no afectará los datos en la función de llamada

#include <iostream>

using namespace std;

void n_chars(char c, int n);

int main(void)
{
    char ch;
    int times;

    cout << "Please enter a character: ";
    cin >> ch; //cin.get()也行

    while(ch != 'q')
    {
        cout << "Enter a integer: ";
        cin >> times;

        n_chars(ch,times);
        cout << endl;
        cout << "Enter another character or press q_key to quie: " << endl;
        cin >> ch;
    }
    return 0; 
}

void n_chars(char c, int n)
{
    while (n-- >0)
    {
        cout << c;
    }
}

resultado:

Por favor ingrese un caracter:

1
Ingrese un número entero: 10
1111111111
Ingrese otro carácter o presione q_key para silenciar:
q

 

*

1) Declare ch y times como los dos parámetros de n_chars respectivamente, y luego devuelva el contenido a través de la función

2: Otra función que recibe dos parámetros

Los temas son los siguientes:

Muchos estados de los Estados Unidos utilizan algún tipo de juego de cartas para emitir loterías que permiten a los participantes elegir una cierta cantidad de opciones de las cartas.

Por ejemplo: se seleccionan 6 números de 51 números, y luego el gerente selecciona aleatoriamente 6 números. Si el jugador elige exactamente el mismo número que estos 6, gana millones de dólares. La función calcula la probabilidad de ganar

En primer lugar, se deben seleccionar 6 números de 51 números, y la probabilidad de ganar es 1/R, y la fórmula de cálculo de R es:

R=\frac{51\times 50\times 49\times 48\times 47\times 46}{6\times 5\times 4\times 3\times 2\times 1}

¡Al elegir 6 números, el denominador es 6! , el numerador es el producto de 6 enteros consecutivos, decreciendo continuamente desde 51, que se puede calcular usando un ciclo for

resultado doble largo = 1.0;

for(n = números , p = selecciones ; p > 0 ; n-- , p--) (números es cuántos números elegir)

        resultado = resultado * n / p; (pick es el número de números seleccionados)

programa:

#include <iostream>

using namespace std;
long double probability(unsigned int numbers,unsigned int picks);

int main(void)
{
    unsigned int total,choices;
    cout << "Enter the total number of choices on the game card and the number of picks allowed: " << endl;
    while((cin >> total >> choices) && choices <= total)
    {
        cout << "You have one chance in " << probability(total,choices) << " of winning";
        cout << "Please enter next two number(q to quit)";
    }
    cout << "Bye";
    
    return 0; 
}
long double probability(unsigned int numbers,unsigned int picks)
{
    double n,p;
    long double result = 1.0;

    for(n = numbers, p = picks; p > 0; n--,p--)
        result = result * (n / p);

    return result;
}

Resultado (la salida es R, la probabilidad es 1/R):

Ingrese el número total de opciones en la tarjeta de juego y el número de selecciones permitidas:
49
6
Tiene una oportunidad en 1.39838e+07 de ganarIngrese los dos números siguientes (q para salir) 100
10
Tiene una oportunidad en 1.73103e+13 de ganarIngrese los dos números siguientes (q para salir)

*

1) Este programa demuestra que se pueden usar dos tipos de variables locales en una función.

El primero son los parámetros formales (números y selecciones); el segundo son otras variables locales (resultado, n, p)

La principal diferencia entre los parámetros formales y las variables locales es que los parámetros formales obtienen sus valores de la función que llama, mientras que otras variables obtienen sus valores de la función.

2) Tenga en cuenta que se puede escribir así:

while ((cin >> total >> opciones) && opciones <= total), significa que si la entrada es exitosa

3. Funciones y matrices

¿Cómo combinar funciones y matrices?

Supongamos que usa una matriz para registrar cuántos postres comió cada persona en el picnic familiar, y ahora quiere contar el total, use la función para lograr

Nuestra parte de valor de retorno no puede ser una matriz, pero la parte de parámetro puede ser

Por ejemplo la siguiente declaración:

int sum_arr ( int arr[] , int n )

El arr aquí parece una matriz, pero en realidad es un puntero, pero cuando se escribe la función, puede considerarse como una matriz.

El siguiente programa demostrará el uso de punteros como nombres de matriz

#include <iostream>

using namespace std;

const int ArSize = 8;

int sum_arr(int arr[],int n);

int main(void)
{
    int cookies[ArSize] = {1,2,4,8,16,32,64,128};//数组定义好了

    int sum = sum_arr(cookies,ArSize); //函数返回总数
    cout << "Total cookies eaten: " << sum << endl;
    
    return 0; 
}
int sum_arr(int arr[],int n)//它用了两个参数,一个是数组,一个是数组数量
{
    int total = 0;
    for(int i = 0; i < n; i++)//很明显,我们用数组的数量和求和
    {
        total += arr[i];
    }
    return total;
}

Resultado: Total de galletas consumidas: 255

1: Cómo las funciones manejan matrices usando punteros

En su mayor parte, C++, como C, trata los nombres de las matrices como punteros e interpreta el nombre de la matriz como la dirección del primer elemento:

galletas == & galletas [0]

Pero hay algunas excepciones, como

1) La declaración de la matriz usa el nombre de la matriz para marcar la ubicación de almacenamiento

2) Usar sizeof en el nombre de la matriz obtendrá la longitud de toda la matriz (en bytes)

3) Cuando & se usa para el nombre de una matriz, devuelve la dirección de toda la matriz

Mire esta llamada de función nuevamente: int sum = sun_arr(cookies, ArSize)

Cookies es el nombre de la matriz y C++ estipula que es la dirección del primer elemento, por lo que la función pasa la dirección. Entonces, el tipo de cookies debe ser un puntero int, es decir, int *. Entonces, el encabezado de función correcto debería ser:
in sun_arr ( int * arr , int n)

En el encabezado de función o prototipo de función, int * arr e int arr[] tienen el mismo significado, ambos significan que arr es un puntero int

arr[i] == *(ar + i)

&arr [i] == ar + i

El puntero (nombre de matriz + 1) significa agregar un valor igual a la longitud del tipo al que apunta el puntero, que es el desplazamiento del puntero

2: ¿Qué significa tener una matriz como parámetro?

sum_arr pasa la dirección del primer elemento de las cookies y los elementos de la matriz a la función sum_arr.

La función sum_arr asigna la dirección de las cookies a la variable puntero arr y asigna ArSize a la variable int n

Cuando la función pasa una matriz, usa la matriz original

Mire la función a continuación, esta vez usamos punteros para demostrar el programa anterior

#include <iostream>

using namespace std;

const int ArSize = 8;

int sum_arr(int arr[],int n);

int main(void)
{
    int cookies[ArSize] = {1,2,4,8,16,32,64,128};//数组定义好了
    cout << "array adress: " << &cookies << endl;
    cout << "size of cookies: " << sizeof(cookies) << endl; //32

    int sum = sum_arr(cookies,ArSize); //函数返回总数
    cout << "Total cookies eaten: " << sum << endl;

    sum = sum_arr(cookies,3);
    cout << "3 cookies eaten: " << sum << endl;
    
    return 0; 
}
int sum_arr(int arr[],int n)//它用了两个参数,一个是数组,一个是数组数量
{
    int total = 0;
    cout << "arr adress: " << arr << endl;
    cout << "size of arr: " << sizeof arr << endl;//这里返回的不是数组,而是指针,8个字节,int *占用8字节

    for(int i = 0; i < n; i++)//很明显,我们用数组的数量和求和
    {
        total += arr[i];
    }
    return total;
}

resultado:

dirección de arreglo: 0x3cebbff7d0
tamaño de las cookies: 32
dirección de arreglo: 0x3cebbff7d0
tamaño de arreglo: 8
Total de cookies consumidas: 255
dirección de arreglo: 0x3cebbff7d0
tamaño de arreglo: 8
3 cookies consumidas: 7

*

1)

cout << "tamaño de las cookies: " << sizeof(cookies) << endl; aquí imprime el tamaño de la matriz

2)cout << "dirección arr: " << arr << endl;

La dirección de nuestro sum_array es exactamente la misma que la dirección de las cookies, por lo que sabemos que sum_array en realidad usa la dirección de las cookies para el cálculo.

3) cout << "size of arr: " << sizeof arr << endl;//Lo que se devuelve aquí no es una matriz, sino un puntero, 8 bytes, int * ocupa 8 bytes

3: Más ejemplos de funciones de matriz

Veamos primero un caso: considere una operación realizada en una serie de bienes inmuebles. Las dos operaciones básicas son leer valores en una matriz y mostrar el contenido de una matriz.

Añade también otra operación: reevaluar el valor de cada inmueble . (todas las propiedades aumentan o disminuyen al mismo ritmo)

#include <iostream>

using namespace std;
const int Max = 5;

int fill_array(double arr[],int limit);
void show_array(const double arr[],int n);
void revalue(double r,double arr[], int n);

int main(void)
{
    
    double properties[Max];//5个double类型数组
   
    int size = fill_array(properties,Max);//添加数组的方法
    
    show_array(properties,size);

    if(size > 0)
    {
        cout << "Enter revaluation factor: ";
        double factor;

        while(!(cin >> factor))
        {
            cin.clear();
            while ((cin.get() != '\n'))
            {
                continue;
            }
            cout << "Bad input : input process terminated." << endl;      
        }
        revalue(factor,properties,size);

        show_array(properties,size);
    }
    cout << "Done!\n";
    cin.get();
    cin.get();
    return 0; 
}
int fill_array(double arr[],int limit)//
{
    double temp;
    int i;
    for (i = 0; i < Max; i++)
    {
        cout << "Enter value #" << i + 1 << ":";
        cin >> temp;
        if(!cin)
        {
            cin.clear();
            while (cin.get() != '\n')
            {
                continue;
            }
            cout << "Bad input : input process terminated." << endl;
            break;
        }
        else if(temp < 0)
            break;
        else
            arr[i] = temp;
    }
    return i;
}
void show_array(const double arr[],int n)//加上const以后,就不能通过指针来修改对象了
{
    for (int i = 0; i < n; i++)
    {
        cout << "Property #" << i+1 << " : $";
        cout << arr[i] << endl;
    } 
}
void revalue(double r,double arr[], int n)//r是比例系数
{
    for(int i = 0; i < n ; i++)
    {
        arr[i] *= r;
    }
}

resultado:

输入:
Ingrese el valor #1:1000
Ingrese el valor #2:2000
Ingrese el valor #3:3000
Ingrese el valor #4:4000
Ingrese el valor #5:5000

espectáculo:

Propiedad #1: $1000
Propiedad #2: $2000
Propiedad #3: $3000
Propiedad #4: $4000
Propiedad #5: $5000

Factor de modificación:
Ingrese el factor de revaluación: 2
Propiedad #1: $2000
Propiedad #2: $4000
Propiedad #3: $6000
Propiedad #4: $8000
Propiedad #5: $10000
¡Listo!

*Descripción del programa:

1) Llena la matriz

Esta función especifica dos parámetros, uno es el nombre de la matriz y el otro especifica el número máximo de elementos leídos. Esta función devuelve el número real de elementos leídos y también presta atención a las dos condiciones para juzgar si su entrada es correcta y si la entrada es mayor que 0, y luego use el ciclo for para crear valores temporales y ponerlos uno por uno

2) Mostrar la matriz

Este es el bucle + elementos de matriz de visualización

3) Modificar la matriz

Necesita pasar tres parámetros a la función, que son factor, matriz y número de elementos, y no hay valor de retorno.

4: Usar funciones e intervalos de matriz

Además de proporcionar el tipo de datos en la matriz, la posición inicial de la matriz y la cantidad de elementos en la matriz en el ejemplo anterior, hay otro método:

Eso es para especificar el rango del elemento (rango), que se puede hacer pasando dos punteros: un puntero identifica el comienzo de la matriz y el otro puntero identifica el final de la matriz, vea el siguiente ejemplo (todavía galletas):

#include <iostream>

using namespace std;

const int ArSize = 8;

int sum_arr(const int * begin, const int * end);

int main(void)
{
    int cookies[ArSize] = {1,2,4,8,16,32,64,128};

    int sum = sum_arr(cookies, cookies + ArSize); 
    cout << "Total cookies eaten: " << sum << endl;
    
    return 0; 
}
int sum_arr(const int * begin, const int * end)
{
    int total = 0;
    const int * pt;

    for(pt = begin; pt != end; pt++)
        total += *pt; 
    return total;
}

Resultado: Total de galletas consumidas: 255

*

1) El comienzo del puntero y el final del puntero están definidos, y el contenido del puntero se usa para sumar

2) Use cookies y cookies + ArSize al principio y al final de la función de llamada

5: punteros y const

El uso de tres const

①const int *pt

②int *punto constante;

③const int *const pt;

①const int *pt es equivalente a int const *pt

Usando const, no puede modificar la matriz a través del puntero, como el siguiente programa:

int main(void)
{
    int n =10;
    int *pt = &n;

    cout << "1)n= " << n << endl;
    
    *pt = 20;//通过指针修改了n的对象
    cout << "2)n= " << n << endl;
    
    return 0; 
}

1)n= 10
2)n= 20

Pero si se agrega const, no se puede modificar a través de punteros.

int main(void)
{
    int n =10;
    const int *pt = &n;

    cout << "1)n= " << n << endl;
    
    *pt = 20;//通过指针修改了n的对象
    cout << "2)n= " << n << endl;
    
    return 0; 
}

El resultado es el siguiente:

 El informe de error dice que *pt es de solo lectura, por lo que el valor original no se puede modificar a través del puntero modificado por const

Pero el puntero aún puede apuntar a otros lugares, de la siguiente manera:

#include <iostream>

using namespace std;


int main(void)
{
    int n =10;
    int m = 100;
    const int *pt = &n;

    cout << "1)n= " << n << endl;
    
    //*pt = 20;//通过指针修改了n的对象
    pt = &m;
    cout << "*pt = " << *pt << endl;
    cout << "m = " << m << endl;
    
    return 0; 
}

Todavía puede apuntar a otras ubicaciones, como m

1)n= 10
*pt = 100
m = 100

②int * punto const;   

#include <iostream>

using namespace std;

int main(void)
{
    int n =10;
    int *const pt = &n;

    cout << "1)n= " << n << endl;
    *pt = 20;
    cout << "2)n = " << n << endl;
    
    return 0; 
}

En este momento, coloque * delante de const, y podrá modificar el valor n original a través del puntero pt

Resultado:
1) n = 10
2) n = 20

Luego apunte el puntero pt a m

#include <iostream>

using namespace std;

int main(void)
{
    int n =10;
    int *const pt = &n;

    cout << "1)n= " << n << endl;
    *pt = 20;
    cout << "2)n = " << n << endl;

    pt = &m;
    
    return 0; 
}

En este momento, se informa un error que indica que *const pt puede modificar el valor que apunta al valor, pero solo puede apuntar a un valor y no puede apuntar a ninguna variable

③const int *const pt;

Esto significa que no puede modificar el contenido a través del puntero ni apuntar a otras ubicaciones

use const siempre que sea posible

Hay dos razones para declarar parámetros de puntero como punteros a datos constantes:

Esto evita errores de programación debido a la modificación involuntaria de los datos.

Use const para permitir que la función maneje argumentos const y non-const; de lo contrario, solo recibirá datos que no sean const

Si es posible, el parámetro de puntero debe declararse como un puntero a const

Si el parámetro de la función es const, entonces se puede llamar independientemente de si la función es const o no const

Si el parámetro de la función no es constante, la llamada no se puede realizar si la función es constante.

Entonces, cuando lo use, ¡es mejor establecer el parámetro formal en un puntero const!

4. Funciones y arreglos bidimensionales

1:

Similar a una matriz unidimensional, asumiendo

int fecha[3] [4] = { {1,2,3,4},{5,6,7,8},{2,4,6,8}};

int total = suma (datos, 3), la función de suma es el nombre de la matriz + elementos en la matriz

data es un nombre de matriz con tres elementos. El primer elemento en sí es una matriz que consta de 4 entradas, por lo que el tipo de datos es un puntero a una matriz de 4 entradas. El prototipo correcto es el siguiente:

int sum(int(*ar2)[4], int size)) (matriz de punteros)

Esto declara una matriz de 4 punteros a enteros

en lugar de un puntero a una matriz de 4 enteros

Tales como: int ar2[4], (este es el puntero a la matriz)

La función de matriz bidimensional se escribe de la siguiente manera, que es más legible;

suma int(int ar2[] [4] , tamaño int);

2: recorrido de matriz bidimensional

Por lo tanto, el recorrido de una matriz bidimensional requiere el anidamiento de bucles, la capa externa accede a las filas y la capa interna accede a las columnas.

int sum(int are[][4],int size)
{
    int total = ;
    for(int r = 0; r < size; r++)
    {
        for(int c = 0;c <4; c++)
        {
            total += ar2[r][c];
        }
    }
    return total;
}

3: Extraer elementos

La razón por la que se puede usar la notación de matriz es: ar2 apunta al primer elemento de la matriz, por lo que ar+r apunta al elemento numerado r, y debido a que el elemento en sí es una matriz, ar2[r] es una matriz compuesta por 4 ints , por lo que ar2[r][c] es un elemento en una matriz de 4 ints (la forma más fácil) , y el puntero debe ser desreferenciado dos veces, de la siguiente manera:
 

ar2[r][c]  ==  *(*(ar2+r)+c)

Primero use el puntero de fila + r, use * para sacar el elemento de la fila, que es una matriz, luego +c al nombre de la matriz, es para compensar esta matriz, y luego * saque el elemento



5. Funciones y cadenas de estilo C

1: Tres formas de representar cadenas

Char array char ghost[15] = "galopar";

Constantes de cadena entre comillas (literales de cadena)   

Un puntero char que se establecerá como la dirección de la cadena char * str = "galumping"

Vea el siguiente ejemplo: Use una función para contar la cantidad de veces que aparece un carácter específico en una cadena

#include <iostream>

using namespace std;

unsigned int c_in_str(const char *str, char ch);

int main(void)
{
    char mmm[15] = "minimum";//第一种字符数组的方式
    const char * wail = "ululate"; //第二种字符指针方式 //char * wail = (char *"ululate")也行

    unsigned int ms = c_in_str(mmm,'m');
    unsigned int us = c_in_str(wail,'u');

    cout << ms << " m characters in " << mmm << endl;
    cout << us << " u characters in " << wail << endl;

    return 0;
}
unsigned int c_in_str(const char *str, char ch)
{
    unsigned int count = 0;

    while ((*str))
    {
        if(*str == ch)
            count++;    
    str++;
    }   
    return count;
}

3 m caracteres en mínimo
2 u caracteres en ululate

2: una función que devuelve una cadena de estilo C

La función no puede devolver una cadena, pero puede devolver la dirección de la cadena, lo que es más eficiente

Lo siguiente define una función buildstr() que devuelve un puntero y recibe dos parámetros, un carácter y un número. La función usa new para crear una cadena de igual longitud que el argumento numérico y luego inicializa cada elemento en la matriz.

#include <iostream>

using namespace std;
char * buildstr(char c, int n);

int main(void)
{
    char ch;
    cout << "Enter a character: ";
    cin >> ch;

    int times;
    cout << "Enter a integer: ";
    cin >> times;

    char *ps = buildstr(ch,times);
    cout << ps << endl;
    delete[] ps;
    ps = buildstr('+',20);
    cout << ps << "-Done-" << ps << endl;
    delete[]ps;

    return 0;
}
char * buildstr(char c, int n)
{
    char * pstr = new char[n+1];//new创建数组
    pstr[n] = '\0';//最后一个留给空字符
    for(int i = 0 ; i < n; i++)
    {
        pstr[i] = c;
    }
    return pstr;
}

resultado:

Introduzca un carácter: V
Introduzca un número entero: 20
VVVVVVVVVVVVVVVVVVVVV
++++++++++++++++++++-Terminado-++++++++++++++++++ ++++

*

1) Preste atención para dejar un espacio más para nosotros cuando haya una nueva cadena

2) Recuerde eliminar cuando finalice el nuevo

6. Funciones y Estructuras

Las variables de estructura se comportan más como variables básicas de un solo valor, en cuyo caso la función usará una copia de la estructura original , alternativamente, las funciones pueden devolver estructuras

A diferencia del nombre de la matriz, que es la dirección del primer elemento de la matriz, el nombre de la estructura es solo el nombre de la estructura . Para obtener la dirección de la estructura, debe usar el operador de dirección &

Si la estructura es muy grande, asignar la estructura aumentará los requisitos de memoria, por lo que muchos programadores de C para pasar y devolver funciones prefieren punteros para acceder al contenido de la estructura.

C++ proporciona una tercera opción: por tipo de referencia

1: estructuras de paso y retorno

Ver el siguiente programa:

#include <iostream>

using namespace std;
const int Mins_per_hr = 60;

struct travel_time
{
    int hours;
    int mins;
};

travel_time sum(travel_time t1, travel_time t2);
void show_time(travel_time t);

int main(void)
{
    travel_time day1 = {5,45};
    travel_time day2 = {4,55};

    travel_time trip = sum(day1,day2);

    cout << "Two days :" << trip.hours << " hours , " << trip.mins << " mins." << endl;//这样写还是有些复杂,再定义一个shouwtime函数

    travel_time day3 = {4,32};
    cout << "Three days :" ;
    show_time(trip);

    return 0;
}
travel_time sum(travel_time t1, travel_time t2)
{
    travel_time total;

    total.mins = (t1.mins + t2.mins) % Mins_per_hr;
    total.hours = t1.hours + t2.hours + (t1.mins + t2.mins) / Mins_per_hr;   //  (t1.mins + t2.mins) / Mins_per_hr会自动取整的

    return total;
}
void show_time(travel_time t)
{
    cout << t.hours << " Hours, " << t.mins << "Minutes." << endl;//没返回值
}

resultado:

Dos días: 10 horas, 40 minutos.
Tres días: 15 horas, 12 minutos.

*Todos los tipos de parámetros aquí son estructuras

2: Otro ejemplo de una función que maneja estructuras

Defina dos estructuras para representar dos formas diferentes de describir ubicaciones, luego desarrolle una función que convierta un formato a otro y muestre el resultado

#include <iostream>
#include <cmath>

using namespace std;

struct polar
{
    double distance;
    double angle;
};

struct rect
{
    double x;
    double y;
};

polar rect_to_polar(rect xypos);
void show_polar(polar dapos);

int main(void)
{
    rect rplace;
    polar pplace;

    cout << "Enter the x and y value: ";
    while (cin >> rplace.x >> rplace.y)
    {
        pplace = rect_to_polar(rplace);//将直角坐标系转为极坐标系,输入的一定是直角坐标系新建的
        show_polar(pplace);//要显示极坐标系,参数肯定是极坐标系
        cout << "Next two numbers(q to quit):";
    }
    return 0;
}
polar rect_to_polar(rect xypos)
{
    polar answer;
    answer.distance = sqrt(xypos.x * xypos.x + xypos.y * xypos.y);
    answer.angle = atan2(xypos.y,xypos.x);//atan2返回弧度,还需要转化为角度
    return answer;
}

void show_polar(polar dapos)
{
    const double Rad_to_deg = 57.29577951;
    cout << "Distance = " << dapos.distance << endl;
    cout << "Angel = " << dapos.angle * Rad_to_deg << "degree" << endl;
}

resultado:

Introduzca el valor de x e y: 30
40
Distancia = 50
Ángel = 53,1301 grados
Siguientes dos números (q para salir):-100
100
Distancia = 141,421
Ángel = 135 grados
Siguientes dos números (q para salir): q

*

1) La función hace referencia al tipo de estructura, y el tipo de estructura debe colocarse en la parte superior; de lo contrario, se informará un error.

2) while (cin >> rplace.x >> rplace.y), si la entrada es exitosa

3: Pasar la dirección de la estructura

El procedimiento anterior se puede modificar

#include <iostream>
#include <cmath>

using namespace std;

struct polar
{
    double distance;
    double angle;
};

struct rect
{
    double x;
    double y;
};

void rect_to_polar(const rect *pxy , polar * pda);
void show_polar(const polar *pda);

int main(void)
{
    rect rplace;
    polar pplace;

    cout << "Enter the x and y value: ";
    while (cin >> rplace.x >> rplace.y)
    {
        //pplace = rect_to_polar(rplace);
        rect_to_polar(&rplace,&pplace);//两个值,第一个是直角坐标系的指针,第二个是极坐标系的指针
        //show_polar(pplace);

        show_polar(&pplace);//直接用地址就行了,没有返回值
        cout << "Next two numbers(q to quit):";
    }
    return 0;
}
void rect_to_polar(const rect *pxy , polar *pda)//定义两个地址,只需要把地址换了就行
{
    pda->distance = sqrt(pxy->x*pxy->x + pxy->y*pxy->y);
    pda->angle = atan2(pxy->y, pxy->x);//atan2返回弧度,还需要转化为角度
}

void show_polar(const polar *pda)
{
    const double Rad_to_deg = 57.29577951;
    cout << "Distance = " << pda->distance << endl;
    cout << "Angel = " << pda->angle * Rad_to_deg << "degree" << endl;
}

resultado:

Introduzca el valor de x e y: 30
40
Distancia = 50
Ángel = 53,1301 grados
Siguientes dos números (q para salir):-100
100
Distancia = 141,421
Ángel = 135 grados
Siguientes dos números (q para salir): q

*

1) El puntero se pasa dentro de la función, el parámetro es un puntero y no hay valor de retorno

Siete, función y objeto de cadena.

Los objetos de cadena son más similares a las estructuras, por ejemplo, puede asignar una estructura a otra estructura y puede asignar un objeto a otro objeto. Las estructuras se pueden pasar a funciones como entidades completas

El siguiente programa declara una matriz de objetos de cadena y pasa la matriz a una función para mostrar el contenido:

#include <iostream>

using namespace std;
const int SIZE = 5;
void display(const string sa[], int n);

int main(void)
{
    string list[SIZE];
    cout << "Enter " << SIZE << " favorite food: " << endl;
    for (int i = 0; i < SIZE; i++)
    {
        cout << i+1 << ": ";
        getline(cin,list[i]);
    }
    cout << "Your list" << endl;
    display(list,SIZE);

    return 0;
}
void display(const string sa[], int n)
{
    for (int i = 0; i < n; i++)
    {
        cout << i+1 << ": " << sa[i] << endl;
    }
}

resultado:

Ingresa 5 comidas favoritas:
1: descanso
2: leche
3: helado
4: vendido
5: pastel
Tu lista
1: descanso
2: leche
3: helado
4: vendido
5: pastel

Ocho, función y objeto de matriz

Suponiendo que desea utilizar un objeto de matriz para almacenar los gastos de cuatro trimestres de un año, consulte el siguiente programa:

#include <iostream>
#include <string>
#include <array>

using namespace std;
const int Seasons = 4;
const array<string,Seasons> Snames = {"Spring","Summer","Fall","Winter"};

void fill(array<double,Seasons> *pa);
void show(array<double,Seasons> da);

int main(void)
{
    array<double,Seasons> expenses;

    fill(&expenses);//把指针填充到array里面
    show(expenses);

    return 0;
}
void fill(array<double,Seasons> *pa)
{
    for (int i = 0; i < Seasons; i++)
    {
        cout << "Enter " << Snames[i] << " expensens: ";
        cin >> (*pa)[i];//pa是array对象的指针,需要转化成值再进行操作
    }
}
void show(array<double,Seasons> da)
{
    double total = 0.0;
    cout << "EXPENSENS: " << endl;
    for (int i = 0; i < Seasons; i++)
    {
        cout << Snames[i] << ": $" << da[i] << endl;
        total += da[i];
    }
    cout << "Total expenses: " << total << endl;
}

resultado:

Ingrese gastos de primavera: 212
Ingrese gastos de verano: 256
Ingrese gastos de otoño
: 208 Ingrese gastos de invierno: 244
GASTOS:
Primavera: $212
Verano: $256
Otoño: $208
Invierno: $244
Gastos totales: 920
 

*cin >> (*pa)[i];//pa es un puntero a un objeto de matriz, que debe convertirse en un valor antes de la operación

Nueve, recursividad

Otra característica de la función C++: puede llamarse a sí misma (pero C++ no permite que main() se llame a sí misma), esta función se llama recursividad.

1: recursión con una llamada recursiva

Si la función recursiva se llama a sí misma, la función llamada también se llamará a sí misma, lo que continuará indefinidamente, a menos que el código contenga contenido de terminación, generalmente ubicado en la declaración if, de la siguiente manera: El código de la función recursiva recurs() de tipo void es como sigue:

void recurs(argumentlist)
{

       statements1
       if(test)
            resurs(arguments)
       statements2

}

Vea el siguiente ejemplo:

#include <iostream>

using namespace std;
void countdown(int n);

int main(void)
{
    countdown(4);
    return 0;
}

void countdown(int n)
{
    cout << "counting down.... " << n << endl;
    if(n>0)//更新条件,递归退出条件
    {
        countdown(n-1);
    }
    cout << n << ": Kandom" << endl;
}

resultado:

cuenta regresiva.... 4
cuenta regresiva.... 3
cuenta regresiva.... 2
cuenta regresiva.... 1
cuenta regresiva.... 0
0: Kandom
1: Kandom
2: Kandom
3: Kandom
4: Kandom

*

1) Cuando n se decremente a 0, se ejecutará el siguiente código: cout << n << ": Kandom" << endl;

2) ¡La segunda parte se ejecutará 5 veces en el orden inverso de las llamadas de función!

3) Cada llamada recursiva creará su propio conjunto de variables, por lo que cuando se llame al programa por quinta vez, habrá 5 n variables independientes, cada una de las cuales tiene un valor diferente. ¡Modifique el programa de la siguiente manera!

#include <iostream>

using namespace std;
void countdown(int n);

int main(void)
{
    countdown(4);
    return 0;
}

void countdown(int n)
{
    cout << "counting down.... " << n << "(n at adress: " << &n << ")" << endl;
    if(n>0)//更新条件,递归退出条件
    {
        countdown(n-1);
    }
    cout << n << ": Kandom" << "(n at adress: " << &n << ")" << endl;
}

El resultado es el siguiente:

contando regresivamente... 4(n en la dirección: 0x1d3adffc10)
contando regresivamente.... 3(n en la dirección: 0x1d3adffbe0)
contando regresivamente.... 2(n en la dirección: 0x1d3adffbb0)
contando regresivamente.... 1( n en la dirección: 0x1d3adffb80)
contando hacia atrás.... 0(n en la dirección: 0x1d3adffb50)
0: Kandom(n en la dirección: 0x1d3adffb50)
1: Kandom(n en la dirección: 0x1d3adffb80)
2: Kandom(n en la dirección: 0x1d3adffb0)
3: Kandom (n en la dirección: 0x1d3adffbe0)
4: Kandom (n en la dirección: 0x1d3adffc10)

2: recursión con múltiples llamadas recursivas

La recursividad es útil cuando necesita seguir dividiendo un trabajo en dos trabajos similares más pequeños. El método recursivo a veces se denomina estrategia de divide y vencerás, como encontrar los dos extremos de la escala, encontrar el punto final y marcarlo, y luego continuar usando la misma operación para las partes izquierda y derecha de la escala.

Consulte el procedimiento a continuación:

#include <iostream>

using namespace std;
const int Len = 66;
const int Divs = 6;
void subdivide(char ar[], int low, int high,int levels);

int main(void)
{
    char ruler[Len];//字符数组
    for(int i = 0; i < Len; i++)
        ruler[i] = ' ';//清空数组
    
    int min = 0; //数组边界开始
    int max = Len - 2; //数组边界结束
    ruler[Len-1] = '\0';
    ruler[min] = ruler[max] = '|';

    for(int i = 1; i < Divs; i++)
    {
        subdivide(ruler,min,max,i);//这样使用递归好像就可以了
        cout << ruler << endl;
    }

    return 0;
}
void subdivide(char ar[], int low, int high,int levels)//levels是为了控制递归退出
{
    if(levels == 0)
        return;

    int mid = (low + high) / 2;
    ar[mid] = '|';

    subdivide(ar,low,mid,levels-1);
    subdivide(ar,mid,high,levels-1);
}

resultado:

| | |
| | | | |
| | | | | | | | |
| | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
 

*

1) Al principio, había dos barras en ambos lados, la segunda vez se convirtió en tres, y la tercera vez se convirtió en cinco, y continuó recursivamente.

2) Escriba el número de recurrencias en los parámetros formales y luego forme la condición de juicio

10. Puntero de función

Al igual que los elementos de datos, las funciones también tienen direcciones. La dirección de la función es la dirección inicial de la memoria donde se almacena el código en lenguaje máquina. Podemos escribir una función que tome como parámetro la dirección de otra función, de modo que la primera función pueda encontrar la segunda función y ejecutarla, en particular, permite pasar la dirección de diferentes funciones en diferentes momentos, lo que significa que se puede usar en Usar diferentes funciones en diferentes momentos

1: Conocimiento básico de punteros de función

Por ejemplo, queremos diseñar una función de estimación () para estimar el tiempo requerido para un número específico de líneas de código, y esperamos que diferentes deseos constantes usen esta función. Pasamos a esitmate() la dirección de la función del algoritmo a utilizar por el programador, para ello es necesario:

· Obtener dirección de función

· Declarar un puntero

・Llamar una función usando un puntero de función

1) Obtener la dirección de la función

Simplemente use el nombre de la función, sin parámetros, por ejemplo, think() es una función, luego think es la dirección de la función

2) Declarar un puntero de función

Por ejemplo: la función es la siguiente

double pan(int); el puntero es el siguiente

doble (*pf)(int);

Al escribir, simplemente reemplace el nombre de la función en el prototipo con (*Nombre)

*Debe agregar (), de lo contrario es el nombre de la función

double (*pf)(int); en este momento el puntero de función

doble *pf(int), esta es una función

                                                                

3) Llamar a una función usando un puntero

Ahora (*pf) juega el mismo papel que el nombre de la función, por lo que cuando se usa (*pf), ¡puede considerarse como un nombre de función!

Por ejemplo:
doble pam(int);

doble (*pf)(int);

pf = pam;

2: Ejemplo de puntero de función

El siguiente programa demuestra cómo usar punteros de función para llamar a la función de estimación() dos veces, pasando la dirección de la función besty() una por una y la dirección de la función pam() en la otra. como sigue
 

#include <iostream>

using namespace std;
double Rick(int lines);
double Jack(int lines);
void estimate(int lines, double(*pf)(int));

int main(void)
{
    int code;

    cout << "How many lines of code do you need?\n";
    cin >> code;

    cout << "Here is Rick's estimate: " << endl;
    estimate(code,Rick);

    cout << "Here is Jack's estimate: " << endl;
    estimate(code,Jack);
    
    return 0;
}
double Rick(int lines)
{
    return lines * 0.05;
}

double Jack(int lines)
{
    return (0.03 * lines) + (0.0004 * lines * lines);
}

void estimate(int lines, double(*pf)(int))
{
    cout << lines << " Lines code will take " << (*pf)(lines) << " hours." << endl;
}

resultado:

¿Cuántas líneas de código necesitas?
100
Aquí está la estimación de Rick:
100 El código de líneas tardará 5 horas.
Esta es la estimación de Jack:
el código de 100 líneas tardará 7 horas.

*

Puede ver que en la última línea de código, declaramos el puntero de función *pf del mismo tipo que Rick y Jack, y usamos el parámetro de nombre directamente cuando lo usamos: (*pf)(líneas) << " horas". << finl;

3: discusión en profundidad de los punteros de función

Vea el siguiente ejemplo:

#include <iostream>

using namespace std;
const double *f1(const double *ar,int n);
const double *f2(const double ar[],int n);
const double *f3(const double ar[],int n);

int main(void)
{
    double av[3] = {1112.3,1542.6,2227.9};
    
    //part1: p1是指向函数的指针
    const double *(*p1)(const double *,int) = f1;//第一种方法,使用传统方法进行给指针赋值
    
    auto p2 = f2; //第二种方法:使用auto方法,让编译器自动判断p2的类型
    
    cout << "PART1:--------------------" << endl;
    cout << "Adress        Value" << endl;
    cout << (*p1)(av,3) << ": " << *((*p1)(av,3)) << endl; //(*p1)(av,3) == f1(av,3),第二个是把该函数内容再显示出来

    cout << p2(av,3) << ": " << *p2(av,3) << endl;//第二种方法,直接把指针名称写出来就行了

    //part2:  p2是由指针构成的数组
    const double *(*pa[3])(const double *,int) = {f1,f2,f3};//指针数组的内容是函数,注意它的声明方法
    
    auto pb = pa;//这样pb也是函数指针数组

    cout << "PART2:--------------------" << endl;
    cout << "Adress        Value" << endl;
    for(int i = 0;i < 3; i++)
        cout << pa[i](av,3) << ": " << *pa[i](av,3) << endl;//pa[1]就是f1了,加*就是它里面的内容
    for (int i = 0; i < 3; i++)
    {
        cout << pb[i](av,3) << ": " << *pb[i](av,3) << endl;
    }

    //part3: 
    //(pc)pd 是指针,指向了一个由函数指针构成的数组
    auto pc = &pa;//pc是指向由三个函数指针作为元素的数组pa的指针
    const double *(*(*pd)[3])(const double *,int) = &pa;//传统方法,首先pd是指针,就是*pd,然后*pd是3个元素数组指针,就是*(*pd)[3],最后每个元素都是函数指针,就有了这个

    cout << "PART3:--------------------" << endl;
    cout << "Adress        Value" << endl;
    cout << (*pc)[0](av,3) << ": " << *(*pc)[0](av,3) << endl;
    
    const double *pdb = (*pd)[1](av,3);
    cout << pdb << ": " << *pdb << endl;

    cout << (*pd)[2](av,3) << ": " << *(*pd)[2](av,3) << endl;
    cout << (*(*pd)[2])(av,3) << ": " << *(*(*pd)[2])(av,3) << endl;//这两种写法其实是一样的

    return 0;
}
const double *f1(const double *ar,int n)
{
    return ar;
}
const double *f2(const double ar[],int n)
{
    return ar + 1;
}
const double *f3(const double ar[],int n)
{
    return ar + 2;
}

结果:
PART1:--------------------
Valor de dirección
0xf0e7dff6a0: 1112.3
0xf0e7dff6a8: 1542.6
PART2:---------------- ----
Valor de dirección
0xf0e7dff6a0: 1112.3
0xf0e7dff6a8: 1542.6
0xf0e7dff6b0: 2227.9
0xf0e7dff6a0: 1112.3 0xf0e7dff6a8
: 1542.6
0xf0e7dff6b0: 2227 .9
PART3:------------------------------------
Dirección Valor
0xf0e7dff6a0: 1112,3
0xf0e7dff6a8: 1542,6
0xf0e7dff6b0: 2227,9
0xf0e7dff6b0: 2227,9

*en conclusión

1)

(*pa[2])(av,3) ≠ *pa[2](av,3), la prioridad de los corchetes es diferente

Para pa[2](av,3), pa[2] es el tercer elemento de la matriz de punteros, que es el puntero de función, y el último * es el valor de la tercera función

(*pa[2])(av,3), (*pa[2]) es el puntero de función señalado por el puntero de función del tercer elemento, y luego asignado, la dirección sigue siendo

2)

Para punteros de función, *pf y pf son en realidad equivalentes

3)

Tenga en cuenta la diferencia entre pa y &pa (pa es una matriz), pa es la dirección del primer elemento de la matriz, es decir, &pa[0], y &pa es la dirección de toda la matriz (tres punteros), numéricamente son lo mismo, pero son de diferentes tipos.

Por ejemplo, pa+1 es la dirección del siguiente elemento y &pa+1 es la dirección del siguiente bloque de memoria de 12 bytes.

Hay otra diferencia Para obtener el valor del primer elemento, solo necesita desreferenciar pa, y &pa desreferencia dos veces

**&pa == *pa == pa[0]

4)

Use auto para liberarse del complicado proceso de declaración

const double *(*pa[3])(const double *,int) = {f1,f2,f3};
    
auto pb = pa;//entonces pb también es una matriz de punteros de función

5)

También puede usar typedef para simplificar (no define cosas nuevas, sino un alias, como se mencionó en el Capítulo 5)

Por ejemplo: typedef int n, aquí pon n en tipo int

Por ejemplo: typedef double real; aquí real se convierte en un tipo doble, no en una variable

Los ejemplos son los siguientes:

typedef const double *(*p_fun) (const double *,int), puede usar el tipo p_fun directamente

p_fun p1 = f1;

p_fun pa[3] ={f1,f2,f3};

11. Preguntas de repaso y ejercicios de programación

1: Preguntas de revisión:

1: ¿Tres pasos para usar la función?

definir, llamar, declarar

2: cree un prototipo de función que coincida con la descripción a continuación

a:igor() no tiene parámetros ni valor de retorno

vacío igor(vacío);

b:tofu() recibe un parámetro int y devuelve un flotante

tofu flotante (int)

c:mpg() recibe dos dobles y devuelve un doble

doble mpg (doble, doble)

d:summation() toma el nombre largo del arreglo y la longitud del arreglo como parámetros y devuelve un largo

largo arr[n];

sumatoria larga(larga [],int)

e:doctor() acepta un parámetro de cadena (no se puede modificar) y devuelve el doble

doctor doble (const char *str )

f:ofcourse() toma la estructura del jefe como parámetro y no tiene valor de retorno

void por supuesto (boss bs) el nombre del parámetro formal se puede escribir o no

g:plot toma el puntero de la estructura del mapa como parámetro y devuelve una cadena

char *plot(mapa *pt)

3: escriba una función que acepte 3 parámetros: nombre de matriz int, longitud de matriz y un valor int, y establezca todos los elementos de la matriz en el valor int

Conjunto vacío (int ar[], int n, int x)

{

     para(i = 0;i<n;i++)

                 {

                              ar[i] = x;

                }

}

4: escriba una función que acepte tres parámetros: un puntero al primer elemento del rango de la matriz, un puntero al final del último elemento del rango de la matriz y un valor int, y establezca cada elemento de la matriz en el int valor

void Set(int *begin,int *end , int x)
{
    for (int *pt = begin; pt != end ; pt ++ )
    {
        *pt = x;
    }
}

*Tenga en cuenta la condición de bucle

5: escriba un nombre de matriz doble y una longitud de matriz como parámetros y devuelva la función del valor máximo en la matriz. Esta función no debería modificar el contenido de la matriz.

double Set(const double ar[],int len)
{
    double max = arr[0];
    for(int i = 1; i < size; i++)
    {
        if(max < arr[i]);
            max = arr[i];
    }
    return max;
}

6: ¿Por qué no usar const para parámetros de función de tipos primitivos?

Nuestro C++ generalmente pasa parámetros por valor, a diferencia de los arreglos y estructuras, que se copian como un todo, y la copia modificada no afecta el valor original, pero si usa un puntero, debe agregar const

7: ¿Qué tres cadenas de estilo C usa C++?

matriz de caracteres. char ch[] = "Hola";

cadena. "Hola;";

Un puntero que puede apuntar al primer carácter de una cadena. char * pt = "Hola. se refiere a la dirección

8: Escribe una función, el prototipo es el siguiente:

Esta función reemplaza todo c1 en la cadena con c2 y devuelve el número de reemplazos

reemplazo int (char * str, char c1,char c2)

int replace(char * str,char c1,char c2)
{
    int count;
    while(*str)
    {
        if(*str == c1)
        {
            *str = c2;
            count++;
        }
        str++;
    }
    return count;
}

9: La expresión *"pizza" significa: la primera dirección de la cadena, sacar p

"taco[2]", taco es una matriz, el tercer elemento, las comillas dobles es la primera dirección

10: C++ permite pasar estructuras por valor, así como direcciones de estructuras. Si glitz es una variable de estructura, ¿cómo pasarla por valor? ¿Cómo pasar la dirección? ¿Cuáles son los pros y los contras de los dos enfoques?

Pasar por dirección no puede proteger los datos originales, pero pasar por valor consume mucha memoria

11: El tipo de devolución de la función Judge() es int, y toma una dirección de función como parámetro: toma un puntero de const char como parámetro, devuelve un valor int y escribe el prototipo de función

int juez(int (*pf) (const char));

12: La estructura es la siguiente:

solicitante de estructura

{

        nombre de char[30];

        calificaciones internas[3];

}

a: Escriba una función que muestre el contenido de la estructura, y el parámetro es la estructura

void show(applicant ap)
{
    for (int  i = 0; i < 2; i++)
    {
        cout << ap.name[i] << ap.ratings[i] << endl;
    }
    
}

b. Use la dirección de la estructura como parámetro para mostrar el contenido de la estructura a la que apunta el parámetro

void show(applicant *ap)
{
    for (int  i = 0; i < 2; i++)
    {
        cout << ap->name << ap->ratings[i] << endl;
    }   
}

13: Supongamos que los prototipos de f1() y f2() son los siguientes:

void f1(solicitante * a);

const char * f2(const solicitante * a1,const solicitante * a2);

1) Declare p1 y p2 como punteros a f1 y f2 respectivamente;

2) Declarar ap como una matriz que contiene 5 punteros del mismo tipo que p1

3) declarar pa como un puntero, y la matriz a la que apunta contiene 10 punteros del mismo tipo que p2

Use el método typedef para lograrlo.

1)

typedef void *(pf_1)(applicant * a);//使用typedef直接变成类型
pf_1 p1 = f1;

typedef char const char *(*p_f2)(const applicant *a1,const applicant *a2);
p_f2 p2 = f2;

2) pf_1ap[5];

3p_f2 (*pa) [10];

2: Ejercicios de programación

Supongo que te gusta

Origin blog.csdn.net/leikang111/article/details/125288203
Recomendado
Clasificación