extern的作用:

extern用来声明变量或者函数,extern声明不是定义,也不分配存储空间。

Example:在一个文件中定义了变量和函数,想要在其他文件中使用它们,可以用两种办法:

  1. 先声明他们,然后引用头文件,其他文件中再去包含这个头文件;
  2. 在其它文件中使用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的用法:

三个作用:修饰局部变量,修饰全局变量,修饰函数

  1. 静态局部变量使用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;程序验证

懒惰是进步的催化剂,也是失败的引擎。