ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

C 语言函数

2022-07-01 01:00:33  阅读:110  来源: 互联网

标签:函数 int void static 参数 main 语言


函数声明

int plus_one(int n) {
  return n + 1;
}

函数声明的语法有以下几点,需要注意。

  • 返回值类型

函数声明时,首先需要给出返回值的类型,上例是int,表示函数plus_one()返回一个整数。

  • 参数

函数名后面的圆括号里面,需要声明参数的类型和参数名,plus_one(int n)表示这个函数有一个整数参数n

  • 函数体

函数体要写在大括号里面,后面(即大括号外面)不需要加分号。大括号的起始位置,可以跟函数名在同一行,也可以另起一行。

  • return语句

return语句给出函数的返回值,程序运行到这一行,就会跳出函数体,结束函数的调用。如果函数没有返回值,可以省略return语句,或者写成return;

函数调用

调用函数时,在函数名后面加上圆括号就可以了,实际的参数放在圆括号里面。

int a = plus_one(13);
// a 等于 14

函数调用时,参数个数必须与定义里面的参数个数一致,参数过多或过少都会报错。

函数必须先声明后使用,否则会报错。C 语言标准规定,函数只能声明在源码文件的顶层,不能声明在其他函数内部。

不返回值的函数,使用void关键字表示返回值的类型。没有参数的函数,声明时要用void关键字表示参数类型。

void myFunc(void) {
  // ...
}

main() 方法

C 语言规定,main()是程序的入口函数。程序总是从这个函数开始执行,如果没有该函数,程序就无法启动。

int main(void) {
  printf("Hello World\n");
  return 0;
}

C 语言约定,返回值0表示函数运行成功,如果返回其他非零整数,就表示运行失败,代码出了问题。

如果main()里面省略return 0这一行,编译器会自动加上,即main()的默认返回值为0。

参数的传值引用

如果函数的参数是一个变量,那么调用时,传入的是这个变量的值的拷贝,而不是变量本身。

void increment(int a) {
  a++;
}

int i = 10;
increment(i);

printf("%d\n", i); // 10

如果想要传入变量本身,只能传入变量的地址。

void Swap(int* x, int* y) {
  int temp;
  temp = *x;
  *x = *y;
  *y = temp;
}

int a = 1;
int b = 2;
Swap(&a, &b);

函数不要返回内部变量的指针,因为当函数结束运行时,内部变量就消失了,这时指向内部变量的内存地址是无效的。

函数指针

函数本身就是一段内存里面的代码,C 语言允许通过指针获取函数。

void print(int a) {
  printf("%d\n", a);
}

void (*print_ptr)(int) = &print;

通过函数指针也可以调用函数。

(*print_ptr)(10);
// 等同于
print(10);

C 语言还规定,函数名本身就是指向函数代码的指针,通过函数名就能获取函数地址。

if (print == &print) // true

五种调用函数的写法。

// 写法一
print(10)

// 写法二
(*print)(10)

// 写法三
(&print)(10)

// 写法四
(*print_ptr)(10)

// 写法五
print_ptr(10)

函数原型

函数必须先声明,后使用,而main()函数是入口函数,因此,其他函数必须在main()函数之前声明,否则编译时会产生警告。

但是,main()是整个程序的入口,也是主要逻辑,放在最前面比较好。另一方面,对于函数较多的程序,保证每个函数的顺序正确,会变得很麻烦。

C 语言提供的解决方法是,只要在程序开头处给出函数原型,函数就可以先使用、后声明。

所谓函数原型,就是提前告诉编译器,每个函数的返回类型和参数类型。

int twice(int);

int main(int num) {
  return twice(num);
}

int twice(int num) {
  return 2 * num;
}

exit()

exit()函数用来终止整个程序的运行。一旦执行到该函数,程序就会立即结束。该函数的原型定义在头文件stdlib.h里面。

exit()可以向程序外部返回一个值,它的参数就是程序的返回值。

一般来说,使用两个常量作为它的参数:EXIT_SUCCESS(相当于 0)表示程序运行成功,EXIT_FAILURE(相当于 1)表示程序异常中止。

main()函数里面,exit()等价于使用return语句。

C 语言还提供了一个atexit()函数,用来登记exit()执行时额外执行的函数,用来做一些退出程序时的收尾工作,该函数的原型也是定义在头文件stdlib.h

int atexit(void (*func)(void));

atexit()的参数是一个函数指针。注意,它的参数函数不能接受参数,也不能有返回值。

exit()执行时会先自动调用atexit()注册的函数,然后再终止程序。

函数说明符

extern 说明符

对于多文件的项目,源码文件会用到其他文件声明的函数。这时,当前文件里面需要给出外部函数的原型,并用extern说明该函数的定义来自其他文件。

extern int foo(int arg1, char arg2);

int main(void) {
  int a = foo(2, 3);
  // ...
  return 0;
}

由于函数原型默认就是extern,所以可以不加extern

static 说明符

static用于函数内部声明变量时,表示该变量只需要初始化一次,不需要在每次调用时都进行初始化。也就是说,它的值在两次调用之间保持不变。

#include <stdio.h>

void counter(void) {
  static int count = 1;  // 只初始化一次
  printf("%d\n", count);
  count++;
}

int main(void) {
  counter();  // 1
  counter();  // 2
  counter();  // 3
}

注意,static修饰的变量初始化时,只能赋值为常量,不能赋值为变量。

int i = 3;
static int j = i; // 错误

在块作用域中,static声明的变量有默认值0

static int foo;
// 等同于
static int foo = 0;

static可以用来修饰函数本身,表示该函数只能在当前文件里使用。

static int Twice(int num) {
  int result = num * 2;
  return(result);
}

static也可以用在参数里面,修饰参数数组。

int sum_array(int a[static 3], int n) {
  // ...
}

上面示例中,static对程序行为不会有任何影响,只是用来告诉编译器,该数组长度至少为3,某些情况下可以加快程序运行速度。

另外,需要注意的是,对于多维数组的参数,static仅可用于第一维的说明。

const 说明符

函数参数里面的const说明符,表示函数内部不得修改该参数变量。

void f(const int* p) {
  *p = 0; // 该行报错
}

上面这种写法,只限制修改p所指向的值,而p本身的地址是可以修改的。

void f(const int* p) {
  int x = 13;
  p = &x; // 允许修改
}

如果想限制修改p 所指向的值,可以把const放在p前面。

void f(int* const p) {
  int x = 13;
  p = &x; // 该行报错
}

如果想同时限制修改p*p,需要使用两个const

void f(const int* const p) {
  // ...
}

可变参数

有些函数的参数数量是不确定的,声明函数的时候,可以使用省略号...表示可变数量的参数。

int printf(const char* format, ...);

...符号必须放在参数序列的结尾,否则会报错。

头文件stdarg.h定义了一些宏,可以操作可变参数:

(1)va_list:一个数据类型,用来定义一个可变参数对象。它必须在操作可变参数时,首先使用。

(2)va_start:一个函数,用来初始化可变参数对象。它接受两个参数,第一个参数是可变参数对象,第二个参数是原始函数里面,可变参数之前的那个参数,用来为可变参数定位。

(3)va_arg:一个函数,用来取出当前那个可变参数,每次调用后,内部指针就会指向下一个可变参数。它接受两个参数,第一个是可变参数对象,第二个是当前可变参数的类型。

(4)va_end:一个函数,用来清理可变参数对象。

double average(int i, ...) {
  double total = 0;
  va_list ap;
  va_start(ap, i);
  for (int j = 1; j <= i; ++j) {
    total += va_arg(ap, double);
  }
  va_end(ap);
  return total / i;
}

上面示例中,va_list ap定义ap为可变参数对象,va_start(ap, i)将参数i后面的参数统一放入apva_arg(ap, double)用来从ap依次取出一个参数,并且指定该参数为 double 类型,va_end(ap)用来清理可变参数对象。

参考: C 语言教程

标签:函数,int,void,static,参数,main,语言
来源: https://www.cnblogs.com/knhap/p/16433167.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有