两种变量、四种存储类以及他们的存储区、生存期与作用域....

一、两种变量
局部变量:在函数内部定义
全局变量:在函数外部定义
二、 四种存储类
auto (自动类型):
修饰局部变量auto int a;
平时定义的变量都是自动变量,auto可以省略 , 没有赋初值为随机数 ,栈空间存放 ,从定义位置开始,到当前代码块结束,即局部变量用完就释放 ,作用于当前代码块。

register (寄存器类型):
修饰局部变量 register int a;
平时的变量都保存在栈中,如果有一些数据需要频繁存取,将数据存储到寄存器中,方便存取。

static (静态):
①修饰局部变量 ,static int a;
这个变量只会被初始化一次,存放在静态数据段,从定义位置开始到整个程序将结束,作用域为当前代码块,修饰全局变量 ,在全局变量的定义之前加static修饰,这个变量只能本当前文件使用,就算其他文件extern声明也不能使用。
②修饰函数 ,在函数定义之前加static
这个函数只能被当前文件下的函数调用,不能被其他文件调用,就算其他文件进行了extern声明。

extern (外部):
①修饰全局变量
定义一个全局变量,存在静态区域,当前代码结束才会释放空间 ,作用域本文件,其他文件不能使用。默认没有外部链接属性,如果其他文件要是用本文件的全局变量的话,要进行extern声明。
②修饰函数
如果函数的定义在其他文件中,需要先外部声明函数,就可以调用其他文件中的函数。

链接:
一个具有外部链接的变量可以在一个多文件程序的任何地方使用;一个具有内部链接的变量可以在一个文件的任何地方使用。
int giant=5; //文件作用域,外部链接
static int dodgers=3; //文件作用域,内部链接

三、堆空间 主动申请主动释放

#include <stdlib.h>

void *malloc(size_t size);    //在堆空间中申请size个字节大小空间,返回这块空间的首地址
//int *  char *
//void *:通用类型地址  相当于一级指针
//void **

int a=10;
int *p=(int *)malloc(4);   //在堆空间定义一个int

int a[10];
int *p=(int *)malloc(40);  //在堆空间定义一个int数组

char ch[20];
char *p=(char *)malloc(20);  //在堆空间定义一个char数组





void free(void *ptr);   //释放堆空间
void *calloc(size_t nmemb, size_t size);  
//在堆空间中申请nmemb块,每块size个字节大小的堆空间,返回首地址,对申请的空间清空为0

/*
    int a[10];
    int *p=(int *)malloc(40);
    int *q=(int *)calloc(10,sizeof(int));  //便于代码可读性
*/


void *realloc(void *ptr, size_t size);  //修改ptr指向的堆空间的大小变为size个字节
/*
    int a[10];          //数组长度固定,不能改变
    int *p=(int *)malloc(40);   //在堆空间定义int数组
    p=realloc(p,80);   //把数组长度扩充          //动态数组:数组长度可变

*/

例1:验证局部变量的生存期

#include <stdio.h>

int *fun(void)
{
    //static int a;      //代码正确
    int a;               //代码错误,局部变量a,当前代码块结束就释放,所以当函数调用结束,a就释放了,在主函数中不能使用a
    a=10;
    return &a;
}

int main(void)
{
    int *p=fun();
    *p=20;              //错误

    printf("%d\n",*p);
    return 0;
}

例2:验证局部变量的生存期与作用域

#include <stdio.h>

int a=100;
int b=200;

int main(void)
{
    printf("%d %d\n",a,b);
    int a=10;
    int b=20;

    {
	int a=5;
	int b=6;
	int c=30;
	printf("%d %d %d\n",a,b,c);           //变量使用,往上找定义语句。
    }

    printf("%d %d\n",a,b);
    return 0;
}

例3:static修饰局部变量 这个局部变量只能被初始化一次

#include <stdio.h>

void fun(void)
{
    static int a=1;   //虽然多次调用这个函数,但这句话只会在第一次调用的时候执行.
    a++;

    printf("%d\n",a);
}

int main(void)
{
    int i;
    for(i=0;i<10;i++)
    {
    
	fun();
    }

    return 0;
}

例4:演示多个编译单位

main.c

#include <stdio.h>

int main(void)
{
    fun();

    return 0;
}

fun.c

#include <stdio.h>

void fun(void)
{
    printf("i am fun!\n");

}

gcc main.c fun.c -o main
./main

例5:static与extern修饰函数

main.c

#include <stdio.h>

extern void fun(void);

int main(void)
{
    fun();

    return 0;
}

fun.c

#include <stdio.h>

static void fun(void)
{
    printf("i am fun!\n");

}

例6: static与extern修饰全局变量

main.c
#include <stdio.h>
static int a=10;

int main(void)
{
    fun();

    printf("%d\n",a);
    return 0;
}

fun.c
#include <stdio.h>
extern int a;

void fun(void)
{
    printf("%d\n",a);
    a=20;

    printf("%d\n",a);

}

例7: 实验堆空间申请与释放函数

#include <stdio.h>
#include <stdlib.h>

int *fun(void)
{
    //int a=10;
    int *p=(int *)malloc(sizeof(int));
    return p;
}

int main(void)
{
    int *p=fun();
    *p=20;

    free(p);
    printf("%d\n",*p);

    //free(p);
    return 0;
}

四、宏定义
编译预处理命令行:以#开头的行 宏定义 文件包含 条件编译 …
1、没有参数的宏
#define 宏名 替换文本 //在文件起始位置函数之外定义,没有;结尾
宏名 : 名字,变量名的规则 一般大写
替换文本 : 宏所代表的的内容

#define N 10
#define QQQ printf(“i love you”)
#define QQQ printf(“i love you!\n”);printf(“marry me!\n”);printf(“do you?\n”)

1#include <stdio.h>
#define N 10

void fun(int *p)
{
    int i;
    for(i=0;i<N;i++)
    {
	p[i]=0;
    }

}

int main(void)
{
    int a[N];
    fun(a);

    int i;
    for(i=0;i<N;i++)
    {
	printf("%d  ",a[i]);
    }

    return 0;
}

2 、带参数的宏
#define 宏名(参数) 替换文本
#define PRINT(a) printf("%d\n",a)
要注意参数最好每个都用小括号括起来

3 、宏替换 :
它与函数调用的方法不同 ,先把宏的替换文本替换对应的宏的位置,然后把参数一一替换.
#include <stdio.h>
//#define SUM(a,b) ab
//#define SUM(a,b) (a)
(b)
#define SUM(a,b) ((a)+(b)) //最安全的写法

int main(void)
{
    int x=10;
    int y=20;
    int ret=SUM(x+y,y);   //(x+y)*(y)
    printf("%d\n",ret);

    return 0;
}

4 、预定义符号

#include <stdio.h>

int main(void)
{
    printf("%s\n",__FILE__);
    printf("%d\n",__LINE__);
    printf("%s\n",__FUNCTION__);
    printf("%s\n",__DATE__);
    printf("%s\n",__TIME__);

    return 0;
}


//system()   //执行一个shell命令  system("clear");
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值