vimer linux kernel 爱好者

c中的一些简单认识

2016-03-10

static

修饰变量

这个static其实一点都不安静,这不,你得注意以下几点:

静态全局变量

作用域只限于从定义处开始,到文件结尾处,即使你使用extern去申请也不管用的。

静态局部变量

在函数体里定义,就只能在这个函数体里面使用,同一文件的其他的函数使用也是 不行的,由于被static修饰??的存放在内存的静态区,就是这个函数运行结束, 变量也不会被撤销。


#include<stdio.h>
static int j;
void fun1(void)
{
	static int i = 0;
	i ++;
	printf("\n");
	printf("static's i= %d\t",i);
}
void fun2(void){
	j = 0;
	j ++;
	printf("\n");
	printf("non-static j=%d\t",j);
}
int main(){
	int k;
	for(k = 0; k < 10; k++){
		fun1();
		fun2();

	}
	return 0;
}

下面是该段程序的运行结果:

static's i= 1	non-static j=1	static's i= 2
non-static j=1	static's i= 3	non-static j=1
static's i= 4	non-static j=1	static's i= 5
non-static j=1	static's i= 6	non-static j=1
static's i= 7	non-static j=1	static's i= 8
non-static j=1	static's i= 9	non-static j=1
static's i= 10	non-static j=1

从这里我们可以看出来,fun1()内的静态变量没有被释放,还是维持着 上次运行的结果。

修饰函数

这里的修饰,是应该它本来的面目,也就是指该函数只对该文件有效,这样, 不同的人在一个大型项目中不必担心命名冲突。linux kernel中充斥着大量的 static.

void

作用两个: 1) 对函数返回的限定 2) 对函数参数的限定

指针

如果p1和p2的指针类型相同,我们可以在p1和p2之间相互赋值,如果P1和P2 指向不同的数据类型,则必须使用强制类型转换运算符把赋值运算符右边的 指针类型转换为左边指针的类型。 例如:

float *p1;
int *p2;
p1 = p2;

最后一句是错误的,必须按照

p1 =(float *)p2;

来赋值。 但是不能将void类型的指针赋值给有类型的指针。

补充

该标准规定不能对void类型的指针进行算法运算,因为不知道该指针的类型(存储空间)。 但是,GNU委员会不这么认为,它规定void * 的类型与char * 的类型一致。所以, 你想写出移植行很高的代码,需要进行如下的操作:

void *pvoid;
(char *)pvoid++;//ANSI: right
(char *)pvoid += 1; //ANSI: errors

修饰返回值和参数

默认不显式的声明函数的类型,则默认为int

如果函数参数为空,最好声明为void

如果函数的参数可以是任意的指针,应该声明为void *.

例如,内存操作函数:

void *memcpy(void *dest, const void *src, size_t len);
void *memset(void *buffer, int c, size_t num);

这样,任何类型的指针都可以传入memset和memcpy中,

const

const 修饰的只读变量只能在定义的同时初始化:

const int Max = 10;

修饰一般变量

int const i = 2; 或者 const int i = 2;

修饰数组

int const a[5] = {1,2,3,4,5};
const int a[5] = {1,2,3,4,5};

修饰指针

const int *p;// const 修饰*p,p是指针,*p是指针指向的对象,不可变
int const *p;
int *const p;
const int *const p;

以上情况有些复杂,我们需要仔细的分析。

编译器解析的时候首先忽略类型名,这里,我们也需要先忽略类型名。 我们看const离谁近,就修饰谁。

const int *p;

int const *p;

int *const p;

const int *const p;

修饰函数的参数

const 修饰符也可以修饰函数的参数,当不希望这个参数被函数体内意外改变使用。 例如:

void Fun(const int i);

修饰函数的返回值

const 修饰函数时,返回值不可改变.

const int fun(void)

在另一连接文件中引用const只读变量:

extern const int i;

volatile

这个关键词大概见过几次,我只是简单的了解到,使用了这个修饰符,编译器不再对 代码进行优化。请看例子:

int i = 10
int k = i;
int j = i;

这里,由于i除了第一句被用作了左值,后两条被用作了右值,也就是说在编译器将i 的值赋值给j后,编译器并没有将i的值立即丢掉,马上将i的值赋值给了k,也就是这 一步,不用经过内存访问,这里提高了效率。

再看下面的例子:

volatile int i = 10;
int k = i;
int j = i;

这里,volatile 关键字告诉编译器,i是随时可以改变的,每次使用它时变量必须每次 从内存中取出来,也就是不能把i的是使用两次


下一篇 c语言连接mysql

Comments

Content