【C】函数真的难嘛?其实一点也不难,原理很简单。

简介: # 什么是函数程序是由多个零件组合而成的,而函数就是这种“零件”的一个较小单位。## main函数和库函数C语言程序中,main函数是必不可少的。程序运行的时候,会执行main函数的主题部分。main函数中使用了printf、scanf、puts等函数。由C语言提供的这些为数众多的函数称为库函数。## 什么是函数当然,我们也可以自己创建函数。而实际上,我们也必须亲自动手创建各种函数。下面我们来自己创建一个简单的函数。创建一个函数,接收两个整数参数,返回较大整数的值。printf函数和scanf函数等创建得比较好得函数,即使不知道其内容,只要了解使用方法,也可以轻松使用。## 函

什么是函数

程序是由多个零件组合而成的,而函数就是这种“零件”的一个较小单位。

main函数和库函数

C语言程序中,main函数是必不可少的。程序运行的时候,会执行main函数的主题部分。main函数中使用了printf、scanf、puts等函数。由C语言提供的这些为数众多的函数称为库函数。

什么是函数

当然,我们也可以自己创建函数。而实际上,我们也必须亲自动手创建各种函数。下面我们来自己创建一个简单的函数。
创建一个函数,接收两个整数参数,返回较大整数的值。
printf函数和scanf函数等创建得比较好得函数,即使不知道其内容,只要了解使用方法,也可以轻松使用。

函数定义

首先来说下函数的创建方法,这里我们来定义一个名为max2的函数,如下所示:
image.png
这里的函数定义由多个部分构成。

函数头

该部分表示函数的名称和格式。虽然称为头函数,实际上说它是函数的“脸”可能更加的合适。

返回类型

函数返回的值——返回值的类型。该函数的情况下,返回的是两个int型数值中较大的一个,所以其类型是int。

函数名

函数的名称。从其他零件调用函数时,使用函数名。

形参声明

小括号括起来的部分,是用于接收辅助性提示的变量——形式参数的声明。

函数体

函数体是复合语句。仅仅在某个函数中使用的变量,原则上应在该函数中声明和使用,但是要注意不能声明和形参同名的变量,否则会发生变量名冲突。

函数调用

下面是使用函数的方法,代码如下:


#include<stdio.h>

int Max(int n, int m)
{
   
   
    if (n>m)
    {
   
   
        return n;
    }
    else
    {
   
   
        return m;
    }
}

int mian()
{
   
   
    int n = 0;
    int m = 0;

    puts("请输入两个整数:");
    printf("整数1:");
    scanf("%d", &n);
    printf("整数2:");
    scanf("%d", &m);

    printf("较大的整数的值是%d\n", Max(n, m));

    return 0;
}

该程序中定义了两个函数Max和mian。程序启动时会执行的时main函数。
运行结果:
image.pngimage.png

  1. 函数的调用形式是在函数后面加上小括号,这个小括号称为函数调用运算符。使用函数调用运算符的表达式就称为函数调用表达式。
  2. 函数调用运算符括起来的是实参,当实参不止一个的时候,要是使用逗号将其分开。
  3. 进行函数调用后,程序的流程将一下子跳转到该函数处,main函数的执行就会中断,直到该函数调用完成之后才会继续执行main函数中的代码。
  4. 进行函数调用后,程序的流程会转到被调用函数处,这时,传递过来的实参值会被赋给函数接收的形参。
  5. 形参的初始化完成后,将执行函数体。在程序中遇到return 语句,或者执行到函数体最后的大括号是,就会从该函数跳到调用函数。

image.png
如上图所示,执行到return b; return语句执行结束后,程序就会返回到原来进行调用的地方,再次执行被中断的main函数。
函数调用运算符的总结如下图:
image.png
函数调用的时候传递的只是函数的参数的值,因此调用函数时使用的实参既可以时变量,也可以是常量。
例如:下面的函数调用,将输出变量n1和5中比较哪一个值大
Max(n1,5);
另外需要注意的是,实参和形参是完全不同的两个东西,因此不用担心实参和形参的名字一样的问题。
上面我还提到了return 语句,它的结构如下图所示;
image.png
函数返回的是“表达式“的值,不能返回两个以上的值。

三个数中的最大值

下面我来说下写求三个整数中的最大值的函数,函数接收的形参,以及函数内定义的变量,都是该函数自己的东西。在函数max3的形参a、b、c和main函数的变量a、b、c虽然名称相同,但是分别是不同的东西。结构如下:
image.png
代码如下:

#include<stdio.h>

//返回三个数中的最大值函数
int max3(int a, int b, int c)
{
   
   
    int max = a;
    if (b>max)
    {
   
   
        max = b;
    }
    if (c>max)
    {
   
   
        max = c;
    }
    return max;
}

int main()
{
   
   
    int a = 0;
    int b = 0;
    int c = 0;

    puts("请输入三个整数。");
    printf("整数1;");
    scanf("%d", &a);
    printf("整数2;");
    scanf("%d", &b);
    printf("整数3;");
    scanf("%d", &c);

    printf("最大值是:%d", max3(a, b, c, ));
    return 0;
}

将函数的返回值作为参数传递个函数

输入两个整数,计算他们的平方差并显示,代码如下:


#include<stdio.h>

//计算整数的平方
int sqr(int a)
{
   
   
    return a * a;
}

//返回差值
int diff(int a, int b)
{
   
   
    return (a > b ? a - b : b - a);
}

int main()
{
   
   
    int x = 0;
    int y = 0;

    puts("请输入两个整数。");
    printf("整数1:");
    scanf("%d", &x);
    printf("整数2:");
    scanf("%d", &y);

    printf("x和y的平方差是%d。\n", diff(sqr(x), spr(y)));
    return 0;
}

运行结果:
image.png
函数sqr会返回形参a所接收值的平方,所以函数调用表达式sqr(x)和sqr(y)的判断结果是16和25,这两个数会被直接作为调用函数diff时的实参传递。因此函数表达式diff(sqr(x),sqr(y))就是diff(16,25),对该表达式进行判断,就会得到函数diff返回的9。

调用其他函数

在自己创建的函数中也可以调用其他函数,求4个数中的最大值代码如下:

#include<stdio.h>

//求两个数最大值
int max2(int x, int y)
{
   
   
    return (x > y ? x : y);
}

//求4个数的最大值
int max4(int a, int b, int c, int d)
{
   
   
    return max2(max2(a, b), maxz(b, c));
}

int main()
{
   
   
    int n1 = 0;
    int n2 = 0;
    int n3 = 0;
    int n4 = 0;

    puts("请输入4个整数。");
    printf("整数1:");
    scanf("%d", &n1);
    printf("整数2:");
    scanf("%d", &n2);
    printf("整数3:");
    scanf("%d", &n3);
    printf("整数4:");
    scanf("%d", &n4);

    printf("最大值是:%d\n", max4(n1, n2, n3, n4));
    return 0;
}

我们可以认为函数就是程序的一个零件,例如,想要实现显示功能的时候,就调用printf这个零件。在制作零件的过程中,如果有其他方便的零件,我们也可以大量的使用。

值传递

下面是一个计算幂的函数,如果n是整数,则通过对x进行n次乘法运算得出的n次方幂,代码如下:

#include<stdio.h>

double power(double a, int b)
{
   
   
    int i = 0;
    double temp = 1.0;

    for ( i = 1; i <= b; i++)
    {
   
   
        temp *= a;
    }
    return temp;
}

int main()
{
   
   
    double a = 0.0;
    int b = 0;

    printf("求a的b次方幂。\n");
    printf("实数a:");
    scanf("%d", &a);
    printf("整数b:");
    scanf("%d", &b);

    printf("%.2f的%d次幂是%.2f", a, b, power(a, b));
    return 0;
}

如上所示,形参a被赋上实参a的值,形参b被赋上实参b的值,像这样通过值来进行参数传递的机制称为值传递。
函数间参数的传递是通过值传递进行的。
这就相当于我们复印一本书,在复印版的书上用红色铅笔写写画画,不会对原来那本书造成任何影响。
形参a是实参a的副本,形参b是实参b的副本。所以在被调用一方的函数中,即使改变接收的形参的值,调用一方的实参也不会改变。

函数设计

上面讲到了函数定义和函数调用相关的基础知识,下面来讲更加正式的函数创建方法等。

没有返回值的函数

显示出一个直角在左下方的等腰 直角三角形,代码如下:

#include<stdio.h>

void put_stars(int n)
{
   
   
    while (n-->0)
    {
   
   
        putchar('*');
    }
}

int main()
{
   
   
    int i = 0;
    int len = 0;

    printf("生成一个直角在左下方的等腰直角三角形。\n");
    printf("短边;");
    scanf("%d", &len);

    for ( i = 0; i < len; i++)
    {
   
   
        put_stars(i);
        putchar('\n');
    }
}

本函数只是用来进行显示的,因此没有需要返回的值,这种没有返回值的类型,要声明为void。

通用性

通过函数使用put_stars可以把用于显示三角形的二重循环简化为一重循环,从而提高程序的可读性。
显示直角在右下方的等腰直角三角形代码如下:

#include<stdio.h>

void put_chars(int ch, int n)
{
   
   
    while (n-->0)
    {
   
   
        putchar(ch);
    }
}

int main()
{
   
   
    int i = 0;
    int len = 0;

    printf("生成一个直角在右下方的等腰直角三角形。\n");
    printf("短边:");
    scanf("%d", &len);

    for ( i = 0; i < len; i++)
    {
   
   
        put_chars(' ', len - i);
        put_chars('*', i);
        putchar('\n');
    }
    return 0;
}

本程序还需要连续显示空白字符,因此需要创建另一个函数put_chars来代替函数put_stars。该函数可以连续显示出n个通过形参传递过来的字符。

不含形参的函数

输入一个正整数并显示其倒转之后的值,代码如下:

#include<stdio.h>

int scan_pint(void)
{
   
   
    int temp = 0;
    do
    {
   
   
        printf("请输入一个正整数;");
        scanf("%d", &temp);
        if (temp<=0)
        {
   
   
            puts("\a请不要输入非正整数。");
        }
    } while (temp<=0);
    return temp;
}

int rev_int(int num)
{
   
   
    int temp = 0;
    if (num>0)
    {
   
   
        do
        {
   
   
            temp = temp * 10 + num % 10;
            num /= 10;
        } while (num>0);
    }
    return temp;
}

int main()
{
   
   
    int nx = scan_pint();

    printf("该整数倒转之后的值是%d。\n", rev_int(nx));
    return 0;
}

函数scan_pint读取从键盘输入的正整数并返回,该函数不接收形参,为了加以说明在小括号里面写了void。

函数返回值的初始化

main函数中声明变量nx的部分,该变量的初始值是函数scan_pint()的调用表达式,变量nx使用函数的返回值进行初始化。

作用域

函数scan_pint和函数rev_pint都包含一个拥有相同标识符的变量,但是它们却是各自独自不同的变量。
也就是说,函数scan_pint中的temp变量是函数scan_pint特有的变量,而rev_pint中的变量temp是函数rev_pint中特有的变量。
赋给变量的标识符,它的名称都有个一通用的范围,称为作用域
在程序块中声明的变量的名称,只在该程序块中通用,在其他区域都无效,也就是说,变量的名称从变量声明的位置开始,到包含该声明的程序块最后的大括号为止,这一区间内通用,这样的作用域称为块作用域

文件作用域

输入5名学生的分数,显示其中的最高分,代码如下:

#include<stdio.h>

#define NU  5
int tensu[NU];
int top(void);

int mian()
{
   
   
    extern  int tensu[];
    int i = 0;

    printf("请输入%d学生的分数。\n",NU);
    for ( i = 0; i < NU; i++)
    {
   
   
        printf("%d:", i + 1);
        scanf("%d", &tensu[i]);

    }

    printf("最高分=%d\n", top());
    return 0;
}

int top(void)
{
   
   
    extern  int tensu[];
    int i = 0;
    int max = tensu[0];

    for ( i = 0; i < NU; i++)
    {
   
   
        if (tensu[i]>max)
        {
   
   
            max = tensu[i];

        }
    }
    return max;
}

在函数的程序块中声明的变量等标识符是该程序块特有的部分,而像数组tensu这样,在函数外声明的变量标识符,其名称从声明的位置开始,到该程序的结尾都是通用的。这样的作用域称为文件作用域。

声明和定义

在上面的程序中声明,一个名为tensu的数组,像这样创建变量实体的声明称为定义声明,另外使用extern的声明表示”使用的在某处创建的tensu“,这里并没有真正创建出变量的实体,因此称为非定义声明。
由于数组tensu是在函数外定义的,所以只需要在main函数或top函数中明确声明要使用它,就可以放心使用。

函数原型声明

编译器在读取数据的时候,也是按照从头到尾的顺序依次读取的,因为本程序中函数top的函数定义在main函数之后,所以要想在main函数中调用top函数,编译器就需要知道。
因此就需要如下声明:
int top(void);
像这样明确记述了函数的返回类型,以及形参的类型和个数等的声明称为函数原型声明。
函数原型声明只声明了函数的返回值和形参等相关信息,并没有定义函数的实体。如果函数返回值的类型和形式参数发生了改变,那么函数定义和函数原型声明两部分都必须进行修改。

头文件和文件包含指令

通过函数原型声明,可以指定函数的参数以及返回值的类型等信息。这样就可以放心调用该函数了。
库函数printf或者putchar等的函数原型声明都包含在中,因此必须要使用下述固定的指令。
#include<stdio.h>
通过#include指令,就可以把中的全部内容都读取到程序中。包含库函数的函数原型声明的称为头文件,而取得头文件内容的#include指令称为文件包含指令。

函数的通用性

函数top的工作过程如下:
找出int型数组tensu最前面NU个元素的最大值,然后返回该值。
当我们创建函数的时候就需要考虑函数的通用性。

可以处理任意数组

可以处理不同元素个数的数组

数组的传递

计算英语分数和数学分数,代码如下:

#include<stdio.h>
#define NU 5

int max_of(int v[],int n)
{
   
   
    int i = 0;
    int max = v[0];

    for ( i = 1; i < n; i++)
    {
   
   
        if (v[i]>max)
        {
   
   
            max = v[i];
        }
    }
    return max;
}

int main()
{
   
   
    int i = 0;
    int eng[NU];
    int mat[NU];
    int max_e = 0;
    int max_m = 0;

    printf("请输入%d名学生的分数。\n", NU);
    for ( i = 0; i < NU; i++)
    {
   
   
        printf("[%d]英语:", i + 1);
        scanf("%d", &eng[NU]);
        printf("    数学:");
        scanf("%d", &mat[NU]);
    }

    max_e = max_of(eng, NU);
    max_m = max_of(mat, NU);

    printf("英语最高分=%d\n", max_e);
    printf("数学最高分=%d\n", max_m);

    return 0;
}

函数max_of的动作如下:
找出包含任意个元素的int 类型数组中的元素的最大值,然后返回该值。

函数的传递和const类型的修饰符

被调用函数中作为形参接收到的数组,就是函数调用时被作为实参的数组。
因此,对接受的数组元素进行修改,也会反映到调用时传入的数组中,下面让我们看以下代码:

#include<stdio.h>

void set_zero(int v[], int n)
{
   
   
    int i = 0;

    for ( i = 0; i < n; i++)
    {
   
   
        v[i] = 0;
    }
}

void printf_array(const int v[], int n)
{
   
   
    int i = 0;

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

int main()
{
   
   
    int ary1[] = {
   
   1,2,3,4,5};
    int ary2[] = {
   
    3,2,1 };

    printf("ary1=");
    printf_array(ary1, 5);
    putchar('\n');
    printf("ary2=");
    printf_array(ary2, 3);
    putchar('\n');

    set_zero(ary1, 5);
    set_zero(ary2, 3);

    printf("把0赋值给两个数组的所有元素。\n");
    printf("ary1=");
    printf_array(ary1, 5);
    putchar('\n');
    printf("ary2=");
    printf_array(ary2, 3);
    putchar('\n');

    return 0;
}

为了解决这个问题,C语言提供了禁止在函数内修改接收到的数组内容的方法,只要在声明形参的时候加上被称为const的类型修饰符就可以了。
如果只是引用所接收的数组元素的值,而不改写的话,在声明接收数组的形参,就应该加上const。这样函数调用方就可以放心的调用函数了。

线性查找(顺序查找)

在数组中查找目标值的程序代码如下;

 #include<stdio.h>
#define NU 5
#define FAILD -1

int search(const int vx[], int key, int n)
{
   
   
    int i = 0;

    while (1)
    {
   
   
        if (i==n)
        {
   
   
            return FAILD;
        }
        if (vx[i]==key)
        {
   
   
            return i;
        }
        i++;
    }
}

int main()
{
   
   
    int i = 0;
    int ky = 0;
    int idx = 0;
    int vx[NU];

    for ( i = 0; i < NU; i++)
    {
   
   
        printf("vx[%d]:", i);
        scanf("%d", &vx[i]);
    }
    printf("要查找的值:");
    scanf("%d", &ky);

    //从元素个数为NU的数组中查找ky
    idx = search(vx, ky, NU);

    if (idx==FAILD)
    {
   
   
        puts("查找失败。");
    }
    else
    {
   
   
        printf("%d是数组的第%d号元素。\n", ky, idx + 1);
    }
    return 0;
}

函数search从元素数为n的int型数组vx的开头,顺次查找是否存在与key值相同的元素,如果有,则返回数组元素下标。如果没有,则返回FAILD,也就是-1。
函数search中while语句的控制表达式是”1“,因此只有在执行return 语句的时候才跳出循环,否则循环体将会一直重复执行下去。
像这样,从数组的开头出发顺次搜索,找出与目标的元素的一系列操作,称为线性查找或者顺序查找

哨兵查找法

进行循环操作的时候,需要不停判断是否满足两个结束循环条件,虽说判断很简单,但是经过数次累积之后,也是一个不小的负担。
如果数组的大小还有富余,我们就可以把想要查找的数值存储到数组的末尾的元素v[n]中,这样一来,即使数组没有想要查找的数值,当遍历到v[n]的时候,也会满足条件。
在数组末尾追加数据称为哨兵,使用哨兵进行查找的方法称为哨兵查找法。使用这种方法可以简化对循环结束条件的判断。
代码如下:

#include<stdio.h>
#define NU 5
#define FAILED -1

int search(int v[], int key, int n)
{
   
   
    int i = 0;

    v[n] = key;

    while (1)
    {
   
   
        if (v[i]==key)
        {
   
   
            break;
        }
        i++;
    }
    return (i < n ? i : FAILED);
}

int main()
{
   
   
    int i = 0;
    int ky = 0;
    int idx = 0;
    int vx[NU + 1];

    for ( i = 0; i < NU; i++)
    {
   
   
        printf("vx[%d]:", i);
        scanf("%d", &vx[i]);
    }

    printf("要查找的值:");
    scanf("%d", &ky);

    if ((idx=search(vx,ky,NU))==FAILED)
    {
   
   
        puts("\a查找失败。");
    }
    else
    {
   
   
        printf("%d是数组的第%d号元素。\n", ky, idx + 1);
    }
    return 0;
}

由于函数search需要改变数组v的内容,因此在声明形参的时候不能加入const类型修饰符。
使用赋值运算符=进行赋值
将函数search的返回值赋给变量idx。
使用相等运算符==进行相等性的判断
判断赋值表达式idx=search(vx,ky,NU)和FAILED是否相等。

多维数组的传递

求4名学生在两次考试中3课程的的总分并显示。
代码如下:

#include<stdio.h>

void mat_add(const int a[4][3], const int b[4][3], int c[4][3])
{
   
   
    int i = 0;
    int j = 0;

    for ( i = 0; i < 4; i++)
    {
   
   
        for ( j = 0; j < 3; j++)
        {
   
   
            c[i][j] = a[i][j] + b[i][j];
        }
    }
}

void mat_printf(const int m[4][3])
{
   
   
    int i = 0;
    int j = 0;

    for ( i = 0; i < 4; i++)
    {
   
   
        for ( j = 0; j < 3; j++)
        {
   
   
            printf("%4d", m[i][j]);
        }
        putchar('\n');
    }
}

int main()
{
   
   
    int tensu1[4][3] = {
   
    {
   
   91,63,78},{
   
   67,72,46},{
   
   89,34,53},{
   
   32,54,34} };
    int tensu2[4][3] = {
   
    {
   
   97,67,82},{
   
   73,43,46},{
   
   97,56,21},{
   
   85,46,35} };
    int  sum[4][3];

    mat_add(tensu1, tensu2, sum);

    puts("第一次考试的分数:");
    mat_printf(tensu1);
    puts("第二次考试的分数:");
    mat_printf(tensu2);
    puts("总分:");
    mat_printf(sum);

    return 0;
}

代码运行结果:
image.png

作用域和存储期

要创建大规模程序,必须首先理解作用域和存储期。

作用域和标识符的可见性

在下面的程序中对变量x的声明总共有三处,代码如下:

#include<stdio.h>

int x = 75;
void printf_x(void)
{
   
   
    printf("x=%d\n", x);
}

int main()
{
   
   
    int i = 0;
    int x = 999;

    printf_x();

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

    for ( i = 0; i < 5; i++)
    {
   
   
        int x = i * 100;
        printf("x=%d\n", x);
    }

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

    return 0;
}

运行结果:
image.png
首先我们来看下int x = 75;处声明的x。该变量的初始值为75,因为它在函数外面声明定义的,所以这个x拥有文件作用域。
因此,函数print_x中的”x“就是上述的x,程序执行后,屏幕上会输出
x=75 ……显示的是x的值
因为printf_x();处调用了函数printf_x,所以会首先进行上面的打印显示。
注意:
如果两个同名变量分别拥有文件作用域和块作用域,那么只要拥有块作用域的变量是”可见“的,而拥有文件作用域的变量会被”隐藏“起来。
当同名变量都被赋予了块作用域的时候,内层的变量是”可见“的,而外层的变量会被”隐藏“起来。

存储期

在函数中声明的变量,并不是从程序开始到程序结束始终有效的,变量的生存期也就是寿命有两种,它们可以通过存储期这个概念来实现。
代码如下:

#include<stdio.h>

int fx = 0;

void func(void)
{
   
   
    static int sx = 0;
    int ax = 0;

    printf("%3d%3d%3d\n", ax++, sx++, fx++);
}

int main()
{
   
   
    int i = 0;
    puts("ax sx fx");
    puts("----------");
    for ( i = 0; i < 10; i++)
    {
   
   
        func();
    }
    puts("----------");

    return 0;
}

运行结果:
image.png
在函数func中声明了sx和ax两个变量,但是声明sx的时候我们使用了存储类说明符static。可能正因为如此,虽然使用相同的值进行初始化并递增的,但最终的ax和sx的值并不相同。

  • 自动存储期

在函数中不使用存储类说明符static而定义出的对象(变量),被赋予了自动存储期,它具有以下特点:
程序执行到对象声明的时候就创建出了相对应的对象,而执行到包含该声明的程序块的结尾,也就是大括号的时候,该对象就会消失。

  • 静态存储期

在函数中使用static定义出来的对象,或者在函数外声明定义出来的对象都被赋予了静态存储期,它具有以下特点:
在程序开始执行的时候,就具体地说是在main函数执行之前的准备阶段被创建出来,在程序结束的时候消失。
也就是说,该对象拥有了”永久“的寿命。另外如果不显示地进行初始化,则该对象会自动初始化为0。
对象的存储期如下图:
image.png

总结

  • 将多个处理集中到一起进行时,可以使用函数这一程序的零件。返回类型、函数名、形参这三个部分决定了函数的特征。不接收参数的函数,其形参类型为void。
  • 函数体是复合语句(程序块)。如果有仅在函数中使用的变量,原则上应在该函数中声明和使用。
  • 函数调用的形式是在函数名后面加上小括号,这个括号称为函数调用运算符。如果没有实参,则小括号为空。有多个实参的情况下,使用逗号隔开。
  • 进行函数调用后,程序的流程将一下子跳转到该函数处。

image.png
image.png
image.png
以上就是我关于函数的介绍,希望都帮到大家。也请大家给我指点不足,谢谢!!!

相关文章
|
5月前
|
存储 算法 C语言
二分查找算法的概念、原理、效率以及使用C语言循环和数组的简单实现
二分查找算法的概念、原理、效率以及使用C语言循环和数组的简单实现
|
5月前
|
存储 算法 安全
数据结构学习记录——图应用实例-拯救007(问题描述、解题思路、伪代码解读、C语言算法实现)
数据结构学习记录——图应用实例-拯救007(问题描述、解题思路、伪代码解读、C语言算法实现)
39 0
|
自然语言处理 前端开发 JavaScript
前端经典面试题 | 闭包的作用和原理
前端经典面试题 | 闭包的作用和原理
|
JSON 前端开发 Java
《优化接口设计的思路》系列:第一篇—接口参数的一些弯弯绕绕
大家好!我是sum墨,一个一线的底层码农,平时喜欢研究和思考一些技术相关的问题并整理成文,限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。 作为一名从业已达六年的老码农,我的工作主要是开发后端Java业务系统,包括各种管理后台和小程序等。在这些项目中,我设计过单/多租户体系系统,对接过许多开放平台,也搞过消息中心这类较为复杂的应用,但幸运的是,我至今还没有遇到过线上系统由于代码崩溃导致资损的情况。这其中的原因有三点:一是业务系统本身并不复杂;二是我一直遵循某大厂代码规约,在开发过程中尽可能按规约编写代码;三是经过多年的开发经验积累,我成为了一名熟练工,掌握了一些实用的技巧。
70 0
|
机器学习/深度学习 算法 搜索推荐
【数据结构】时间复杂度(详细解释,例子分析,易错分析,图文并茂)
【数据结构】时间复杂度(详细解释,例子分析,易错分析,图文并茂)
424 0
|
编解码 缓存 NoSQL
7点 讲明白地图切片的概念与原理
7点 讲明白地图切片的概念与原理
474 0
|
数据可视化 算法
大白话理解递归本质,可视化递归过程
大白话理解递归本质,可视化递归过程
211 0
|
SQL 测试技术
软件测试面试题:解释以下函数及他们的不同之处?
软件测试面试题:解释以下函数及他们的不同之处?
73 0
|
存储 算法
算法不难的话,也挺简单的哈
算法不难的话,也挺简单的哈
107 0