c语言函数输入输出参数,C语言函数输入/输出【IN/OUT】参数讲解

数据结构是编程的核心,还是算法是编程的核心,这一直是一个争论的话题。正因为如此,说明了数据结构与算法在编程领域的核心地位。------程序员

苏格拉没有底与糕点

苏格拉没有底是一个伟大的哲学家,他很喜欢吃一家店的现做的糕点,但是他每天都忙与奔波,所以不能每天都吃到糕点。一天,他突然想到一个好办法。他每天路过糕点店的时候,会把糕点钱和一张写有地址的纸条留给糕点店,糕点店做好蛋糕之后就会把蛋糕放到纸条上的指定地点去,然后苏格拉没有底就可以在这个指定地点找到自己想吃的蛋糕啦,好开心~

好了,输入输出参数讲解完啦。。。

糕点店其实就是一个函数(因为它实现了制作糕点的功能),苏格拉没有底把两类东西给了它,一类是糕点钱,它用作输入目的,因为钱是用来买制作糕点用的材料的;另一类是写有地址的小纸条,它用作输出目的,因为它指定了糕点完成之后糕点的交货地点,哈哈;

最后再来说一下,既然输出参数是个地址,那它一定是个指针啦,而这个指针指向的地址最终会存放函数的运算结果~

通过实际的例子形象的描述清除了问题的解决方案。正如哲学家就餐问题,说明了线程,互斥  一样。但是更深的细节还需要我们去挖掘和体会。

C语言深度学习---输入型参数和输出型参数

1、函数为什么需要形参和返回值

(1)函数名是一个符号表示整个函数代码段的首地址, 实质是一个指针的常量,指针常量指向这个函数用到的函数名都是当地           址用的,用来调用这个函数的。

(2)函数体是函数的关键,由一对{}括起来,包含很多句代码。函数体就是函数实际上做的工作。

(3)形参的列表和返回值 形参是函数的输入部分,返回值是函数的输出部分,对函数最好的理解就是把函数理解成一个加工的          机器。  把数据进行加工,得到输出值。 程序其实就是数据的加工器。  那么我们形参的列表就是这个机器的原材料的输入          端,而返回值就是机器的成品输出端。

(4)其实如果没有形参列表,函数也能对数据进行加工,用全局变量就可以了。

在嵌入式里面,除了你的产品占用的结构体,其它地方最好不要用到全局变量。

因为全局变量是非常的耗费内存的,所以我们要总是使用局部的变量。

两种方法都有自己的优点和缺点:

A:  函数参数传参用的比较多,因为这样可以实现模块化的编程,而C语言也是尽量减少使用全局变量。

B:Linux内核在早期审查的不是十分的严格,所以出现了很多全局变量。使用的函数

C:全局变量的传参是十分快的,参数很多情况下面对它进行打包成一个结构体。省略了函数传参的开销,所以效率要高一些,但是实战中用的最多的还是传参,如果参数很多传参的开销非常大的,通常的做法是把很多参数打包成一个结构体,然后传结构体变量的指针进去。

2、函数传参的使用const指针

(1)const一般是在函数的参数的列表当中的,用法是const int *P意义是指针变量P本身是可变的,而P指向的变量是不可变的。

(2)char *pstr = “Linux”;   //存放在代码段的

char pstr[] = "linux" ;     //因为数组是存放在数据段的

(3)const用来修饰指针做函数的参数,作用就是在于函数内部不会改变这个指针所指向的内容,所以给该函数传一个不可改变的指针(char *p ="linux")不会触发错误,而是一个未声明为const指针的函数。总之:你看到const参数,他已经默认叫你不要去随便的修改。

(4)函数需要向外部返回多个值的时候该怎么办?

PS:一开始我的想法是那你不会弄一个结构体传出去啊?其实传出去的就是结构体的指针,所以你的输出型参数在多个时候

就是要用指针传递

(1)一般来说,函数的输入部分就是函数的参数,输出部分就是返回值,估计很多C语言初学者也会这么认为的。

(2)问题是如果函数的参数可以有很多个,而返回值只能有一个,这就会让我们无法让一个函数返回多个值。

(3)现实编程中,一个函数需要返回多个值是非常普遍的,通常的做法是用参数来返回。

在典型的Linux返回值是不用来返回结果的,返回值的作用是用来返回0或者一个负数,用来表示程序执行的结果是对还是错的。

(4)普遍的做法,编程中函数的输入和输出都是靠函数的参数的,返回值只是用来表示函数的执行结果是对的还是错。

(5)如果这个函数是用来做输入的,也叫做输入型参数,用来做输出的就叫做输出型参数。输出型参数就是让函数把函数内部把数据输出到函数的外部的。

#include Int multip5_3(int a,int *p);

int main(void)

{

Int a,b,ret = -1;

a= 3;

Mutip5_3(a,&b);

}

Int multip5_3(    int a  ,  int *p   )

{

*p = 5 * a;

Return 0;

}

总结:

(1)看到一个函数的原型的时候,怎么样看出来哪个参数做输入或者输出型的参数。

只能传进去的指针,才能是输出型参数。

(2)函数传参如果传的是普通的变量的话,肯定是输入型的参数。如果传递指针的话那么就有可能是输入也有可能是输出型的参数。

(3)为了区别,经常的做法是,如果这个参数是做输入的,(通常做输入的在函数内部只需要读取这个参数,而不会需要更改          它)就在指针前面加const来修饰。如果函数形参是指针变量并且还没有加const,那么就表示这个参数是用来做输出型数。

(4)别人在调用你写的函数的时候或者你读别人的函数的时候,有很多隐含的意义。

举例子:

1.比如我们C库函数中,char * strcpy(char *dest,const char *src);

Src 是只读的,不需要改写的,  dest就是一个输出型的参数的实例。

2.比如以下代码:

void LoRaMacPayloadEncrypt(

const uint8_t*buffer,             //指针做输入(指向的内容不可以修改)

uint16_t   size,                         //普通输入

const uint8_t   *key,                 //指针做输入(指向的内容不可以修改)

uint32_taddress,                   //普通输入

uint8_t   dir,                              //普通输入

uint32_t   sequenceCounter,    //普通输入

uint8_t *encBuffer )                 //指针做输出(没有const进行修饰)

{

uint16_t i;

uint8_t bufferIndex = 0;

uint16_t ctr = 1;

memset1( AesContext.ksch, '\0', 240 );

aes_set_key( key, 16, &AesContext );

aBlock[5] = dir;

aBlock[6] = ( address ) & 0xFF;

aBlock[7] = ( address >> 8 ) & 0xFF;

aBlock[8] = ( address >> 16 ) & 0xFF;

aBlock[9] = ( address >> 24 ) & 0xFF;

aBlock[10] = ( sequenceCounter ) & 0xFF;

aBlock[11] = ( sequenceCounter >> 8 ) & 0xFF;

aBlock[12] = ( sequenceCounter >> 16 ) & 0xFF;

aBlock[13] = ( sequenceCounter >> 24 ) & 0xFF;

while( size >= 16 )

{

aBlock[15] = ( ( ctr ) & 0xFF );

ctr++;

aes_encrypt( aBlock, sBlock, &AesContext );

for( i = 0; i < 16; i++ )

{

encBuffer[bufferIndex + i] =buffer[bufferIndex + i] ^ sBlock[i];

}

size -= 16;

bufferIndex += 16;

}

if( size > 0 )

{

aBlock[15] = ( ( ctr ) & 0xFF );

aes_encrypt( aBlock, sBlock, &AesContext );

for( i = 0; i < size; i++ )

{

encBuffer[bufferIndex + i] = buffer[bufferIndex + i] ^ sBlock[i];

}

}

}

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值