函数小结

Archer- 2017-10-01 02:30:29
以下是我的一些心得体会,请大家一起补充,批评指正
真正成为一个引领初学者的笔记

一.函数
声明:
可以在程序头部声明、

#include <stdio.h>
#include <string.h>
int text(char* a)
{
;
}
int main()
{

return 0;
}

也可以这样
注意分号的位置。

#include <stdio.h>
#include <string.h>
int text(char* a); //注意这个分号,他区分了函数原型和函数的起始部分
int main()
{

return 0;
}
int text(char* a)
{
int fat = 1;
return fat;
}

无论哪一种声明,你必须要保证一点
在调用定义的函数之前你必须保证编译器提前知道函数原型
编译器见过原型后,就可以检查该函数的调用,确保参数,返回值无误
编译器会把不匹配的实参或返回值转化为正确的类型,(可能吧。。。。。)

补充 函数的缺省认定
当程序调用一个无法看到原型的函数时,编译器便认为该函数返回一个整数值
举一个简单的例子

#include <stdio.h>
#include <string.h>
int text(char* a);
main()
{
return 0;
}

这样编译照样通过,但是你会看到编译器开始抱怨了:
||=== Build: Debug in pant (compiler: GNU GCC Compiler) ===|
D:\Projects\pant\main.c|4|warning: return type defaults to 'int' [-Wreturn-type]|
||=== Build finished: 0 error(s), 1 warning(s) (0 minute(s), 3 second(s)) ===|
||=== Run: Debug in pant (compiler: GNU GCC Compiler) ===|
巧妙利用函数的缺省可以使代码变得简洁,但是千万不要挑战编译器的极限,有时候会很顽皮。。
函数的参数 (辨析“传值调用”“传址调用”)
首先,我们要明白函数的工作原理
当编译器读到函数原型时,便会给函数预留一个贮存空间,传入的变量会自动生成一份拷贝,作为函数的形参
你可以说C函数的所有参数均已“传值调用”
但是,如果被传递的是一个数组名呢?如果在函数中以下标访问呢?
那么在函数中对数组元素进行修改实际上是调用程序中的数组元素,数组中元素将被实际修改,这个行为我们称为 传址调用
其实这一点都不矛盾,数组名的值实际上就是一个指针(地址的变量),无论是硬件还是我们的编译器,他们都是根据地址来调用某个变量。下标引用或者是间接访问(*)在本质上都是一致的,都是以地址来访问变量。
所以,参数(指针)实际上就是一份地址拷贝,但在这个拷贝上访问的是原先的值
记住两个规则
1.传递给函数的标量参数是传值调用的,只会在函数定义下更改值,但初始值并未被修改
2.传递给函数的数组参数是传址调用的,会改变初始的值

举一个很经典的例子

void text(int a,int b) //两个整数未被交换
{
int temp;
temp = a;
a = b;
b = temp;
}


void text(int* a,int* b) //交换成功
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}

思考下面一个代码,两个整数交换成功,但是为什么说它有风险

void text(int* a,int* b)
{
int* temp;
temp = *a;
*a = *b;
*b = *temp;
}

想知道吗?
当你学到指针就明白了,哈哈
...全文
497 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
进阶的橘子 2017-11-20
  • 打赏
  • 举报
回复
小白提问 为什么呢?
大米粥哥哥 2017-10-01
  • 打赏
  • 举报
回复
Archer- 2017-10-01
  • 打赏
  • 举报
回复
最后一个代码中 把 temp = *a; 改为*temp = *a;

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧