1)函数的定义:
函数的作用域 函数的返回值 函数名( 形参类别及形参名列表 )
{
具体的功能实现
}
int func1( char a )
{ ...........
return -1;
}
func1的返回值是int 类型的,调用的时候需要给一个char类型的数
int func2( int x , int y )
{ ...........
return 2;
}
func2的返回值是int 类型的,调用的时候需要给2个int类型的数
int func3( void )
{ ...........
return 1;
}
func3的返回值是int 类型的,调用的时候不需要给参数
void func4( int a )
{ ...........
return ;
}
func4是没有返回值,调用的时候需要给1个int类型的数
2)函数的调用:
在某个函数中调用函数, 调用的时候需要注意函数的格式(返回值、参数)
func1( ‘a’ ) ; 如果在调用的时候觉得不需要使用函数的返回值, 可以不处理
i = func2( a , b ); 把a和b变量的值传递给函数,函数的返回值赋值给 i
int ret = func3( ); 函数不需要形参,直接使用函数的返回值
func4 ( 10 ); 直接给函数传递一个常量值10
练习: 定义一个函数, 可以返回3个参数中的最大值
编程验证效果
有返回值, 有3个参数
max_func.c:15:8: warning: implicit declaration of function ‘max_func’[-Wimplicit-function-declaration]
1: 因为函数没有事先声明
2: 定义和调用的函数名或者参数的个数不一致
3)函数的声明:
因为编译器是从上往下进行编译的, 当编译到某个没有实现定义的函数时候会给一个警告, 需要在.c文件的开头增加函数的声明
int max_func(int a, int b , int c); 声明和定义差不多,但是后面跟的是分号
也可以忽略参数名,只保留参数的类型
int max_func(int , int , int );
4)字符串函数的使用
字符串相关的函数声明基本都放在#include<string.h>,定义都在系统库文件中
函数是由“巨人”写好的~
这类函数不需要关心里面的实现, 但是得根据它的描述充分理解它的功能,并且调用
#include<string.h>
size_t strlen(const char *s);
给一个字符串名,返回数组的有效字符数,遇到’\0’就停止
int strcmp(const char *s1, const char *s2);
比较两个字符串,返回值为0表示字符串完全相同
int strncmp(const char *s1, const char *s2, size_t n);
比较两个字符串的指定长度,
返回值为0表示字符串指定长度完全相同
5)函数传参
int min_func( int a , int b) // 函数的形参a、b
在调用的时候,等价于a和b被赋值了
{
return (a>b ? b : a );
}
int main ( void )
{
int x = 100; ----- 实参
int y = 200; ----- 实参
int min ;
min = min_func ( x , y);
-----在函数调用的时候用实际值的参数给函数的形参赋值
printf(“min = %d \n”, min );
}
在用数组做为形参的时候需要注意:
数组名作为形参可以有以下形式
void func( char arr[ 256 ] )
void func( char arr[ ] ) 函数的形参都只表示某数组的首元素地址
int main(void)
{
charch[256];
func( ch ); // 数组名通常表示首元素的地址,只有sizeof(ch)和&ch例外
}
void upper_case(charstr[ ] )
upper_case.c:6:39: warning: ‘sizeof’ on arrayfunction parameter ‘str’ will return size of ‘char *’ [-Wsizeof-array-argument]
printf("sizeof(str) = %ld \n", sizeof(str));
sizeof计算的是在函数形参中的额数组名, 实际计算的是sizeof(char *)
也就是char类型数据的地址(64位机中地址是用64位(8B)来表示的)\
upper _case中的形参str, 虽然定义的时候写成数组的形式, 但是sizeof只会把它当做是同类型的地址。sizeof(str )得到的是在不同系统中的地址字节数, 32位机所有的地址值都用 32位(4B)表示, 64位机用64位(8B来表示一个地址值)因为数组传参一般使用数组名来传递参数,数组名仅表示首元素的地址,所以不能直接用形参名来计算数组的长度,
通常要在函数中直到数组元素个数的时候,只能通过另一个形参来传递
upper_case(char str[ ] , int length )
对应字符数组的操作, 可以有另一个处理方法:
void upper_case(char str[ ] ) // 虽然定义成数组形式,但是本质还是个指针
{
int i ;
printf("sizeof(str) = %ld\n", sizeof(str)); // 最关键的是和sizeof结合的时候
得到的是指针大小(64位机 8Bytes)
printf("sizeof(str[0]) = %ld\n", sizeof(str[0])); // 对象依旧是char , 大小为1
// for(i=0;i<sizeof(str)/sizeof(str[0]); i++) NG sizeof(str)/sizeof(str[0]恒为8
for(i=0; str[i] != ‘\0’; i++)// 根据字符串尾来处理
{
if(str[i] >='a' &&str[i] <= 'z')
str[i] -= ('a'- 'A');//97 - 65
}
printf("str : %s \n", str);
}
函数:
定义---- 返回值类型 函数名 ( 形参类型 形参名列表)
int func ( short a , int x )
{
实现内容
}
调用----
被调用函数中需要使用怎么样的参数,该被调用函数会返回怎样的信息给我们
1: 参数可以是调用函数中的变量、全局变量、常量,使用这些值给被调用函数中的形参直接赋值
main()
{
func( 100 , 200 ) ;// 形参a等价于100, b等价于200
}
2: 这被调用函数的返回值,有没有什么作用
函数的返回值通常根据需要来处理
通常返回的是数值就要处理,
如果返回的是处理过程的的状态就可以根据需要处理~
声明 : 仅仅是告诉编译器要调用的函数的返回值类型和形参类型
int func( short , int );