C语言总结2(变量和常量)

2、变量和常量

2.1、变量
变量,指的是在程序运行过程中,可以通过代码使它的值改变的量。
2.1.1、局部变量
定义在函数中的变量,就叫局部变量。
2.1.1.1、普通局部变量(auto)
普通的局部变量定义时直接定义,或者在定义前加auto关键字

void func1(void)
{
	int i = 1;
	
	i++;
	
	printf("i = %d.\n", i);
}

局部变量i的解析:
在连续三次调用func1中,每次调用时,在进入函数func1后都会创造一个新的变量i,并且给它赋初值1,然后i++时加到2,然后printf输出时输出2.然后func1本次调用结束,结束时同时杀死本次创造的这个i。这就是局部变量i的整个生命周期。下次再调用该函数func1时,又会重新创造一个i,经历整个程序运算,最终在函数运行完退出时再次被杀死。

2.1.1.2、静态局部变量(static)
静态局部变量定义时前面加static关键字。

总结:
1、静态局部变量和普通局部变量不同。静态局部变量也是定义在函数内部的,静态局部变量定义时前面要加static关键字来标识,静态局部变量所在的函数在多调用多次时,只有第一次才经历变量定义和初始化,以后多次在调用时不再定义和初始化,而是维持之前上一次调用时执行后这个变量的值。本次接着来使用。
2、静态局部变量在第一次函数被调用时创造并初始化,但在函数退出时它不死亡,而是保持其值等待函数下一次被调用。下次调用时不再重新创造和初始化该变量,而是直接用上一次留下的值为基础来进行操作。
3、静态局部变量的这种特性,和全局变量非常类似。它们的相同点是都创造和初始化一次,以后调用时值保持上次的不变。不同点在于作用域不同
练习题目:c语言中static静态的局部变量和非静态的局部变量的区别

#include <stdio.h>


void func1(void);
void func_static(void);
void func_static2(void);
void func_global(void);
void func_register(void);

int g_a = 1;


int main(void)
{
	//a = 4;			// 编译报错,未定义
	g_a = 5;			// 可以,因为g_a是全局变量,所以到处都可以用

	func1();		// i = 2
	func1();		// i = 2
	func1();		// i = 2
	
	func_static();	// a = 2
	func_static();	// a = 3
	func_static();	// a = 4
	
	func_static2();	// a = 4;
	func_static2();	// a = 7;
	func_static2();	// a = 10;
	
	func_global();	// g_a = 4;
	func_global();	// g_a = 7;
	func_global();	// g_a = 10;
	
	func_register();
	func_register();
	func_register();
	
	
	
/*	
 因为i是定义在函数func中的局部变量,所以i的作用域为代码块作用域,所以i只在func1
 函数内部有效,在func1外面是不能访问i的。所以这里i会无定义。
 */
	//i = 5;		// error: ‘i’ undeclared (first use in this function)
	
	return 0;
}


void func1(void)
{
	int i = 1;			    	// 普通的局部变量,auto可以省略的
	//auto int i = 0;			// 自动局部变量,其实就是普通局部变量
	
	i++;
	
	printf("i = %d.\n", i);
}

void func_static(void)
{
	static int a = 1;		// 静态的局部变量
	
	a++;
	
	printf("a = %d.\n", a);
}

void func_static2(void)
{
	static int a = 1;		// 静态的局部变量
	
	a += 3;
	
	printf("a = %d.\n", a);
}

void func_global(void)
{
	g_a += 3;
	
	printf("g_a = %d.\n", g_a);
}

void func_register(void)
{
	register int a = 1;		// 静态的局部变量
	
	a += 3;
	
	printf("a = %d.\n", a);
}

2.1.1.4、register关键字
register(寄存器),C语言的一个关键字
register int i = 3;

总结:register类型的局部变量表现上和auto是一样的,这东西基本没用,知道就可以了。register被称为:C语言中最快的变量。C语言的运行时环境承诺,会尽量将register类型的变量放到寄存器中去运行(普通的变量是在内存中),所以register类型的变量访问速度会快很多。但是它是有限制的:首先寄存器数目是有限的,所以register类型的变量不能太多;其次register类型变量在数据类型上有限制,譬如你就不能定义double类型的register变量。一般只在内核或者启动代码中,需要反复使用同一个变量这种情况下才会使用register类型变量。

2.1.2、全局变量
定义在函数外面的变量,就叫全局变量。
2.1.2.1、普通全局变量
普通全局变量就是平时使用的,定义前不加任何修饰词。普通全局变量可以在各个文件中使用,可以在项目内别的.c文件中被看到,所以要确保不能重名
2.1.2.2、静态全局变量
静态全局变量就是用来解决重名问题的。静态全局变量定义时在定义前加static关键字,告诉编译器这个变量只在当前本文件内使用,在别的文件中绝对不会使用。这样就不用担心重名问题。所以静态的全局变量就用在我定义这个全局变量并不是为了给别的文件使用,本来就是给我这个文件自己使用的。

2.1.1.3、跨文件引用全局变量(extern)
就是说,你在一个程序的多个.c源文件中,可以在一个.c文件中定义全局变量g_a,并且可以在别的另一个.c文件中引用该变量g_a(引用前要声明)
函数和全局变量在C语言中可以跨文件引用,也就是说他们的连接范围是全局的,具有文件连接属性,总之意思就是全局变量和函数是可以跨文件看到的(直接影响就是,我在a.c和b.c中各自定义了一个函数func,名字相同但是内容不同,编译报错。)。
练习题目:C语言中全局变量和局部变量分别怎么使用


#include <stdio.h>

void func1(void);

/* 全局变量的特点:在整个文件中所有的函数内都可以访问该全局变量,而且访问的都是该
全局变量本身。如果你在之前某个函数中更改了它的值,则后面再引用时它的值就是前面
那次更改之后的值。
*/
int g_a;


int main(void)
{
	printf("g_a = %d.\n", g_a);			// 0
	func1();
	printf("g_a = %d.\n", g_a);			// 100
	
	g_a += 1;
	printf("g_a = %d.\n", g_a);			// 101
	
	
	return 0;
}

void func1(void)
{
	g_a = 100;
}

局部变量和全局变量的对比:
1、定义同时没有初始化,则局部变量的值是随机的,而全局变量的值是默认为0.
2、使用范围上:全局变量具有文件作用域,而局部变量只有代码块作用域。
3、生命周期上:全局变量是在程序开始运行之前的初始化阶段就诞生,到整个程序结束退出的时候才死亡;而局部变量在进入局部变量所在的代码块时诞生,在该代码块退出的时候死亡。
4、变量分配位置:全局变量分配在数据段上,而局部变量分配在栈上。

判断一个变量能不能使用,有没有定义,必须注意两点:第一,该变量定义的作用域是否在当前有效,是否包含当前位置;第二,变量必须先定义后使用。所以变量引用一定要在变量定义之前
练习题目:区分全局变量和局部变量

#include <stdio.h>

int func(void);

int g_a = 5;			// g_a定义在函数外面,因此是全局变量

int main(void)
{
	int a;			// a定义在main函数中,所以是局部变量
	
	a = 23;
	printf("a = %d, g_a = %d.\n", a, g_a);
	
	printf("g_a = %d.\n", g_a);
	
	//func();
	
/*
	int i;
	for (i=0; i<10; i++)
	{
		int b = 5;		// b定义在这里,则作用域只有for后面的{}里面,外面是看不见的
		
		b++;
	}
	printf("b = %d.\n", b);
	
*/	
	
	return 0;
}




int func(void)
{
	int i;
	int j;
	int k;
	
	//i = a;		// a是main函数中定义的局部变量,它的作用域只有main函数中的代码块
				// 因此在这里不能访问a
	return i;
}

基本概念:
作用域:起作用的区域,也就是可以工作的范围。
代码块:所谓代码块,就是用{}括起来的一段代码。
数据段:数据段存的是数,像全局变量就是存在数据段的
代码段:存的是程序代码,一般是只读的。
栈(stack):C语言对内存的管理方式。,先进后出。C语言中局部变量就分配在栈中。

2.2、常量
常量,程序运行过程中不会改变的量。常量的值在程序运行之前初始化的时候给定一次,以后都不会变了,以后一直是这个值。
2.2.1、#define定义的常量
#define N 20 // 符号常量
int a[N];
练习题目:C语言中三种常量的演示

#include <stdio.h>

#define N 	20


int main(void)
{

/*
	const int i = 10;
	
	// i = 20;		// error: assignment of read-only variable ‘i’
*/

/*
	int a[N];
	
	//N = 21;		// error: lvalue required as left operand of assignment
	
	printf("sizeof(a) = %d.\n", sizeof(a));		// 20*4 = 80
*/	
	return 0;
}

2.2.2、const关键字

const int i = 14
const和指针结合,共有4种形式
const int *p;	    p是一个指针,指针指向一个int型数据。p所指向的是个常量。		
int const *p;   	p是一个指针,指针指向一个int型数据。p所指向的是个常量。	
int *const p;   	p是一个指针,指针指向一个int型数据。p本身是常量,p所指向的是个变量
const int *const p;	p是一个指针,指针指向一个int型数据。p本身是常量,指向的也是常量

结论和记忆方法:

1、const在*前面,就表示const作用于p所指向的量。所以这时候p所指向的是个常量。
2、const在*后面,表示p本身是常量,但是p指向的不一定是常量。

const型指针有什么用?
char *strcpy(char *dst, const char *src);
字符串处理函数strcpy,它的函数功能是把src指向的字符串,拷贝到dst中。

2.2.3、枚举常量
枚举常量是宏定义的一种替代品,在某些情况下会比宏定义好用。
enum

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值