searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

C语言各种变量与const

2023-03-28 00:55:53
16
0

使用C语言开发中,常使用的变量有全局变量、局部变量、静态全局变量、静态局部变量这几种, 可以从两个方面来区分他们

1、作用域

  • 全局变量具有全局作用域。全局变量只需在一个源文件中定义,就可以作用于所有的源文件。当然,其他不包含全局变量定义的源文件需要用extern 关键字再次声明这个全局变量。
  • 局部变量也只有局部作用域,它是自动对象(auto),它在程序运行期间不是一直存在,而是只在函数执行期间存在,函数的一次调用执行结束后,变量被撤销,其所占用的内存也被收回。
  • 静态全局变量也具有全局作用域,它与全局变量的区别在于如果程序包含多个文件的话,它作用于定义它的文件里,不能作用到其它文件里,即被static关键字修饰过的变量具有文件作用域。这样即使两个不同的源文件都定义了相同名字的静态全局变量,它们也是不同的变量。
  • 静态局部变量具有局部作用域,它只被初始化一次,自从第一次被初始化直到程序运行结束都一直存在,它和静态全局变量的区别在于全局变量对所有的函数都是可见的,而静态局部变量只对定义自己的函数体始终可见。

2、内存分配和存储

  • 全局变量,静态局部变量,静态全局变量都在静态存储区分配空间,而局部变量在栈里分配空间。
  • 全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误;
  • 静态变量会被放在程序的静态数据存储区(全局可见)中,这样可以在下一次调用的时候还可以保持原来的赋值
  • 静态局部变量用static告知编译器,自己仅仅在变量的作用范围内可见。这一点是它与全局变量的区别。

 

3. 进阶:const变量

如下程序比较简单, 很容易得出输出是

/* CONNTRACL */
static const char magicstart[] = {0x43, 0x4f, 0x4e, 0x4e, 0x54, 0x52, 0x41, 0x43, 0x4C};
static const int magiclen = 9;
/* CEND */
static const char magicend[] = {0x43, 0x45, 0x4e, 0x44};

static void help(void)
{
    fprintf(stderr, 
       "\tmagicstart[%s]\n"
        "\tmagicend[%s]\n", magicstart, magicend);
    exit(0);
}

int main(int argc, const char **argv)
{
    help();
    return 0;
}

很容易得出输出是

    magicstart[CONNTRACL]
    magicend[CEND]
 
简单需改一下程序如下
/* CONNTRACL */
static const char magicstart[] = {0x43, 0x4f, 0x4e, 0x4e, 0x54, 0x52, 0x41, 0x43, 0x4C};
static int magiclen = 9;
/* CEND */
static const char magicend[] = {0x43, 0x45, 0x4e, 0x44};

static void help(void)
{
    fprintf(stderr, 
       "\tmagicstart[%s]\n"
        "\tmagicend[%s]\n", magicstart, magicend);
    exit(0);
}

int main(int argc, const char **argv)
{
    help();
    return 0;
}
 

结果并没有按上面的结果输出, 输出的是:

        magicstart[CONNTRACLCEND]
        magicend[CEND]

代码里唯一的差别就是唯一的差别就是变量magiclen, 前面程序中它是const类型的静态全局变量,后者是非const静态全局变量,

const类型的静态全局变量会存储在在只读数据段, 非const静态全局变量存储在静态存储区

后面程序中magicstart没有数组结束符'\n', 中间如果没存储其他类型的数据,在输出字符数组指针magicstart的内容的时候,会输出后面连续的字符、

程序中的变量存储情况可以通过nm进行查看, 可以看到后面的程序magiclen类型是d, 表示全局变量, 类型r表示只读存储区

[root@test]$ nm -n -C test1 |grep magic  
0000000000400680 r magicstart
000000000040068c r magiclen
0000000000400690 r magicend
[root@test]$ nm -n -C test2 |grep magic 
0000000000400680 r magicstart
0000000000400689 r magicend
0000000000601034 d magiclen
0条评论
作者已关闭评论
何****森
15文章数
1粉丝数
何****森
15 文章 | 1 粉丝
何****森
15文章数
1粉丝数
何****森
15 文章 | 1 粉丝
原创

C语言各种变量与const

2023-03-28 00:55:53
16
0

使用C语言开发中,常使用的变量有全局变量、局部变量、静态全局变量、静态局部变量这几种, 可以从两个方面来区分他们

1、作用域

  • 全局变量具有全局作用域。全局变量只需在一个源文件中定义,就可以作用于所有的源文件。当然,其他不包含全局变量定义的源文件需要用extern 关键字再次声明这个全局变量。
  • 局部变量也只有局部作用域,它是自动对象(auto),它在程序运行期间不是一直存在,而是只在函数执行期间存在,函数的一次调用执行结束后,变量被撤销,其所占用的内存也被收回。
  • 静态全局变量也具有全局作用域,它与全局变量的区别在于如果程序包含多个文件的话,它作用于定义它的文件里,不能作用到其它文件里,即被static关键字修饰过的变量具有文件作用域。这样即使两个不同的源文件都定义了相同名字的静态全局变量,它们也是不同的变量。
  • 静态局部变量具有局部作用域,它只被初始化一次,自从第一次被初始化直到程序运行结束都一直存在,它和静态全局变量的区别在于全局变量对所有的函数都是可见的,而静态局部变量只对定义自己的函数体始终可见。

2、内存分配和存储

  • 全局变量,静态局部变量,静态全局变量都在静态存储区分配空间,而局部变量在栈里分配空间。
  • 全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误;
  • 静态变量会被放在程序的静态数据存储区(全局可见)中,这样可以在下一次调用的时候还可以保持原来的赋值
  • 静态局部变量用static告知编译器,自己仅仅在变量的作用范围内可见。这一点是它与全局变量的区别。

 

3. 进阶:const变量

如下程序比较简单, 很容易得出输出是

/* CONNTRACL */
static const char magicstart[] = {0x43, 0x4f, 0x4e, 0x4e, 0x54, 0x52, 0x41, 0x43, 0x4C};
static const int magiclen = 9;
/* CEND */
static const char magicend[] = {0x43, 0x45, 0x4e, 0x44};

static void help(void)
{
    fprintf(stderr, 
       "\tmagicstart[%s]\n"
        "\tmagicend[%s]\n", magicstart, magicend);
    exit(0);
}

int main(int argc, const char **argv)
{
    help();
    return 0;
}

很容易得出输出是

    magicstart[CONNTRACL]
    magicend[CEND]
 
简单需改一下程序如下
/* CONNTRACL */
static const char magicstart[] = {0x43, 0x4f, 0x4e, 0x4e, 0x54, 0x52, 0x41, 0x43, 0x4C};
static int magiclen = 9;
/* CEND */
static const char magicend[] = {0x43, 0x45, 0x4e, 0x44};

static void help(void)
{
    fprintf(stderr, 
       "\tmagicstart[%s]\n"
        "\tmagicend[%s]\n", magicstart, magicend);
    exit(0);
}

int main(int argc, const char **argv)
{
    help();
    return 0;
}
 

结果并没有按上面的结果输出, 输出的是:

        magicstart[CONNTRACLCEND]
        magicend[CEND]

代码里唯一的差别就是唯一的差别就是变量magiclen, 前面程序中它是const类型的静态全局变量,后者是非const静态全局变量,

const类型的静态全局变量会存储在在只读数据段, 非const静态全局变量存储在静态存储区

后面程序中magicstart没有数组结束符'\n', 中间如果没存储其他类型的数据,在输出字符数组指针magicstart的内容的时候,会输出后面连续的字符、

程序中的变量存储情况可以通过nm进行查看, 可以看到后面的程序magiclen类型是d, 表示全局变量, 类型r表示只读存储区

[root@test]$ nm -n -C test1 |grep magic  
0000000000400680 r magicstart
000000000040068c r magiclen
0000000000400690 r magicend
[root@test]$ nm -n -C test2 |grep magic 
0000000000400680 r magicstart
0000000000400689 r magicend
0000000000601034 d magiclen
文章来自个人专栏
C语言
5 文章 | 1 订阅
0条评论
作者已关闭评论
作者已关闭评论
0
0