C语言计算阶乘的和、函数声明和定义

一. 计算1!-2!+3!-4!+5!-6!+7!-8!+9!-10!并输出计算结果

#include "stdio.h"
double fun(int n)
{
    double sum = 1.0;
    int i;
    for (i = 1; i <= n; i++)
        sum *= i;
    return sum;
}
int main()
{
    int i, mark = 1;
    double sum = 0, item = 0;
    for (i = 1; i <= 10; i++)
    {
        item = mark * fun(i);
        sum += item;
        mark = -mark;
    }
    printf("1!-2!+3!-4!+5!-6!+7!-8!+9!-10!=%.0lf\n", sum);
}

运行结果为:1!-2!+3!-4!+5!-6!+7!-8!+9!-10!=-3301819

二.函数的声明和定义

1) 只要你在main函数前面声明过一个函数,main函数就知道这个函数的存在,就可以调用这个函数。而且只要知道函数名、函数的返回值、函数接收多少个参数、每个参数是什么类型的,就能够调用这个函数了,因此,声明函数的时候可以省略参数名称。

2) 格式:返回值类型    函数名(参数1,参数2,参数3,.....,参数n)

例如:int  sum(int,int);

3)如果只有函数的声明,而没有函数的定义,那么程序将会在链接时出错。

4)如果想把函数的定义写在main函数后面,而且main函数能正常调用这些函数,那就必须在main函数的前面进行函数的声明。

1 // 只是做个函数声明,并不用实现
 2 int sum(int a, int b);
 3 
 4 int main()
 5 {
 6     int c = sum(1, 4);
 7     return 0;
 8 }
 9 
10 // 函数的定义(实现)
11 int sum(int a, int b) {
12     return a + b;
13 }


在第11行定义了sum函数,在第2行对sum函数进行了声明,然后在第6行(main函数中)就可以正常调用sum函数了。

三. #include <>和#include ""的区别

二者的区别在于:当被include的文件路径不是绝对路径的时候,有不同的搜索顺序。

1)对于使用双引号""来include文件,搜索的时候按以下顺序:

先在这条include指令的父文件所在文件夹内搜索,所谓的父文件就是这条include指令所在的文件
如果上一步找不到,则在父文件的父文件所在文件夹内搜索;
如果上一步找不到,则在编译器设置的include路径内搜索;
如果上一步找不到,则在系统的INCLUDE环境变量内搜索。

2)对于使用尖括号<>来include文件,搜索的时候按以下顺序:

在编译器设置的include路径内搜索;
如果上一步找不到,则在系统的INCLUDE环境变量内搜索。

四. .h,.c,.o指的意思

1)stdio.h 是C语言函数库中的一个头文件,里面声明了一些常用的输入输出函数。

注意:stdio.h里面只有printf函数的声明。

2).c是源文件里面会生成.o文件。

五.形式参数和实际参数

1)形式参数:形参出现在被调函数当中,在整个函数体内都可以使用。形参在定义时编译系统并不分配存储空间,只有在调用该函数时才分配内存单元。调用结束内存单元被释放,故形参只有在函数调用时有效,调用结束时不能再使用。

2)实际参数:实参出现在主调函数当中,当函数调用时,主调函数把实参的值传送给被调函数的形参,从而实现函数间的数据传递。传递方式有两种:值传递和地址传递方式。

六.变量作为函数参数
当形参定义为变量时,实参可以是常量、变量和表达式,这种函数间的参数传递为值传递方式。值传递的特点是参数的“单向传递”;

int swap(int a,int b)
{
   int temp;
   temp=a;
   a=b;
   b=temp;
   return 0;
}  
int main (void){
        int a=3,b=4;
        swap(a,b);
    }


由于是值传递,单向传递,并不会改变a,b的值。
七.数组作为函数参数
1)数组元素作为函数参数
数组元素又称为下标变量,它具有普通变量的一切性质,因此数组元素作为函数的实参进行数据传递是与普通变量没有任何区别,也是值传递

int swap(int a,int b)
{
   int temp;
   temp=a;
   a=b;
   b=temp;
   return 0;
}  
int main (void){
        int a[]={3,4};
        swap(a[0],b[0]);
    }

同样是值传递并不会改变a[0]的值。
2)一维数组名作为函数参数
数组名是一个地址,是数组的首地址,因此用数组名作为函数的参数进行数据传递时,执行的是地址传递方式。所谓地址传递,顾名思义实参传递的不是数据本身,而是数据存在的地址。函数调用时,把数组名即数组的首地址作为实参传递给形参(必须是可接受地址的数组名或者指针变量),形参数组名取得首地址后就有了实在的数组,这时实质上实参和形参是同一个数组,指向同一段存储空间,实参的改变就是对形参的改变,所以传址方式可看成是数据进行了“双向传递”。
3)数组指针,即数组元素的地址作为函数参数
由于数组元素的地址的本质仍然为地址,所以属于地址传递方式。

int swap(int *a,int *b)
{
   int temp;
   temp=*a;
   *a=*b;
   *b=temp;
   return 0;
}  
int main (void){
        int arr[] = {1,2};
        int *a = &arr[0];
            int *b = &arr[1];
            swap(a,b);
    }

重点:
数组元素(下标变量)作为函数的参数进行的数据传递是值传递方式,数组名(数组首地址)、数组元素的地址(&arr[0])作为函数参数进行的数据传递是地址传递方式。
实参为数组名是,形参接收时可以有三种形式:带下标的数组名(arr[0])。不带下标的数组名(arr)、可接收地址值的指针变量名(*a)。由于是参数组和形参数组都指向同一段内存单元,故它们操作的是同一批数据,所以形参的改变就是改变了实参中的数据。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值