返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C语言的函数概念与规则你了解吗
  • 591
分享到

C语言的函数概念与规则你了解吗

2024-04-02 19:04:59 591人浏览 泡泡鱼
摘要

目录一、函数概念1.传入参数2.返回值二、函数参数三、指针函数-函数名指针化1.指针指向其他函数的函数名(标签)效果2.指针指向其他函数的地址效果3.通过二级指针,将一组函数线性化四

一、函数概念

函数三要素
int fun(int,int,char){xxx}

函数名 (地址)输入参数输出参数

1.传入参数

实参: 调用时传入的具体值
形参: 函数内部接受的变量

2.返回值

返回函数处理的结果数据(另一种方式是函数外部使用址传递参数,来获得函数处理的数据)

二、函数参数

C语言函数传参,实际上就是copy的过程,参数类型的区别在于copy的多少的问题,当然类型不同可能存在丢失部分数据情况(copy不完整)


void printAddress(int a)
{
	//printAddress a地址:0xc
    printf("printAddress a地址:%p\n",a);
}
int main()
{
    int a = 12;
    //main a地址:0xc
    printf("main a地址:%p\n",a);
    printAddress(a);
    return 0;
}

void printAddress(int a)
{
	//printAddress a地址:0xffffff9b
    printf("printAddress a地址:%p\n",a);
}
int main()
{
    char a = "ABCDE";
    //main a地址:0xffffff9b
    printf("main a地址:%p\n",a);
    printAddress(a);
    return 0;
}

void printAddress(int a)
{
    //printAddress a地址:0xeccc1e18
    printf("printAddress a地址:%p\n", a);
}
int main()
{
    int a = 12;
    int *p_a;
    p_a = &a;
    //main a地址:0x7ffeeccc1e18
    printf("main a地址:%p\n", p_a);
    printAddress(p_a);
    return 0;
}

三、指针函数-函数名指针化

通过函数三要素可以得出,指针也可以表示函数
int (*p)(int,int,char){xxx} 与指针指向二维数组类似,指针必须要加(),来提高程序对他解读的优先级,而不是默认从右往左读

1.指针指向其他函数的函数名(标签)效果


int main()
{
    int (*printf2)(const char *,...);
    //HelloWOrld
    printf("HelloWOrld\n");
    printf2 = printf;
    //FFFF
    printf2("FFFF\n");
    return 0;
}

2.指针指向其他函数的地址效果


int main()
{
    int (*printf2)(const char *, ...);
    //HelloWOrld 0x7fff204b50b8
    printf("HelloWOrld %p \n", printf);
    printf2 = (int (*)(const char *, ...))0x7fff204b50b8;
    //FFFF
    printf2("FFFF\n");
    return 0;
}

3.通过二级指针,将一组函数线性化


int (*p[5])(int,int);
p[0]=func1;
p[1]=func2;
p[2]=func3;
//使用效果,可以替代switch
p[day](8,9);

四、函数值传递和址传递

值传递:void fun1(int a){...}传入数据a copy到函数中,函数中数据的修改不影响函数外被传入的数据
址传递:void func2(*a){...}传入数据地址&a copy到函数中,函数中数据的修改是在该地址上修改的,函数外被传入的数据也处在该内存地址上,所以会数据被修改

仅查看时用值传递
读写资源或节省资源时 使用址传递

五、函数连续空间的传递

连续空间传递,一般都会选择使用址传递,使用值传递浪费资源过多

1.结构体(变量)

值传递示例


struct product_t
{
    char name[20];
    int price;
};

void println(struct product_t product)
{
    strncpy(product.name, "牙刷", 20);
    product.price = 3;
    //println:牙刷
    printf("println:%s \n", product.name);
    //println:3
    printf("println:%d \n", product.price);
}
int main()
{
    struct product_t product;
    strncpy(product.name, "手机", 20);
    product.price = 3666;
    println(product);

    //main:手机
    printf("main:%s \n", product.name);
    //main:3666
    printf("main:%d \n", product.price);
    return 0;
}

址传递示例 (通过指针)


struct product_t
{
    char name[20];
    int price;
};

void println(struct product_t *product)
{
    //product[0]等价于*product此处可以替换,但是需要加()让程序优先识别,即:(*product)
    strncpy(product[0].name, "牙刷", 20);
    product[0].price = 3;
    //println:牙刷
    printf("println:%s \n", product[0].name);
    //println:3
    printf("println:%d \n", product[0].price);
}
int main()
{
    struct product_t product;
    strncpy(product.name, "手机", 20);
    product.price = 3666;
    println(&product);

    //main:牙刷
    printf("main:%s \n", product.name);
    //main:3
    printf("main:%d \n", product.price);
    return 0;
}

2.数组(标签)

数组int names[10];在定义时,编译器已经知道其首地址被names标签描述,因此数组作为形参时只需要传递数组的标签名和偏移量即可names[10]即可

数组址传递数据示例


//C语言现在优化允许使用int p[10],便于阅读 实际上效果与int *p一致,都是址传递
void println(int *p)
{
    p[0] = 77;
    //println:77
    printf("println:%d \n", p[0]);
    //println:11
    printf("println:%d \n", p[1]);
}
int main()
{
    int prices[10] = {22, 11, 55};
    println(prices);

    //main:77
    printf("main:%d \n", prices[0]);
    //main:11
    printf("main:%d \n", prices[1]);
    return 0;
}

数组址传递地址示例


//C语言现在优化允许使用int p[10],便于阅读 实际上效果与int *p一致,都是址传递
void println(int *p)
{
    p[0] = 77;
    //println:0x7ffee8964df0
    printf("println:%p \n", &p[0]);
    //println:0x7ffee8964df4
    printf("println:%p \n", &p[1]);
}
int main()
{
    int prices[10] = {22, 11, 55};
    println(prices);

    //main:0x7ffee8964df0
    printf("main:%p \n", &prices[0]);
    //main:0x7ffee8964df4
    printf("main:%p \n", &prices[1]);
    return 0;
}

如上两段代码,数组传递为址传递,数组标签名本身就是地址的标签,与指针非常相似

3.连续空间的只读

定义参数时使用const修饰指针所指的内存地址即可,如const char *p,这也是开发时默认的规范
读写函数形参:char *p;
只读函数形参:const char *p
如strncpy函数的源码:char *stpncpy(char *dst, const char *src, size_t n)

六、函数返回值

返回值与参数一样,也是copy的原理传递,可以copy值,也可以copy地址


char func1()
{
    char s = 'A';
    return s;
}
int main()
{
    char s= func1();
    //41
    printf("%X",s);
    return 0;
}

注意:指针是C语言中返回空间的唯一类型 (无法返回函数内部创建的变量地址,会被回收:异常)
int * func();


char * func1()
{
    return "HelloWorld";
}
int main()
{
    char *p= func1();
    //HelloWorld
    printf("%s",p);
    return 0;
}

工程中一般不使用上述方案(常量区存储),意义不大,通常使用静态区存储局部变量(程序结束才回收),即如下方法


char * func1()
{
    static char abc[] = "HelloWorld";
    return abc;
}
int main()
{
    char *p= func1();
    //HelloWorld
    printf("%s",p);
    return 0;
}

也可以使用堆区存储malloc()函数中创建的变量,注意使用完毕后一定要释放内存(free())


char * func1()
{
    char *s = (char *)malloc(50);
    strncpy(s,"HelloWorld",50);
    return s;
}
int main()
{
    char *p= func1();
    //HelloWorld
    printf("%s",p);
    free(p);
    return 0;
}

总结

本章主要为C语言函数概念和规则

本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注编程网的更多内容!

--结束END--

本文标题: C语言的函数概念与规则你了解吗

本文链接: https://lsjlt.com/news/133696.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C语言的函数概念与规则你了解吗
    目录一、函数概念1.传入参数2.返回值二、函数参数三、指针函数-函数名指针化1.指针指向其他函数的函数名(标签)效果2.指针指向其他函数的地址效果3.通过二级指针,将一组函数线性化四...
    99+
    2024-04-02
  • C语言的strcpy函数你了解吗
    目录strcpy函数原型参数讲解返回值详解函数详解第二个注意点:目标空间必须足够大,以确保能存放源字符串第三个注意点:目标空间必须可变总结strcpy 拷贝字符串到目标地址 函数原...
    99+
    2024-04-02
  • C语言的abs()函数和div()函数你了解吗
    C语言库中提供了许多函数,这样需要计算的时候,可以直接借助库函数,而不用自己重新编写函数。今天就来看一下C语言标准库函数里面的整型函数。 int __cdecl abs(int ...
    99+
    2024-04-02
  • 数据类型是Go语言中的重要概念,你了解吗?
    作为一门现代化的编程语言,Go语言在设计之初就考虑到了数据类型的重要性。在Go语言中,数据类型是指变量可以存储的数据的类型。每个数据类型都有自己的特点和用途,掌握好数据类型可以让我们更好地编写高质量的代码。本文将为大家详细介绍Go语言中的...
    99+
    2023-08-05
    对象 接口 数据类型
  • C语言的基本编写规范你了解吗
    目录基本编写规范一、代码规范化的好处二、规范目的与基本规则1.目的2.基本原则1.空行2.空格3.成对书写(有些编译器会自动补括号)4.缩进(有些编译器会自动缩进)5.对齐(有些编译...
    99+
    2024-04-02
  • 了解Go语言中数组的概念
    数组概述 数组是Go语言中一种基本的数据类型,用于存储一组具有相同类型的数据元素。数组中的每个元素都有一个唯一的索引,可以通过索引来访问该元素。数组的长度是固定的,一旦创建就不能改变。 创建数组 可以使用以下...
    99+
    2024-01-31
    go数组理解 go数组功能 go数组特点 go语言
  • C语言时间函数的ctime()和gmtime()你了解吗
    目录ctime函数gmtime函数总结函数原型如下: __CRT_INLINE char *__cdecl ctime(const time_t *_Time); __CRT_I...
    99+
    2024-04-02
  • C语言与C++对比分析:你了解吗?
    c++++ 相较于 c 语言的优势在于:语法更灵活,支持面向对象编程,提供自动内存管理,拥有函数重载和模板等高级功能,提升代码可读性和可维护性。 C 语言与 C++ 对比分析:深入了解...
    99+
    2024-04-03
    c++ c语言 代码可读性
  • C++的多态与虚函数你了解吗
    目录多态性虚函数总结多态性 多态性是面向对象程序设计的关键技术之一,若程序设计语言不支持多态性,不能称为面向对象的语言,利用多态性技术,可以调用同一个函数名的函数,实现完全不同的功能...
    99+
    2024-04-02
  • Go语言中方法与函数的概念辨析
    Go语言中方法与函数的概念辨析 在Go语言中,方法(Method)和函数(Function)是两个不同的概念,虽然它们都可以实现相同的功能,但在使用和定义上有所不同。本文将从概念、特点...
    99+
    2024-04-02
  • C语言中的时间函数clock()和time()你都了解吗
    目录clock函数time函数总结时间函数在编写代码的时候会经常用到,下面就来总结一下clock和time函数的用法,函数原型如下: clock_t __cdecl clock(...
    99+
    2024-04-02
  • 一篇文章带你了解C语言浮点数之间的比较规则
    目录你认为这段代码输出什么?为什么不等于呢? 应该怎么解决?那么怎么判断两个浮点数 f1 和 f2 相等呢。 伪代码可以简化为 >>怎么判断浮点数等于0? 还有一个问题 ...
    99+
    2024-04-02
  • C语言中的柔性数组你了解吗
    目录1.什么是柔性数组2.柔性数组应该如何使用3.柔性数组的替代方案及内存分布对比4.柔性数组有哪些优点总结1.什么是柔性数组 柔性数组就是大小可以变化的数组。 注意跟C99中的变长...
    99+
    2023-05-15
    C语言柔性数组使用 C语言 柔性数组 C语言 数组
  • Go语言函数和指针的概念
    本篇内容主要讲解“Go语言函数和指针的概念”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Go语言函数和指针的概念”吧!函数函数就是一段基本的代码块,一般用来对需要重复执行的代码进行复用。在 go...
    99+
    2023-06-15
  • C语言的运算符你了解吗
    目录前言一、算数运算符(数学运算) + -* / %二、逻辑运算符(判断真假)|| &&> >= < <=!? : ...
    99+
    2024-04-02
  • C语言的结构体你了解吗
    目录结构体内存对齐结构体传参结构体实现位段什么是位段位段在内存中的存储位段的问题总结结构体内存对齐 当我们创建一个结构体变量时,内存就会开辟一块空间,那么在创建结构体变量时内存到底是...
    99+
    2024-04-02
  • C语言的模板与泛型编程你了解吗
    目录模板与泛型编程浅谈摘要(Effective C++):模板与泛型编程简单介绍函数模板模板编译类模板为什么我们需要模板特例化?总结模板与泛型编程浅谈 摘要(Effective C+...
    99+
    2024-04-02
  • C 语言的弱符号与弱引用你了解吗
    目录C语言中的__attribute__((weak)) 与 attribute ((weakref())弱符号弱符号的作用与示例弱引用测试代码1:测试代码2:总...
    99+
    2024-04-02
  • C语言二叉树与堆的概念与实现
    目录引言—树的故事树的基本性质和描述树的基本特点树的关键字解析树的表示方法二叉树的概念结构特殊二叉树二叉树的性质二叉树的存储结构二叉树与堆堆的实现堆排序堆的功能实现TOPK问题二叉树...
    99+
    2024-04-02
  • C++的内联函数你了解吗
    目录1.概念2.函数演示3.函数特性总结1.概念 以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数压栈的开销,内联函数提升程序运行的效率。...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作