函数参数的传递方式
基本介绍
C语言传递参数可以是值传递((pass by value),也可以传递指针(a pointer passed by value)也叫传递地址或者引用传递。
两种传递方式
(1)值传递
(2)引用传递(传递指针、地址)
其实,不管是值传递还是引用传递,传递给函数的都是变量的副本,不同的是,值传递的是值的拷贝,引用传递的是地址的拷贝,一般来说,地址拷贝效率高,因为数据量小,而值拷贝决定拷贝的数据大小,数据越大,效率越低。
值传递和引用传递使用特点
(1)值传递:变量直接存储值,内存通常在栈中分配。
(2)默认是值传递的数据类型有:1. 基本数据类型,2. 结构体,3. 共用体,4. 枚举类型。
(3)引用传递:变量存储的是一个地址,这个地址对应的空间才真正存储数据(值)。
(4)默认是引用传递的数据类型有:指针和数组。
(5)如果希望函数内的变量能修改函数外的变量,可以传入变量的地址&,函数内以指针的方式操作变量(*指针)。
(6)从效果上看类似引用,比如修改结构体的属性。
变量作用域
基本介绍
变量作用域:指变量的有效范围。
(1)函数内部声明 / 定义的局部变量,作用域仅限于函数内部。
正确引用
#include<stdio.h>
void sayHello(){
char name[] = "Tom";
printf("%s hello\n",name);
}
void main(){
sayHello();
}
错误引用
#include<stdio.h>
void sayHello(){
char name[] = "Tom";
printf("%s hello\n",name);
}
void main(){
sayHello();
//这里就不能在使用sayHello的name变量
printf("name=%s",name);
}
报错:[Error] ‘name’ undeclared (first use in this function)
(2)函数的参数,形式参数,被当作该函数内的局部变量,如果与全局变量同名它们会优先使用局部变量(编译器使用就近原则)。
(3)在一个代码块,比如for / if中的局部变量,那么这个变量的的作用域就在该代码块。
(4)在所有函数外部定义的变量叫全局变量,作用域在整个程序有效。
初始化局部变量和全局变量
(1)局部变量,系统不会对其默认初始化,必须对局部变量初始化后才能使用,否则,程序运行后可能会异常退出。
(2)全局变量,系统会自动对其初始化,如下所示。
数据类型 初始化默认值
int 0
char '\0'
double 0.0
float 0.0
pointer指针 NIULL
#include<stdio.h>
//全局变量
int a;
float f;
double d1;
void main(){
//打印全局变量
printf("\n a=%d f=%f d1=%f",a,f,d1);
}
作用域的注意事项和细节
(1)全局变量(Global Variable)保存在内存的全局存储区中,占用静态的存储单元,它的作用域默认是整个程序,也就是所有的代码文件,包括源文件(.c文件)和头文件(.h文件)。
(2)局部变量(Local Variable)保存在栈中,函数被调用时才动态地为变量分配存储单元,它的作用域仅限于函数内部。
(3)C语言规定,只能从小的作用域向大的作用域中去寻找变量,而不能反过来,使用更小的作用域中的变量。
(4)在同一个作用域,变量名不能重复,在不同的作用域,变量名可以重复,使用时编译器采用就近原则。
(5)由{ }包围的代码块也拥有独立的作用域。
练习题
思考:下面的代码输出什么内容?
#include<stdio.h>
//全局变量
double price = 200.0;
void test01(){
printf("%.2f\n",price);
}
void test02(){
//编译器采用就近原则
double price = 250.0;
printf("%.2f\n",price);
}
void main(){
printf("main函数中的price=%.2f\n",price);
test01();
test02();
test01();
}