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) {
// ...
}
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()函数用来终止整个程序的运行。一旦执行到该函数,程序就会立即结束。该函数的原型定义在头文件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 int foo(int arg1, char arg2);
int main(void) {
int a = foo(2, 3);
// ...
return 0;
}
由于函数原型默认就是extern,所以可以不加extern。
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说明符,表示函数内部不得修改该参数变量。
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后面的参数统一放入ap,va_arg(ap, double)用来从ap依次取出一个参数,并且指定该参数为 double 类型,va_end(ap)用来清理可变参数对象。
参考: C 语言教程
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
几个月前,我读了一篇关于rubygem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:
如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只
?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------
嗨~大家好,这里是可莉!今天给大家带来的是7个C语言的经典基础代码~那一起往下看下去把【程序一】打印100到200之间的素数#includeintmain(){ inti; for(i=100;i 【程序二】输出乘法口诀表#includeintmain(){inti;for(i=1;i 【程序三】判断1000年---2000年之间的闰年#includeintmain(){intyear;for(year=1000;year 【程序四】给定两个整形变量的值,将两个值的内容进行交换。这里提供两种方法来进行交换,第一种为创建临时变量来进行交换,第二种是不创建临时变量而直接进行交换。1.创建临时变量来
说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时
我需要一个通过输入字符串进行计算的方法,像这样function="(a/b)*100"a=25b=50function.something>>50有什么方法吗? 最佳答案 您可以使用instance_eval:function="(a/b)*100"a=25.0b=50instance_evalfunction#=>50.0请注意,使用eval本质上是不安全的,尤其是当您使用外部输入时,因为它可能包含注入(inject)的恶意代码。另请注意,a设置为25.0而不是25,因为如果它是整数a/b将导致0(整数)。