×
嵌入式 > 嵌入式开发 > 详情

《C与指针》读书笔记三

发布时间:2020-06-19 发布时间:
|

函数是各种编程语言中都有的概念。早2000年之前,好些大学的教学课程是PASCAL。 从概念上来说函数的概念没有发生任何变化。函数一般是处理数据的工具,可以进行模块性开发。有点像机械**中各个零件。将各个零件组装起来就成为系统工具。也就是软件也可以采用工程管理方法来进行生产,代码重用性也得到了增强,比如我从来没有编写过冒泡的排序,只是简单的使用。

从返回值来划分函数分为有返回值和没有返回值。从参数的角度划分可以分为有参数和无参数。在使用函数的过程中我从来没有认真的考虑参数的具体含义。如果静下心来仔细考虑有觉得没有什么深刻的意义。有一本书上介绍,参数就是函数接口。就像机械的接口,比如一台电动机经过变速调整后流出的接口就是一个齿轮或者飞轮一样。使用者可以根据齿轮或者飞轮的继续设计传动机械。而不必在考虑动力来源。

但是参数到底是什么?这个问题我一直没有考虑透彻过。在《C指针》中有一段简单的描述,简单到作者根本没有任何前后文铺垫。作者肯定是对参数的实质了然于胸。所以可以很平淡的叙述出参数的实质。仅仅四个字“传值调用”。这段话出现在122页,

仔细斟酌原文的每一句话。对理解函数、参数以C语言的调用原理甚至指针的概念非常有用。所有的参数都是传值调用,也就对原值“复制”。既然是复制那么就对原值不会进行人和操作。任何概念都不是孤立的,如果结合变量的作用域来理解“复制”就非常容易理解。如果再加入计算机内存模型的概念。理解“传值调用”就更加简单。因为一个变量有两个属性----地址和值。既然传值那么对原来地址就没有任何影响。可以简单图解。

void main( )

{

int x, y;

x = 10;

y = 20;

….. …..

}

前三条语句我们声明了两个变量---x、y,并且给两个变量都赋值---10 、20。这当然是文本的字面表达的意义。如果我们列出一个内存模型来理解这三条语句,也就是从计算机的角度来理解能得到什么概念。可以图解一下。

在计算机角度也该是划分两个地址空间0x100 00、0x100 01,并且在这个地址空间分别插入10、20的值。如果设计一个函数来修改x、y的值,其实就是对地址空间0x100 00、0x100 01的内容进行修改。

我们设计一个函数,对x、y的的值进行乘方,代码如下:

int power( int dat)

{

return dat *dat;

}

x = power( x );

y = power( y );

完整代码如下:

int power( int dat)

{

return dat *dat;

}

void main( )

{

int x, y;

x = 10;

y = 20;

x = power( x );

y = power( y );

….. …..

}

从文本角度理解,非常简单,就是通过power函数计算出某个数的平方。通过参数dat接收了x和y的值。平方后返回,通过x、y接收了返回值。如果不采用x、y接收x、y的值就不会受到影响。比如主函数代码如下:

void main( )

{

int x, y;

x = 10;

y = 20;

power( x );

power( y );

….. …..

}

图解原理也非常简单。

power( x ); 是将x变量(地址:0x100 00)值传给了dat。在执行power( x );结束时,函数表达式返回的值为100. power( y );同理。

在int power( int dat)函数运行过程中是对dat数据(地址:0x200 00)进行处理,不会影响main函数的变量x、y的值。当power函数结束后会释放对地址0x200 00的控制,将他交给系统。系统可以继续将他分配给其他变量使用。

int power( int dat) 是由返回的函数,如果采用无返回的函数,也可以实现乘方并且将乘方的结果存入x、y。代码如下:

void power( int *dat )

{

int temp = *dat;

*dat = temp * temp;

}

void main( )

{

int x, y;

x = 10;

y = 20;

power( &x );

power( &y );

….. …..

}

power( &x ); 接收的也是值,不过不是x的值10,而是x的地址,即0x100 00。 通过对 x地址的来操作x的值。这就解决的变量的作用域问题。power( int *dat )

不能超过自己作用域去访问上级调用函数的变量。但是可以通过地址来访问到上级函数的变量。如果仔细分析该函数。我们其实可以对指针理解更深一步。

void power( int *dat )

{

int temp = *dat;

*dat = temp * temp;

}

power( &x );其实等价于power( 0x100 00 );那么temp = *dat;其实就等价于temp = *((int *)0x100 00), (int *)是整型指针,地址为0x100 00。*((int *)0x100 00)是指向0x100 00地址的解引用,返回的值为10.temp接收了该值。 *dat = temp * temp;等价于*((int *)0x100 00) = 10*10。即在0x100 00地址存入100的值。



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
RIOS实验室联手Imagination.共同助力RISC-V生态发展