变量在程序中用变量名表示。变量名由用户根据其用途任意命名。
变量名由字母、数字、下划线组成,不能以数字开头,不能和C的关键字重名。
在程序运行时,变量占据存储空间的大小由其数据类型决定。
变量在内存空间中的首地址,称为变量的地址。
变量的说明
变量在程序中使用时,必须预先说明它们的存储类型和数据类型。
变量说明的一般形式是:
<存储类型> <数据类型 > <变量名> ;
<存储类型>是关键词auto、register、static和extern;
<数据类型>可以是基本数据类型,也可以是自定义的数据类型。
变量的存储类型
auto
auto说明的变量只能在某个程序范围内使用,通常在函数体内或函数中的复合语句里。(默认是随机值)
在函数体的某程序段内说明auto存储类型的变量时可以省略关键字auto,如下:
auto int k ;
int j ;
double x;
register
register称为寄存器型,register变量是想将变量放入CPU的寄存器中,这样可以加快程序的运行速度。
如申请不到就使用一般内存,同auto ;
register变量必须是能被CPU所接受的类型。这通常意味着register变量必须是一个单个的值,并且长度应该小于或者等于整型的长度。
不能用“&”来获取register变量的地址。
由于寄存器的数量有限,真正起作用的register修饰符的数目和类型都依赖于运行程序的机器。
在某些情况下,把变量保存在寄存器中反而会降低程序的运行速度。因为被占用的寄存器不能再用于其它目的;或者变量被使用的次数不够多,不足以装入和存储变量所带来的额外开销。
static
static变量称为静态存储类型的变量,既可以在函数体内,也可在函数体外说明。(默认是0)
局部变量使用static修饰,有以下特点:
在内存中以固定地址存放的,而不是以堆栈方式存放
只要程序没结束,就不会随着说明它的程序段的结束而消失,它下次再调用该函数,该存储类型的变量不再重新说明,而且还保留上次调用存入的数值。
extern
当变量在一个文件中的函数体外说明,所有其他文件中的函数或程序段都可引用这个变量。
extern称为外部参照引用型,使用extern说明的变量是想引用在其它文件中函数体外部说明的变量。
static修饰的全部变量,其它文件无法使用
const
const关键字是constant的缩写,翻译为常量、常数。在C语言中const的作用很强大,它可以修饰变量、数组、指针、函数参数等。
const修饰变量:表示希望此变量具有只读性,防止被直接直接修改;
int main()
{
const int a = 10;
a = 20;//错误
return 0;
}
可以通过指针对常变量进行修改:
int main()
{
const int a = 10;
int* p = &a;
*p = 20;
printf("%d\r\n", a);//20
return 0;
}
为了避免通过指针对const修饰的进行修改,应当对用const修饰指针:
int main()
{
const int a = 10;
int const * p = &a;//const *p
int b = 20;
//*p = 20;//错误,只对*P不能修改,但可以对p进行修改
p = &b;
printf("%d\r\n", a);//10
return 0;
}
const修饰数组:const修饰数组时,其值不能被直接修改;
int main()
{
const int a[2] = {1,3};
a[0] = 2;//错误
return 0;
}
const修p:
int main()
{
int a = 100;
int* const p = &a;//const p,p不能修改,*p可以修改
*p = 1000;//可以改变指向的值
//p++;//错误
printf("%d\n", a);//1000
}
const修饰*p:
int main()
{
int a = 10;
const int* p = &a;//const *p,*p不能修改,p可以修改
//*p = 20;//错误
a = 20;//a 本身可以修改
a++;
printf("%d\n", a);//21
}
const修饰p和*p:
int main()
{
const int* const p;//const p,const *p, p和*p都不能修改
return 0;
}
注意以下区别:
int a;
const int* p1 = &a;//const *p1,不能通过指针修改
int const* p2 = &a;//const *p2,不能通过指针修改
int *const p3 = &a;//const p3,指针不能修改
/*判断哪个被const了的标志是const在*的前面还是后面*/
const修饰指针形参:
int myFunc(const int* p)//const *p
{
*p = *p + 1;//*p不能被修改
return *p;
}
int myFunc(int *const p)//const p
{
*p = *p + 1;//可以对*p修改,但无意义
//p++;
return *p;
}
const修饰引用形参:
void function(const Type& Var); //引用参数在函数内不可以改变
参数为引用,将外部实参传递给引用形参,传递的是外部实参本身,无需进行拷贝,增加了效率,同时参数是const引用,无法通过引用修改实参,保证了外部数据的安全性。
const 修饰函数返回值:
const int myFunc()
{
return 1;
}
毫无意义,返回的时临时变量,临时变量具有常性。
const修饰指针类型的返回值 :
const *p形式:
const int* myfun1();
const int* myfun1() {
int a = 1;
return &a;
}
int main()
{
const int* p1 = myfun1();
printf("%d\r\n", *p1);//1
int *p2 = myfun1();
printf("%d\r\n", *p2);//1
return 0;
}
const p形式:
int* const myfun1();
int* const myfun1() {
int a = 1;
return &a;
}
int main()
{
int* const p1 = myfun1();
printf("%d\r\n", *p1);//1
int* p2 = myfun1();
printf("%d\r\n", *p2);//1
return 0;
}