2021-10-15 C language function

Posted by ym_chaitu on Fri, 15 Oct 2021 22:43:20 +0200

Day8 function
Basic usage of functions
1. Definitions
A function is a code module that completes a specific function. Its program code is independent. It usually requires a return value or a null value.
The general form is as follows:

<data type><Function name>(<Formal parameter description>){
Statement sequence;
return [(<expression>)];
}

① < data type > is the return value type of the whole function. The value of the expression in the return [(< expression >)] statement should be consistent with the < data type > of the function. If there is no return value, it should be written as void.
② < formal parameter description > is the description form of mu lt iple variables separated by commas ",".
③ The {< < statement sequence >} in large brackets is called the function body< The statement sequence > is composed of 0 or more statements.
④ The description of a function refers to the function prototype. Where < formal parameter description > can be the variable name of the default description, but the type cannot be the default.
⑤ Note: function function, parameter and return value.
Example:

double Power (double x , int n );
double Power (double , int );

2. Use of functions
The use of function is also called function call, and the form is as follows:
Function name (< actual parameter >);
① The argument is the data passed from the calling function to the called function when using the function. The exact data is required.
② A function call can appear in an expression as an operand or form a word alone. For functions without return value, only one function call statement can be formed.
③ Functions should be described before use (you don't need to implement them first)
Example: write a function to display "Hello everyone!", Then write the main program and call it main.

#include <stdio.h>

int hello ( ){
	printf("Hello everyone!");
	return 0 ;
}

int main ( ){
	hello ( ) ;
	return 0 ;
}

3. Examples of procedures
Define a function to find the nth power of X (x is a real number and n is a positive integer)

#include <stdio.h>

double power(double x, int n) 
{
        double r = 1;
        int i;

        for (i = 1; i <= n; i++)
                r *= x;

        return r;
}

int main() 
{
        double x, ret;
        int n;

        printf("input:");
        scanf("%lf%d", &x, &n);

        ret = power(x, n);

        printf("%lf %d = %lf\n", x, n, ret);

        return 0;
}

Q: when using the function library, why is the header file introduced? Is there any other alternative?
A: there are function descriptions in the header file. Only after the header file is introduced can the compiler see the function descriptions and calls in the file. The function description required in the header file can be introduced into the program instead of directly introducing the header file.
Example: by referencing scanf and printf functions, you can introduce < stdio. H > header files, or directly reference scanf and printf in < stdio. H >
Function description.

//#include <stdio.h>
int scanf(const char *format, ...);
int printf(const char *format, ...);

double power(double, int);

int main() 
{
        double x, ret;
        int n;

        printf("input:");
        scanf("%lf%d", &x, &n);

        ret = power(x, n);

        printf("%lf %d = %lf\n", x, n, ret);

        return 0;
}

double power(double x, int n) 
{
        double r = 1;
        int i;

        for (i = 1; i <= n; i++)
                r *= x;

        return r;
}

Parameter passing of function
Parameter transfer methods between functions: global variable, copy transfer method and address transfer method
1. Global variables
(1) Global variable is the variable described outside the function, which is visible in every function in the program.
(2) Once a global variable is defined, it will be visible anywhere in the program. The execution result of the program may be affected by the location of the function call, which is not recommended.
Example:

#include <stdio.h>

double x = 2;
int n = 3;

double power();

int main() 
{
//        double x = 2;
//        int n = 3;
        double ret;

        ret = power();

        printf("%lf %d = %lf\n", x, n, ret);

        return 0;
}

double power() 
{
        double r = 1;
        int i;

        for (i = 1; i <= n; i++)
                r *= x;

        return r;
}

2. Copy transfer method (value transfer)
(1) The calling function passes the arguments to the called function, and the called function will create formal parameters of the same type and initialize with the arguments.
(2) The formal parameter is a newly opened storage space, so changing the value of the formal parameter in the function will not affect the actual parameter. Formal parameters and arguments are one-to-one relationships.

Example:

#include <stdio.h>

double power(double, int);

int main() 
{
        double x = 2;
        int n = 3;
        double ret;

        printf("&x=%p &n=%p\n", &x, &n);

        ret = power(x, n);

        printf("%lf %d = %lf\n", x, n, ret);

        return 0;
}

double power(double a, int b) //double a = x; int b = n; Pass the value of X to a and the value of n to B
{
        double r = 1;
        int i;

        printf("&a=%p &b=%p\n", &a, &b);

        for (i = 1; i <= b; i++)
                r *= a;

        return r;
}

3. Address transfer mode (pointer transfer)
Passed by address, the argument is the address of the variable, and the formal parameter is a pointer of the same type. The operation on the formal parameter in the called function will directly change the value of the argument (the target operation of the called function on the pointer is equivalent to the operation on the argument itself).
Example:

#include <stdio.h>

void  swap(int * x, int * y);

int main() 
{
        int a = 10;
        int b = 20;

        printf("before:%d %d\n", a, b);

        swap(&a, &b);//Introducing a, b addresses

        printf("after:%d %d\n", a, b);

        return 0;
}
//int * x = &a; int *y = &b;
void  swap(int * x, int * y) 
{
        int t;
        t = *x;//a
        *x = *y;
        *y = t;
}

4. Examples of procedures
Write a function to count the number of lowercase letters in the string and convert the lowercase letters in the string into uppercase letters.

#include <stdio.h>
int str_fun(char * p);

int main(int argc, char *argv[])
{
        char s[] = "welcome2021Beijing";
        int n;

        n = str_fun(s);
        printf("n=%d %s\n", n, s);

        return 0;
}

int str_fun(char * p) //char * p = s;
{
        int num = 0;
        while (*p != '\0') {//while (*p)
                if (*p <= 'z' && *p >= 'a') {
                        num++;//Count the number of lowercase letters
                        *p -= ' ';//Convert lowercase letters to uppercase
                }
                p++;
        }
        return num;
}

Q: how to program the address transfer mode without changing the arguments?
Answer: use const modifier

Pass array parameters in function
1. Function parameters - array
(1) Global array transfer mode
(2) Copy delivery method
The argument is the pointer to the array, and the formal parameter is the array name (essentially a pointer variable)
(3) Address transfer mode
The argument is a pointer to the array, and the formal parameter is a pointer variable of the same type

2. Examples of procedures
(1) Write a function to calculate the sum of all elements of a one-dimensional array
Copy delivery method

#include <stdio.h>

int array_sum(int data[], int n);

int main(int argc, char *argv[])
{
        int a[] = {5, 9, 10, 3, 10};
        int sum = 0;

        sum = array_sum(a, sizeof(a)/sizeof(int));

        printf("sum=%d\n", sum);
        return 0;
}

int array_sum(int data[], int n) // int data[] = a;error  int * data = a;
{		
//int n = sizeof(a)/sizeof(int);
        int ret = 0;
        int i;

        for (i = 0; i < n;i++) {
                printf("%d\n", data[i]);
                ret += data[i];
        }

        return ret;
}

Address transfer mode

#include <stdio.h>

int array_sum(int * data, int n);

int main(int argc, char *argv[])
{
        int a[] = {5, 9, 10, 3, 10};
        int sum = 0;

        sum = array_sum(a, sizeof(a)/sizeof(int));

        printf("sum=%d\n", sum);
        return 0;
}

int array_sum(int * data, int n) //int * data = a;
{
//int n = sizeof(a)/sizeof(int);
        int ret = 0;
        int i;

        for (i = 0; i < n;i++) {
                printf("%d\n", data[i]);
                ret += data[i];
        }

        return ret;
}

(2) Write a function to delete spaces in a string

#include <stdio.h>

void del_space(char * s1);

int main(int argc, char *argv[])
{
        char s[] = "   h  a   sdf g  ";

        puts(s);
        del_space(s);
        puts(s);

        return 0;
}

void del_space(char * s1) 
{
        char * s2;

        s2 = s1;

        while (*s1) {
                if (*s1 == ' '){
                        s1++;//Space pointer forward encountered
                }
                else {
                        *s2 = *s1;//Assign s1 content to s2 when characters are encountered
                        s1++;
                        s2++;//s1, s2 forward cycle continues
                }
        }
        *s2 = '\0';
}

Pointer function
Pointer function refers to a function whose return value is the address quantity.
The general form of definition of pointer function is as follows:

<data type> *<Function name>(<Parameter description>){
Statement sequence;
return [(<expression>)];
}

Return value: address of global variable / address of static variable / address of string constant / heap address
Example:
Are there any problems with the following procedures? If so, how to modify them? (in doubt)

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

char * getstring();

int main(int argc, char *argv[])
{
        char * r;
        
        r = getstring();
        printf("---%s---\n", getstring());

        (*r)++;
        puts(r);

        return 0;
}

char * getstring() 
{
        char str[20];

        strcpy(str, "hello");//String str is a local variable

        return str;
}

Modification:

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

//char str[20];
char * getstring();

int main(int argc, char *argv[])
{
        char * r;
        
        r = getstring();
        printf("---%s---\n", getstring());

        //(*r)++;
        puts(r);

        return 0;
}

char * getstring() 
{
        //char str[20];//error
        //static char str[20];
        char * str = "hello";

       // strcpy(str, "hello");

        return str;
}

Example:
(1) Write a pointer function to delete spaces in a string

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

char * del_space(char * s);

int main(int argc, char *argv[])
{
        char * r;
        char str[]= "   how    are  you  ";
        char s[50], s2[50];
        
        r = del_space(str);
        printf("---%s---\n", r);

        //strcpy(s, del_space(str));
        strcpy(s2, strcpy(s, del_space(str)));//m=n=k
        puts(str);
        puts(s);
        puts(s2);

        return 0;
}

char * del_space(char * s) //char * s = str;
{
        char * r = s;
        char * p = s;

        while (*s) {
                if (*s == ' ')
                        s++;
                else {
                        *p = *s;
                        s++;
                        p++;
                }
        }
        *p = '\0';

        return r;//The r pointer is the first address of the string, and the p pointer performs string operation
}

(2) Write a pointer function to realize string function connection

#include <stdio.h>

char * mstrcat(char * dest, const char * src);

int main(int argc, char *argv[])
{
        //char * r;
        char dest[50] = "welcome";
        char src[] = "everyone";
        
        puts(mstrcat(dest, src));
        puts(dest);

        return 0;
}

char * mstrcat(char * dest, const char * src) 
{
        char * r = dest;

        while (*dest++);//When * dest is not \ 0, the dest pointer is incremented by 1

        dest--;//At this time, the dest pointer points to \ 0, and you need to return one bit for string connection

        while (*dest++ = *src++);//Loop concatenates the src string after the dest string

        return r;
        /*Mode II
        char * r = dest;

        while (*dest++);

        dest--;

        while (*src) {
                *dest++ = *src++;
        }

        *dest = '\0';

        return r;
        */
        /*Mode III
        char * r = dest;

        while (*dest) {
                dest++;
        }

        while (*src) {
                *dest = *src;
                dest++;
                src++;
        }

        *dest = '\0';

        return r;
        */
}

(3) Write a pointer function to convert an integer into a string

#include <stdio.h>

char * itoa(char *p, int n);

int main(int argc, char *argv[])
{
        int n;
        char  s[50], * r;

        printf("input:");
        scanf("%d", &n);

        r = itoa(s, n);

        puts(r);
        puts(s);

        return 0;
}

char * itoa(char *p, int n)
{
        int r, i = 0, j;
        //static char p[50];

        while (n) {
                r = n % 10;
                n /= 10;
                p[i] = r + '0';
                i++;//The numeric string is output circularly. At this time, the output characters are converted to the reverse order of numbers
        }
        p[i] = '\0';

        j = i-1;
        i = 0;

        while (i < j) {
                r = p[i];
                p[i] = p[j];
                p[j] = r;
                i++;
                j--;//Converts the output string to positive order
        }

        return p;
}

Recursive functions and function pointers
1. Recursive function
Recursive function refers to a function that is called directly or indirectly in the function body of a function.
The execution process of recursive function calls is divided into two stages:
① Recursion function: starting from the original problem, recursion from unknown to known according to the recursion formula, and finally reach the recursion termination condition.
② Regression stage: the results are obtained according to the recursive termination conditions, and the recursive formula is gradually brought into reverse to return to the original problem.
Example:
(1) Write a recursive function to calculate n!

#include <stdio.h>

int fac(int n);

int main(int argc, char *argv[])
{
        int n;

        printf("input:");
        scanf("%d", &n);

        printf("%d\n", fac(n));

        return 0;
}

int fac(int n) 
{
        if (n == 0 || n == 1)
                return 1;

        return n * fac(n-1);
}

(2) Write a recursive function to calculate the Fibonacci sequence: Generally speaking, rabbits have the ability to reproduce two months after birth. A pair of rabbits can give birth to a pair of rabbits every month. If all rabbits do not die, how many pairs of rabbits can they reproduce in a year?

#include <stdio.h>

int fib(int n);

int main(int argc, char *argv[])
{
        int n = 1;

        while (n <= 10) {
                printf("%d  ", fib(n));
                n++;
        }

        printf("\n");


        return 0;
}

int fib(int n) 
{
        if (n == 1 || n == 2)
                return 1;

        return fib(n-1)+fib(n-2);
}

2. Function pointer
(1) The function pointer is used to store the address of the function. This address is the address of a function. The function name represents the entry address of the function. The general form of function pointer variable description is as follows:

<data type> (*<Function pointer name>) (<Parameter description list>) ;

< data type > is the return value type of the function pointed to by the function pointer.
< parameter description list > should be consistent with the formal parameter description of the function pointed to by the function pointer, and the parameter name can be omitted.
(* < function pointer name >), the * description is the pointer type. () cannot be defau lt ed, indicating that it is a pointer to a function.
Example:

#include <stdio.h>

int add(int a, int b) {
        return a+b;
}
int sub(int a, int b) {
        return a-b;
}
int mul(int a, int b) {
        return a*b;
}

int main(int argc, char *argv[])
{
        int m = 10, n = 20;
        
        int  (* p)(int, int);

        p = add;

        //printf("%d\n", add(m, n));
        printf("%d\n", (*p)(m, n));

        p = sub;
        printf("%d\n", (*p)(m, n));

        return 0;
}

(2) A function pointer array is an array that holds several function names. The general form is as follows:

<data type> (*<Function pointer array name>) [<size>] (<Parameter description list>) ;

Where, < size > refers to the number of array elements of function pointers, and others are the same as ordinary function pointers.
Example:

int add(int a, int b) {
        return a+b;
}
int sub(int a, int b) {
        return a-b;
}
int mul(int a, int b) {
        return a*b;
}

int main(int argc, char *argv[])
{
        int m = 10, n = 20;
        
        int  (* p[2])(int, int);//int * p[3]

        p[0] = add;

        //printf("%d\n", add(m, n));
        printf("%d\n", (*p[0])(m, n));

        p[1] = sub;
        printf("%d\n", (*p[1])(m, n));

        return 0;
}

Q: how to call the qsort function in the C library to sort integer arrays?
Answer:

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

int compare(const void *, const void *);

int main(int argc, char *argv[])
{
        int s[] = {89, 23, 10, 8, 7, 61}, n, i;

        n = sizeof(s)/sizeof(int);

        qsort(s, n, sizeof(int), compare);//Learn to use functions through the find functions manual

        for (i = 0; i < n; i++)
                printf("%d ", s[i]);
        puts("");

        return 0;
}

int compare(const void * p, const void * q) 
{
        return (*(int *)p - *(int *)q);

}

Topics: C