extern的作用:
extern用来声明变量或者函数,extern声明不是定义,也不分配存储空间。
Example:在一个文件中定义了变量和函数,想要在其他文件中使用它们,可以用两种办法:
- 先声明他们,然后引用头文件,其他文件中再去包含这个头文件;
- 在其它文件中使用extern修饰。
//test.c
#include <stdio.h>
int fun(); //声明fun函数
int main(int argc , const char *argv[])
{
fun();
printf("%d\n",h);
return 0;
}
int h=2;
int fun()
{
printf("%d\n",h);
}
显然编译不通过;在运行fun()函数之前,h赋值并未进行。对程序进行一点小修改:
//test.c
#include <stdio.h>
int fun(); //声明fun函数
int main(int argc , const char *argv[])
{
extern int h;
fun();
printf("%d\n",h);
return 0;
}
int h=2;
int fun()
{
printf("%d\n",h);
}
编译通过,打印结果:
2
2
同样,在不同文件中,extern也可以使用。
//main.c
#include <stdio.h>
int main(int argc , const char *arv[])
{
int h;
printf("%d\n".h);
return 0;
}
//fun.c
#include <stdio.h>
int h=10;
int main(int argc , const char *arv[])
{
printf("%d\n".h);
return 0;
}
此时编译运行,main函数中打印的值h是一个随机值。
//main.c
#include <stdio.h>
int main(int argc , const char *arv[])
{
extern int h;
printf("%d\n".h);
return 0;
}
//fun.c
#include <stdio.h>
int h=10;
int main(int argc , const char *arv[])
{
printf("%d\n".h);
return 0;
}
修改main.c中h的变量,声明为extern,此时,再编译运行打印结果为10。
static的用法:
三个作用:修饰局部变量,修饰全局变量,修饰函数
- 静态局部变量使用static修饰符定义,static修饰局部变量可以把它初始化为0。且静态局部变量存储于进程的全局数据区,即使函数返回,它的值也会保持不变。
#include <stdio.h>
int fu()
{
int a= 10;
printf("a = %d\n" ,a);
a++;
printf("a++ = %d\n ,a);
}
int hu(){
int a= 10;
printf( "a %d\n" ,a);
a++;
printf( "a++ = %d\n" ,a);
int main(int argc,const char *argv[])
{
fu();
printf("........\n ");
hu();
printf("........\n ");
fu();
printf("........\n ");
hu();
printf("........\n ");
return 0;
}
编译运行结果:
若将代码修改为:
#include <stdio.h>
int fu()
{
int a= 10;
printf("a = %d\n" ,a);
a++;
printf("a++ = %d\n ,a);
}
int hu(){
static int a= 10;
printf( "a %d\n" ,a);
a++;
printf( "a++ = %d\n" ,a);
int main(int argc,const char *argv[])
{
fu();
printf("........\n ");
hu();
printf("........\n ");
fu();
printf("........\n ");
hu();
printf("........\n ");
return 0;
}
此时,运行结果:
在经过第一次运行hu()后,变量a变成静态变量,因此再次执行hu(),a的值将会继承fu()函数的操作结果;
2、在程序中使用static(修饰全局变量)
静态全局变量仅当前文件可见,其他文件不可访问,其他文件可以定义与其同名的变量,两者互不影响定义在函数体外部,在全局数据区分配存储空间,编译器会自动对其初始化
#include <stdio.h>
static int a= 10;
int fu()
{
printf("a = %d\n" ,a);
a++;
printf("a++ = %d\n ,a);
}
int hu(){
printf( "a %d\n" ,a);
a++;
printf( "a++ = %d\n" ,a);
int main(int argc,const char *argv[])
{
fu();
printf("........\n ");
hu();
printf("........\n ");
fu();
printf("........\n ");
hu();
printf("........\n ");
return 0;
}
编译运行结果:
3、在程序中使用static(修饰函数)
静态全局变量仅当前文件可见,其他文件不可访问,不同的文件可以使用相同名字的静态函数,互不影响。
//main.c
#include <stdio.h>
int nain(int argc,const char *argv[])
{
hu();
return 0;
}
//b.c
#include <stdio.h>
#if 1
static int hu()
{
printf( " world\n");
}
此时能否编译通过?
显然不能,hu()函数被static修饰,只能在b.c中被调用。
const和define以及区别
区别1:执行程序:
define是在编译的预处理阶段起作用,而const是在编译、运行的时候起作用。
区别2:
对程序的作用:
define只是简单的字符串替换,没有类型检查。
而const有对应的数据类型,是要进行判断的,可以避免一些低级的错误。
const int n = 10; const修饰变量n后,保护了变量n,使其不能被赋值修改。
//const.c
const int*p = &n;
//n里面的值不能被改变
*p = 20;//会报错
const1.c const放在*的左边,修饰的是指针指向的内容,保证指针指向的内容不能通过指针来改变。const修饰过的指针变量p不能修改a中的内容,而没有用const修饰过的指针变量q照样可以修改a中的内容,而且a自己也可以重新给自己赋值。
const放在*的右边,修饰的是指针变量本身,保证了指针变量的内容不能修改int*const p = &n;指向n的行为不能被改变
//p = &m;//会报错
int main(int argc, const char *argv[])
{
const int n= 10;
n = 20;
printf("%d\n",n);
return 0;
}
编译无法通过,n被const修饰,值被保护无法再被修改。
int nain(int argc, const char "argv[])
{
int a = 10;
const int *p;
p= &a;
int *q;
q= &a;
*q= 20;
printf("a= %d\n",a);
a =30;
printf("a = %d\n", a);
return 0;
}
const 放在*的左边,修饰的是指针指向的内容, 此内容不能通过这个指针改变,但是可以通过其他指针*q,或者a自身修改*p的内容。若执行*p= xxx就会报错。
int *const p =&n;
p = &a;
此时就会编译报错,因为指向n的行为不能被改变。
4,typedef的理解
1,将变量重新定义新的名字。
系统默认的所有基本类型都可以利用typedef关键字来重新定义类型名。
typedef int data;
将int重新定义成data
2.第二种理解:将结构体重新定义新名字
用以下结构体为例,定义一个名为student的结构体:
struct student{
age x;
number y;
};
调用这个结构体时,必须这样来调用这个结构体struct
student ming={20,100};
// struct student hong;
起个别名:
typedef struct student name;
name ming={20,100}; // name hong;程序验证
Comments | NOTHING
Warning: Undefined variable $return_smiles in /www/wwwroot/ogisosetsuna/wp-content/themes/Sakura/functions.php on line 1096