C语言——函数

news2024/11/24 20:24:26

目录

  • 1. 函数基本用法
    • 1.1 定义和三要素
    • 1.2 函数的声明和定义
      • 1.2.1 函数声明
      • 1.2.2 函数定义格式
    • 1.3 函数调用
    • 1.4 函数传参
      • 1.4.1 值传递
      • 1.4.2 地址传递
      • 1.4.3 数组传递
    • 1.5 函数和栈区
  • 2. 开辟堆空间
    • 2.1 堆的概念
    • 2.2.malloc函数
      • 2.2.1 定义
      • 2.2.2 用法
    • 2.3 free()函数定义
    • 注意📢:
    • 2.4 函数中开辟堆空间
  • 3.string函数族
    • 3.1 strcpy
    • 3.2 strlen
    • 3.3 strcat
    • 3.4 strcmp
  • 4.递归函数
    • 4.1 概念
    • 4.2 执行过程

1. 函数基本用法

1.1 定义和三要素

函数是一个可以完成特定功能的代码模块,其程序代码是独立的,通常有返回值,也可以没有。

函数的三要素:

功能:函数要实现的功能。

参数:在函数声明和调用时定义的遍历,它用于传递数据给函数。

【1】形参:就是在函数声明的时候定义的变量,用于传递信息给函数。此时它没有具体的数值。

【2】实参:就是在调用函数时传递给函数的实际数值。

返回值:函数调用后留下的右值。

1.2 函数的声明和定义

1.2.1 函数声明

存储类型 数据类型 函数名(数据类型 形参1,数据类型 形参2,…);

1.2.2 函数定义格式

存储类型 数据类型 函数名(数据类型 形参1,数据类型 形参2,…)

{

​ 函数体;

}

函数名:是一个标识符,要符合标识符命名规则。

数据类型:是整个函数的返回值类型,如果没有返回值为void。

形式参数说明:是逗号分隔的多个变量的形式说明,简称形参。

形参就是函数声明或定义时括号中的变量,因为形式参数只有在函数调用时也被传递真实的数值。

大括号对{语句序列},称为函数体,函数体由大于等于零个语句组成的。

函数的数据总结:

(1)没有参数:括号中的参数列表可以省略,也可以写void。

(2)没有返回值:数据类型为void,函数内没有return语句。

(3)有返回值:要跟根据返回值的数据类型定义函数的数据类型,可以用return接收返回值。

(4)定义子函数时可以直接在主函数上面,如果想在主函数下面定义需要在主函数上面事先声明。

1.3 函数调用

(1)没有返回值:直接调用

​ 函数名(实参);

(2)有返回值:要在函数内定义一个与返回值类型相同的变量用return接收。如果不需要接收返回值,就直接调用函数。如果想拿到返回值来用,可以在调用函数前设一个同类型变量去接收。

实参:在调用有参数函数时,函数名后面括号中的参数称为“实参”,此时是我们传递给函数的真实数值。实参可以是:常量、变量、表达式、函数等。

代码示例:

#include <stdio.h>
void fun()                //实现打印功能
{
    printf("in fun\n");
}

void add(int a,int b)    //实现两数相加函数,无返回值。
{
    int c=a+b;
    printf("a+b=%d\n",c);
}
int add2(int a,int b)    //实现两数相加函数,有返回值。
{
    return a+b;
}

int dec(int a,int b);    //实现两数相减函数,子函数在主函数下面定义需要在上面事先声明。
int main(int argc, char const *argv[])
{
    int n1=2,n2=3;
    int rel=0,diff=0;
    fun();
    add(2,3);
    add(n1,n2);
    rel=add2(n1,n2);
    printf("in main add:%d\n",rel);
    diff=dec(6,5);
    printf("in main dec :%d\n",diff);
    return 0;
}

int dec(int a, int b)
{
    return a-b;
}

练习:定义求x的n次方值的函数( x是实数, n为正整数)。

#include <stdio.h>
float mypow(float x, int n)
{
    float rel=1;
    if(n<0)
    {
        printf("error\n");
        return -1;
    }
    for(int i=0;i<n;i++)
        rel *=x;
    return rel;
}

int main(int argc, char const *argv[])
{
    float result=mypow(1.5,2);
    printf("result= %f\n",result);
    return 0;
}

练习:编写一个函数,函数的2个参数,第一个是一个字符,第二个是一个char *,

返回字符串中该字符的个数。

#include <stdio.h>

int str_fang(char c,char *p)
{
    int n=0;
    while (*p)
    {
        if(*p == c)
            n++;
        p++;
    }
    return n;
}

int main(int argc, char const *argv[])
{
    char s[100]="helloooooo";
    int val=str_fang('o',s);
    printf("%d\n",val);
  
    return 0;
}

练习:编程实现strlen函数的功能,strlen计算字符串实际长度,不包含’\0’

#include <stdio.h>
int mystrlen(char *s)
{
    int n=0;
    while(*s != '\0')
    {
        n++;
        s++;
    }
    return n;
}

int main(int argc, char const *argv[])
{
    int len=mystrlen("hello");
    printf("%d\n",len);
  
    return 0;
}

1.4 函数传参

1.4.1 值传递

单向传递,将实参传递给形参使用,改变形参实参不会受影响。

void fun(int a, int b)
{
    a++;
    b++;
    printf("in fun: a=%d b=%d\n", a, b);
}
int main(int argc, char const *argv[])
{
    int n1 = 10, n2 = 20;
    fun(n1, n2);
    printf("in main: a=%d b=%d\n", n1, n2);
    return 0;
}

1.4.2 地址传递

双向传递,在函数中修改形参,实参也会随之变化。

void fun2(int *a, int *b)
{
    *a = 40;
    *b = 90;
    printf("in fun2: a=%d b=%d\n", *a, *b);
}

int main(int argc, char const *argv[])
{
    int n1 = 10, n2 = 20;
    fun2(&n1, &n2);
    printf("in main: a=%d b=%d\n", n1, n2);
    return 0;
}

1.4.3 数组传递

和地址传递一样,参数中存在数组的定义,也认为是指针。

void fun3(int *arrp, int n)
{
    int *p = arrp;
    printf("in fun3 array:\n");
    *(p + 1) = 100;
    for (int i = 0; i < n; i++)
    {
        printf("%d %d\n", p[i], *(p + i));
    }
    printf("in fun3: *(p+1)= %d\n", *(p + 1));
}
int main(int argc, char const *argv[])
{
    int arr[5] = {1, 2, 3, 4, 5};
    fun3(arr, 5);
    printf("in main array:\n");
    for (int i = 0; i < 5; i++)
    {
        printf("%d %d\n", arr[i], *(arr + i));
    }
    printf("in main: *(arr+1)= %d\n", *(arr + 1));
    return 0;
}

1.5 函数和栈区

栈用来存储函数内部(包括main()函数)的变量。它是一个FILO(First In Last Out),先进后出的结构。当一个函数运行结束后,这个函数所有在栈中的变量都会被删除,并且它们所占的空间将会被释放。这就产生了函数内的局部变量。栈区由CPU自动管理,不需要手动申请和释放。

p9IQRHI.png

2. 开辟堆空间

2.1 堆的概念

申请的空间种分为五个区域栈区(堆栈区),堆区,全局区,字符常量区,代码区,我们之前讲的这些定义局部变量、数组都是在内存的栈区存储。

栈区和堆区的区别

栈区:是由CPU自动申请和释放的,不需要我们手动申请。

堆区:需要我们自己随时申请,由我们自己去释放的。随用随取,用完释放。

2.2.malloc函数

2.2.1 定义

 #include <stdlib.h>
 void *malloc(size_t size);
  • 功能:在堆区开辟大小为size的空间

  • 参数:size:开辟空间的大小,单位为字节。

  • 返回值

    • 成功:返回开辟空间的首地址

    • 失败:空指针NULL

    • malloc( ) 要和free( )搭配使用

2.2.2 用法

malloc内的参数是需要动态分配的字节数,而不是可以存储的元素个数!

代码格式:

type* var_name = (type *)malloc(sizeof(type)*n);

2.3 free()函数定义

 #include <stdlib.h> 
 void free(void *ptr);
  • 功能:释放之前用malloc、calloc和realloc所分配的内存空间。

  • 参数:ptr:堆空间的首地址。

  • 返回值:无

可以释放完堆空以后,把指针赋值为空指针:

free(p);
p=NULL;

malloc和free搭配用法👇:

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
    int *p=(int *)malloc(sizeof(int)*100);

    if(p==NULL)
        printf("lost!\n");
    else 
        printf("success\n");
    free(p);
    p=NULL;
    return 0;
}

注意📢:

  1. 手动开辟堆区空间,要注意内存泄漏

当指针指向开辟堆区空间后,又对指针重新赋值,则没有指针指向开辟的堆区空间,就会造成内存泄漏。

  1. 使用完堆区空间后及时释放空间

例如:

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
    char *p=(char *)malloc(sizeof(char)*32);
   // p="hello"; //错误,指针指向别的地方,没有对堆空间进行操作
    scanf("%s",p);
    printf("%s\n",p);
    free(p);
    p=NULL;
    return 0;
}

2.4 函数中开辟堆空间

思考🤔:如下代码输出结果

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

void fun(char *p)
{
    p= (char *)malloc(32);
    scanf("%s",p);
}

int main(int argc, char const *argv[])
{
    char *m=NULL;
    fun(m);
    printf("%s\n",m);
    //free(m);
    //m=NULL;
    return 0;
}

运行结果:Segmentation fault (core dumped)出现段错误。

p9I314P.png

原因是,函数执行完堆空间会被销毁,不会被保留函数内开辟堆空间的地址,并不会保留m的指向。此时m还指向空。

🎯解决方法1:通过返回值

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

char *fun()
{
    char *p= (char *)malloc(32);
    scanf("%s",p);   
    return p;
}

int main(int argc, char const *argv[])
{
    char *m=fun();
    char *n=fun();
    printf("%s\n",m);
    printf("%s\n",n);
    free(m);
    m=NULL;
    free(n);
    n=NULL;
    return 0;
}

🎯解决方法2:通过传参

#include <stdio.h>
#include <stdlib.h>
void fun(char **p)
{
    *p = (char *)malloc(32);
    scanf("%s", *p);
}

int main(int argc, char const *argv[])
{
    char *m=NULL;
    fun(&m);
    printf("%s\n",m);
    free(m);
    m=NULL;
    return 0;
}

p9I344x.png

3.string函数族

3.1 strcpy

#include <string.h>
char *strcpy(char *dest, const char *src);
  • 功能:实现字符串的复制,包括\0
  • 参数:
    • dest:目标字符串首地址
    • src:源字符串首地址
  • 返回值:目标字符串首地址
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char const *argv[])
{
    char s1[32]="hello";
    char s2[32]="world";
    strcpy(s1,s2);
    printf("%s\n",s1);
    return 0;
}

3.2 strlen

#include <string.h>
size_t strlen(const char *s);
  • 功能:计算字符串长度
  • 参数:s:字符串的首地址
  • 返回值:返回字符串实际长度,不包括‘\0’在内。

3.3 strcat

#include <string.h>
char *strcat(char *dest, const char *src);
  • 功能:用于字符串拼接

  • 参数:

    • dest:目标字符串首地址
    • src:源字符串首地址
  • 返回值:目标字符串首地址

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

int main(int argc, char const *argv[])
{
    char s1[32]="hello ";
    char s2[32]="world";
    strcat(s1,s2);
    printf("%s\n",s1);
    return 0;
}
#include <string.h>
char *strncat(char *dest, const char *src, size_t n);

拼接src的前n个字符

char s1[32]="hello ";
char s2[32]="world";
strncat(s1,s2,4);
printf("%s\n",s1);  //hello worl

3.4 strcmp

#include <string.h>
int strcmp(const char *s1, const char *s2);
  • 功能:用于比较字符串
  • 参数:s1和s2是比较的字符串的首地址
  • 返回值:
    • 1:s1>s2
    • 0: s1==s2
    • -1: s1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char const *argv[])
{
    int a=strcmp("hello","world");
    if(a==0)
        printf("相等!\n");
    else 
        printf("不相等!\n");
    return 0;
}
#include <string.h>
int strncmp(const char *s1, const char *s2, size_t n);

比较两个字符串前n个字符的大小

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char const *argv[])
{
    int a=strncmp("hello world","hello",5);
    if(a==0)
        printf("相等!\n");
    else 
        printf("不相等!\n");
    return 0;
}

练习1:封装函数实现两数交换

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

void swap(int *a, int *b)
{
	int c=0;
	c=*a;
	*a=*b;
	*b=c;
}
int main()
{
	int n1=5,n2=6;
	printf("n1=%d, n2=%d\n",n1,n2);
	swap(&n1,&n2);
	printf("n1=%d, n2=%d\n",n1,n2);
	return 0;
}

练习2:封装函数实现strcpy功能

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

char *myStrcpy(char *dest, char *src)
{
	while(*src != '\0')
	{
		if(*dest!=*src)
			*dest=*src;
		dest++;
		src++;
	}
	*dest='\0';
}
int main()
{
	char s1[32]="hello";
	char s2[32]="world~~";

	myStrcpy(s1,s2);
	printf("%s\n",s1);
}

练习3:封装函数实现strcat功能

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

char *myStrcat(char *dest, char *src)
{
    int len = strlen(dest);
    char *p = dest + len;
    while (*src != '\0')
    {
        *p = *src;
        p++;
        src++;
    }
    *p = '\0';
}

int main()
{
    char s1[32] = "hello ";
    char s2[32] = "world~";
    myStrcat(s1, s2);
    printf("%s\n", s1);
}

练习4: 封装函数实现冒泡排序

#include <stdio.h>

void *maopao(int *arr,int n)
{
    int c=0;
    for (int i=1;i
    {
        for(int j=0;j
        {
            if(arr[j]>arr[j+1])
            {
                c=arr[j];
                arr[j]=arr[j+1];
                arr[j+1]=c;
            }
        }
    }
}
int main(int argc, char const *argv[])
{
    int a[5]={5,4,3,2,1};
    maopao(a,5);
    for(int i=0;i<5;i++)
        printf("%d ",a[i]);
    printf("\n");
    return 0;
}

4.递归函数

4.1 概念

所谓递归函数是指一个函数体中直接或者间接调用了该函数本身,这里的直接调用是指一个函数的函数体中含有调用自身的语句,间接调用是指一个函数在函数体里有调用了其它函数,而其它函数又反过来调用了该函数的情况。

4.2 执行过程

递归函数调用的执行过程分为两个阶段:

(1)递归阶段:从原问题出发,按递归公式递推从未知到已知,最终达到递归终止条件。就是从最里层开始算,然后一层层算,直到终止。

(2)回归阶段:按递归终止条件求出结果,逆向逐步带入递归公式,回到原问题求解。

例子:求5的阶乘5!

#include <stdio.h>

int fac(int n)
{
    if(n==1)
        return 1;
    else
        return n*fac(n-1);
}
int main(int argc, char const *argv[])
{
    int n=5,ret=fac(n);
    printf("ret=%d\n",ret);
    return 0;
}

练习:

斐波那契数列 指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波纳契数列以如下被以递归的方法定义:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*) 求第五个数。

F(n) :

1 n<=2

F(n-1)+F(n-2) n>2

#include <stdio.h>

int fun(int n)
{
    if (n <= 2)
        return 1;
    else
        return fun(n - 1) + fun(n - 2);
}
int main()
{
    int rel = fun(5);
    printf("rel=%d\n", rel);
    return 0;
}

递归函数调用的执行过程分为两个阶段:

(1)递归阶段:从原问题出发,按递归公式递推从未知到已知,最终达到递归终止条件。就是从最里层开始算,然后一层层算,直到终止。

(2)回归阶段:按递归终止条件求出结果,逆向逐步带入递归公式,回到原问题求解。

例子:求5的阶乘5!

#include <stdio.h>

int fac(int n)
{
    if(n==1)
        return 1;
    else
        return n*fac(n-1);
}
int main(int argc, char const *argv[])
{
    int n=5,ret=fac(n);
    printf("ret=%d\n",ret);
    return 0;
}

练习:

斐波那契数列 指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波纳契数列以如下被以递归的方法定义:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*) 求第五个数。

F(n) :

1 n<=2

F(n-1)+F(n-2) n>2

#include <stdio.h>

int fun(int n)
{
    if (n <= 2)
        return 1;
    else
        return fun(n - 1) + fun(n - 2);
}
int main()
{
    int rel = fun(5);
    printf("rel=%d\n", rel);
    return 0;
}

img

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/552513.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

随机数发生器设计(一)

1 随机数发生器设计概述 密码行业的随机数发生器总体框架标准为GM/T 0103。随机数发生器可以分为硬件随机数发生器和软件随机数发生器。 硬件随机数发生器一般以组成部件的形式集成在安全芯片的内部&#xff0c;或者随机数发生器本身就是安全芯片。考虑到随机数发生器是密码产…

ChatGPT 能自己跑代码了!

公众号关注 “GitHubDaily” 设为 “星标”&#xff0c;每天带你逛 GitHub&#xff01; time leap, sci-fi, photorealistic, --niji 5 --ar 3:2 --s 1000 自 ChatGPT 发布以来&#xff0c;各行各业对其能力探索的举措一直没有停止。 很多大厂纷纷跟进&#xff0c;竞相推出自研…

Springboot +spring security,登录用户数据获取

一.简介 前面章节学习了登录表单的配置并且对源码进行了简单的分析&#xff0c;现在有个问题了&#xff0c;既然用户登录了&#xff0c;那么如何在接口中获取用户信息呢。这篇文章就来看下这个问题&#xff0c;代码中获取登录用户信息。 二.创建项目 如何创建一个SpringSecu…

笔记:BLIP源码之(1)数据集预处理【仅考虑Image-Text Retrieval on COCO】

BLIP&#xff1a;Bootstrapping Language-Image Pre-training for Unified Vision-Language Understanding and Generat 论文的两个贡献如下&#xff1a; 从模型的角度&#xff1a;提出了 Encoder-Decoder (MED) 的多模态混合 An MED can operate either as a unimodal encode…

Js常识三

文章目录 作用域GCclosure变量和函数提升函数参数 作用域 GC Js Gc 算法 引用计数&#xff08;已淘汰&#xff09;标记清除 closure 一句话&#xff1a;内层函数 外层函数的变量 闭包作用&#xff1a;私有化数据&#xff0c;or 私有化状态 变量和函数提升 Js 祖传var变…

C语言结构体初级

目录 一、为什么要用结构体 二、使用结构体的具体形式 1.结构体类型的声明&#xff08;main函数外部&#xff09; 2.结构体变量的定义&#xff08;在main函数内或者外&#xff09; 3.结构体变量的初始化 4.结构体成员的访问 5.结构体的传参 跑了这么久&#xff0c;再坚…

分布式软件架构——单体架构

序言 当一项大工程需要大量人员共同开发&#xff0c;并保证它们分布在网络中的大量服务器节点能够同时运行&#xff0c;那么随着项目规模的增大、运行时间变长&#xff0c;它必然会受到墨菲定律的无情打击。 Murphy’s Law&#xff1a;Anything that can go wrong will go wro…

Qt文件系统源码分析—第四篇QLockFile

深度 本文主要分析Windows平台&#xff0c;Mac、Linux暂不涉及 本文只分析到Win32 API/Windows Com组件/STL库函数层次&#xff0c;再下层代码不做探究 本文QT版本5.15.2 类关系图 QTemporaryFile继承QFile QFile、QSaveFile继承QFileDevice QFileDevice继承QIODevice Q…

法规标准-ISO 17361标准解读

ISO 17361是做什么的&#xff1f; ISO 17361全称为智能交通系统-车道偏离警告系统性能要求和测试程序&#xff0c;其中主要描述了LDWS系统的功能要求及测试要求 系统功能 车道偏离警告系统的功能元件应符合图中的要求&#xff0c;抑制请求、车速检测、驾驶员偏好和其他附加功…

[CTF/网络安全] 攻防世界 simple_js 解题详析

[CTF/网络安全] 攻防世界 simple_js 解题详析 代码分析代码漏洞姿势String[fromCharCode]总结 题目描述&#xff1a;小宁发现了一个网页&#xff0c;但却一直输不对密码。(Flag格式为 Cyberpeace{xxxxxxxxx} ) 页面源代码&#xff1a; 代码分析 function dechiffre(pass_enc){…

StarRocks 集群模式搭建

一、StarRocks 集群模型搭建 上篇文章对 StarRocks 进行了简单的介绍及使用 Docker 进行了快速体验&#xff0c;本篇文章进行StarRocks 集群模型的搭建&#xff0c;下面是上篇文章的地址&#xff1a; StarRocks 极速全场景 MPP 数据库介绍及使用 部署规划 host主机名角色192.…

求解包含约束的最优化问题:拉格朗日乘子法和KKT条件

文章目录 无约束等式约束不等式约束KKT条件 无约束 之前梯度类算法中介绍的最速下降法、牛顿法和拟牛顿法&#xff0c;可以直接使用的条件之一为&#xff1a;决策变量都是无约束的。 用数学语言描述的话&#xff0c;可以表达为&#xff1a;决策变量为 x ( x 1 , x 2 , ⋅ ⋅…

LeetCode104. 二叉树的最大深度(递归非递归)

写在前面&#xff1a; 题目链接&#xff1a;LeetCode104.二叉树的最大深度 编程语言&#xff1a;C 题目难度&#xff1a;简单 一、题目描述 给定一个二叉树&#xff0c;找出其最大深度。 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。 说明: 叶子节点是指没有子…

You Only Look Once:Unified,Real-Time Object Detection总结笔记

一、论文思想 1.将一个图像分成S*S个网格&#xff08;grid cell&#xff09;&#xff0c;如果某个object的中心落在这个网格中&#xff0c;则这个网络就负责预测这个object。 2.每个网格要预测B个bounding box&#xff0c;每个bounding box除了要预测位置之外&#xff0c;还要…

微服务技术(SpringCloud、Docker、RabbitMQ)

目录 一、微服务技术简介 二、服务拆分及远程调用 1.Eureka注册中心 2.Nacos注册中心 3.Nacos配置管理 4.http客户端Feign 三、统一网关Gateway 四、Docker 五、异步通信技术 六、ElasticSearch 一、微服务技术简介 微服务是分布式架构&#xff08;分布式&#xff…

Lesson14---卷积神经网络

14.1 深度学习基础 14.1.1 深度学习的基本思想 特征工程&#xff1a;尽可能选择和构建出好的特征&#xff0c;使得机器学习算法能够达到最佳性能。是机器学习的上限&#xff0c;而算法就是逼近这个上限传统的机器学习特证工程 依靠人工方式提取和设计特征需要大量的专业知识…

低代码系统前端实践之vue-element-admin运行demo

文章目录 1、简介2、实践功能3、实践过程3.0 下载运行demo3.1.1 解决执行npm install或出现以下报错(删掉组件tui-editor相关即可)3.1.2 解决执行npm run dev或出现no module body-parser(安装body-parser即可)3.1.3 解决执行npm run dev或出现error:0308010C:digital envelope…

RK3568平台开发系列讲解(驱动基础篇)RK平台I2C的使用

🚀返回专栏总目录 文章目录 一、I2C 使用情况二、定义和注册 I2C 设备三、定义和注册 I2C 驱动3.1 I2C 驱动定义3.2 I2C 驱动注册3.3 通过 I2C 收发数据沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将对RK I2C 的使用进行学习。 配置 I2C 可分为两大步骤: 定…

【Linux C】GCC编译 GDB调试 从入门到放弃 (gcc调试选项详解、gdb调试、条件断点、远程调试、脚本化调试)

阅读本文可能需要一些基础&#xff0c;比如&#xff1a;C语言基础、Linux基础操作、vim、防火墙等。篇幅有限&#xff0c;本文讲的“比较浅显”。 通过本文你将学会&#xff1a; gcc编译gdb调试 少年你渴望力量吗&#x1f447;&#x1f447;&#x1f447; 一、使用GCC编译C程序…

Antd 下拉面板的位置计算错误

项目场景&#xff1a; 公司使用无界微前端集成ERP项目应用&#xff08;可惜没跟着走一边无界&#xff0c;难受&#xff09;&#xff0c;某些子应用使用时&#xff0c;发现antd的弹窗弹出的位置不对。如下图&#xff1a; 问题描述 无界微前端嵌入的子应用中的antd的下拉框位置…