C语言入门学习(第二十二天——函数)
2021-06-09 06:03
标签:swa 空间 交换变量 程序员 根据 防止 全局变量 定义函数 target Pixiv:よはく 当程序规模不断扩大时,主函数会变得冗杂、复杂、难阅读、关联度过高、难修改等问题,这时候引入【函数】来分解程序,提高可读性、效率是非常有必要的。 其他程序员在使用你的函数时只需要了解作用、参数、返回即可。 编译会从上往下编译,而如果你调用的语句在上面定义函数在下面,则会报错。于是你需要提前声明函数防止报错,告诉编译器“确实有这个函数,只是你还没看到。” 一般声明语句会写在最上面 extern关键字用于声明全局变量 和声明函数类似,防止报错 变量被定义到不同位置时,所作用的范围称为作用域。 一个代码块{}中定义的变量只能在这代码块中使用 作用域不同的变量允许名字一致 作用域在调用同名变量时会优先考虑这个代码块所在的变量 比如 在代码块之外的变量、数组、函数等能在这整个文件中使用,则称为具有文件作用域 具有文件作用域的称为全局变量 注:应尽量避免使用全局变量以节省内存、防止污染命名空间、降低程序耦合性。一个好的程序应该要高内聚、低耦合 声明函数中对于声明的参数的作用域仅限这一行代码。 所以声明时可以不写参数名,参数名也可以不同于原型的参数名 【没什么用】 函数在调用时会产生的作用域,goto语句的标签会被限制在函数内,当函数调用完成后会销毁这个作用域 定义是指为某一个对象分配存储空间 声明是指向编译器表明存在这个变量 函数由参数、返回值、函数体构成 以交换变量的函数为例 由上面的结果来看,是不符合我们的预期的。 原因在于我们函数内的变量是局部变量无法改变值,需要引入指针或全局变量来达到预期目的 现在再来改一下代码 数组在函数中传递的是首元素的指针,所以即使在函数内改变数组的值,也会改变main中数组的值 数组只有第一维可以省略数量 函数返回类型为指针的函数称为指针函数 和之前的知识多少有些重复,比较简单,但需要注意一个点! 根据作用域我们可以得知,定义指针的变量是一个在函数作用域内的变量。 当你返回指针后这个变量也同时被销毁,而返回到的指针因为原本指向的内容也被销毁自然会有八嘎(bug) 以下这段代码明显会出错 (编译器只会警告,不确定你是要这个指针的返回值还是所指向的内容) 这是不是感觉和数组指针很像呢?本质上就是优先级的不同而导致的不同的结果。 那么函数指针有什么作用呢? 函数在定义后会存在一个地址,这个地址称为【入口地址】,而这个地址的值就是函数名。 现在你多了一种方式去调用函数 return关键字用来返回函数的值并结束本次函数的调用 只能返回一个值 现在可以使用函数去简化main函数,参数可以用变量、指针、数组,返回值可以是变量、常量、指针,调用方式也可以使用指针来调用. 另外可以看看stdarg.h 还可以看看如何用函数传递函数 这个模块能较弱地实现一个函数带可变数量的参数 C语言入门学习(第二十二天——函数) 标签:swa 空间 交换变量 程序员 根据 防止 全局变量 定义函数 target 原文地址:https://www.cnblogs.com/AlienfronNova/p/14454208.html镇楼图
============
〇、引入函数的原因
============
一、函数
①声明函数
(参数列表)
//若不存在返回值,参数最好写void
//声明函数可以只写类型
void test();
int main(){
test();
}
void test(){
printf("HelloWorld");
}
②定义函数
(参数列表){
}
③调用函数
根据你写的函数按照定义来调用
//声明函数
void print_C();
//定义函数
void print_C(){
printf(" ###### \n");
printf("## ##\n");
printf("## \n");
printf("## \n");
printf("## \n");
printf("## ##\n");
printf(" ###### \n");
}
int main()
{
//调用函数
print_C();
return 0;
}
============
二、extern关键字
int main(){
extern int a;
printf("%d\n\a",a);
}
int a = 3;
============
三、作用域
①代码块作用域block scope
/*
for、if、switch、函数中定义的变量
也不可在这些代码块以外使用
*/
int main(){
int a = 2;
{
{
int a = 52;
printf("%d\n",a);
}
printf("%d\n",a);
int a = 3;
{
int a=1;
printf("%d\n",a);
}
printf("%d\n",a);
}
printf("%d\n",a);
}
②文件作用域
③原型作用域
void f(int,int diff);
void f(int a,int b){
//...
}
④函数作用域
============
四、定义与声明
定义:
声明:
定义也可以当作是声明
相同名字只能定义一次,而可以声明多次
============
五、指针参数
void swap(int,int);
void swap(int x,int y){
int t;
printf("In swap,互换前:x = %d,y = %d\n",x,y);
t = x;
x = y;
y = t;
printf("In swap,互换后:x = %d,y = %d\n",x,y);
}
int main(){
int x = 3,y = 5;
printf("In main,互换后:x = %d,y = %d\n",x,y);
swap(x,y);
printf("In main,互换后:x = %d,y = %d\n",x,y);
}
void swap(int*,int*);
void swap(int *x,int *y){
int t;
printf("In swap,互换前:x = %d,y = %d\n",*x,*y);
t = *x;
*x = *y;
*y = t;
printf("In swap,互换后:x = %d,y = %d\n",*x,*y);
}
int main(){
int x = 3,y = 5;
printf("In main,互换后:x = %d,y = %d\n",x,y);
swap(&x,&y);
printf("In main,互换后:x = %d,y = %d\n",x,y);
}
============
六、传递数组
void get_array(int a[5]);
void get_array(int a[]){
int i;
a[3] = 520;
for (i = 0;i
===========
七、指针函数
char *cstrcat(char*,const char*);
char *cstrcat(char* a,const char* b){
char* r = strcat(a,b);
return r;
}
int main(){
char a[30] = "123456",b[] = "abcdef";
cstrcat(a,b);
printf("%s",a);
return 0;
}
不要返回局部变量的指针
char *cstrcat(void);
char *cstrcat(void){
char str[10] = "ABCDEFG";
return str;
}
int main(){
printf("%s",cstrcat());
return 0;
}
============
八、函数指针
int (*p)(int,int)
int square(int);
int square(int num){
return num*num;
}
int main(){
int num;
scanf("%d",&num);
int (*p)(int) = square;
printf("%d",(*p)(num));
}
============
九、return
============
总结
参考资料
https://fishc.com.cn
http://www.cplusplus.com/reference
https://www.icourse163.org/course/ZJU-200001
http://c.biancheng.net/