当全局变量和局部变量名字相同的情况下,局部变量优先。
#include <stdio.h>
int num = 10;
int main()
{
int num = 0;
printf("%d\n", num);
return 0;
}
运行结果
在C语言中,当局部变量和全局变量的名字相同时,程序会优先使用局部变量,这是由语言的作用域规则决定的。作用域是指程序中可以访问变量的区域。以下是两种变量作用域的简要说明:
局部变量:
全局变量:
为什么局部变量优先:
建议不要全局变量和局部变量名字设为相同。
const修饰的常变量既有常属性又有变属性。
const int num = 0;
num = 10;
这个写法是错误的,编译器会报错,这是因为const修饰的变量有“常属性”,它们不能被更改。
我们知道C99之前的标准都不允许变长数组,所以数组初始化时[]内只能用常量,例如:
int arr[10] = { 0 };
但是,如果在C99之前的标准中使用下面的代码,则会报错:
const int num = 0;
int arr[num] = { 0 };
这代表num还具有“变属性”。
在C语言中,const
关键字用于声明一个变量为常量。这意味着一旦被初始化后,这个变量的值就不应当被修改。从表面上看,const
修饰的变量具有“常属性”,即它们的值在定义后不可改变。
然而,const
修饰的变量在某些情况下确实展示出一定的“变属性”:
指针与const
:
const
修饰指针时,可以声明指向常量的指针(const
在*
之前)或常量指针(const
在*
之后)。通过指针修改const
:
const
变量本身不应该被修改,但如果将const
变量的地址赋给一个非const
指针,通过指针间接改变其值是可能的。这样做时,需要强制类型转换来绕过编译器的类型检查,这种行为是未定义的(undefined behavior)并且强烈不推荐。存储在可写内存区域:
const
变量通常存储在程序的只读数据段,但如果const
变量是通过malloc
等动态内存分配函数创建的,它实际上存储在堆区,是可以修改的。举例来说,如果你声明了一个const
整型变量:
const int a = 10;
这个变量a
应该在整个程序中保持值不变。尝试修改a
,比如a = 20;
将会导致编译器错误。
然而,如果你使用指针绕过这个限制,像下面这样:
const int a = 10;
int* p = (int*)&a;
*p = 20;
这个代码片段试图修改一个const
变量的值,这是未定义行为。在某些平台和编译器上,它可能导致程序崩溃或其他不可预测的行为,因为a
可能存储在只读内存段。即使它“工作了”,这也是一个不好的编程实践,应该避免。
实际上这里虽然表面上a的值被更改了,实际上a的值可能没有变化。
因为:
编译器优化:因为 a
被声明为 const
,编译器可能已经对代码进行了优化,将 a
的值当成一个常量直接嵌入到了代码中,因此打印的时候直接使用了原始的常量值10,而不是去内存中读取 a
的实际值。
缓存机制:在某些架构中,CPU可能将 const
变量缓存到寄存器中,因此改变内存中的值不会影响到寄存器中的值。
未定义行为:由于修改 const
变量的值是未定义行为,所以实际上任何结果都是可能的,包括没有改变、改变了值、程序崩溃、或者其他奇怪的副作用。
总体来说,正确使用const
可增加程序的可读性和健壮性,它是一个告诉编译器和其他开发者某个值不应被改变的好方法。任何尝试绕过const
的方法都是不安全的,并且应该被视为错误的编程实践。
上层 | 应用软件 |
下层(底层) | 操作系统 |
驱动层 | |
硬件 |
更详细的层次结构:
硬件(Hardware):这是计算机系统的最底层,包括处理器、内存、硬盘、显卡、网络适配器等物理设备。
固件(Firmware)/BIOS/UEFI:这是软硬件之间的一个中间层,通常嵌入在硬件中,为硬件提供最基本的控制和系统启动的功能。
驱动层(Drivers):驱动软件使操作系统能够与硬件设备通信。它们通常是操作系统的一部分,但有时也由硬件制造商提供。
操作系统(Operating System, OS):操作系统是软件与硬件之间的接口层,提供文件管理、内存管理、进程管理等基本服务,并允许用户与系统交互。
中间件(Middleware):中间件是位于操作系统和应用软件之间的软件,为应用程序提供通信和数据管理的服务,这样的例子包括数据库系统、Web服务器和某些API。
应用软件(Application Software):这是用户直接使用的软件层,包括办公软件、图像处理软件、游戏、数据库应用程序等。
这是一个模块化的视图,每一层都建立在前一层的基础之上,为上层提供服务。在实际应用中,某些层次可能会有不同的划分方式,特别是在不同的操作系统架构和计算机架构中。