# 03 - 变量声明与赋值

Viper 的变量声明使用 Python 的类型注解语法，通过 `t` 模块指定 C 级别的类型信息。

## 带注解的变量声明

使用 `变量名: 类型` 语法声明变量：

```python
x: t.CInt = 0                    # int x = 0;
y: t.CUInt32T = 42               # uint32_t y = 42;
name: list[t.CChar, 64]          # char name[64];
ptr: t.CVoid | t.CPtr            # void* ptr;
msg: t.CConst | str = "Hello"    # const char* msg = "Hello";
```

### 无初始值的声明

未赋值的变量声明会生成零初始化的变量，此处是未定义行为，即在不同环境位置可能会覆盖0，也可能不会，最好预先复制或用 memset 清除：

```python
count: t.CInt                     # int count = 0;
buffer: list[t.CChar, 256]        # char buffer[256] = {0};
```

### 延迟赋值

变量可以先声明后赋值：

```python
x: t.CInt
x = 10
```

### 指针变量

```python
p:       t.CInt | t.CPtr               # int* p;
fb:      t.CVoid | t.CPtr             # void* fb;
str_ptr: t.CConst | t.CChar | t.CPtr  # const char* str_ptr;
```

### 指针变量的特殊初始化

使用 `t.CVoid(0, t.CPtr)` 初始化指针为 NULL：

```python
p: t.CVoid | t.CPtr = t.CVoid(0, t.CPtr)  # void* p = NULL;
```

或使用 `None`：

```python
p: t.CVoid | t.CPtr = None      # void* p = NULL;
```

## 普通赋值

```python
x: t.CInt = 0
x = 42                            # x = 42;
```

## 增强赋值

支持所有 Python 增强赋值运算符：

```python
x: t.CInt = 0
x += 1                            # x += 1;
x -= 1                            # x -= 1;
x *= 2                            # x *= 2;
x //= 3                           # x /= 3; (整数除法)
x %= 5                            # x %= 5;
x <<= 1                           # x <<= 1;
x >>= 1                           # x >>= 1;
x |= 0xFF                         # x |= 0xFF;
x &= 0x0F                         # x &= 0x0F;
x ^= 0xAA                         # x ^= 0xAA;
```

## 全局变量

模块顶层声明的变量即为全局变量：

```python
kbd_tid: t.CInt = -1              # 全局 int kbd_tid = -1;
BootInfo: bootinfo | t.CPtr       # 全局 struct bootinfo* BootInfo;
```

### 静态全局变量

```python
x: t.CStatic | t.CInt = 0        # static int x = 0;
```

### 外部声明

```python
x: t.CExtern | t.CInt            # extern int x;
```

## 常量定义

使用 `t.CDefine` 定义编译时常量。`t.CDefine` 不是数据类型，而是编译时元指令——常量在 LLVM IR 中不生成全局变量，而是在引用处直接内联展开。详见 [01-overview.md 中 t.CDefine 深度解析](01-overview.md#tcdefine-深度解析)。

```python
MAX_SIZE: t.CDefine = 1024
PAGE_SIZE: t.CDefine = 4096
FA_READ: t.CDefine = 0x01
FA_WRITE: t.CDefine = 0x02
```

## 字符串常量

Viper 中的字符串字面量编译为 C 的字符串常量（`const char*`）：

```python
msg: t.CConst | str = "Hello, World!"
serial.puts(msg)
```

也可以直接传递字符串字面量：

```python
serial.puts("Hello, World!")
```

## 类型转换

使用类型构造函数进行显式类型转换：

```python
x: t.CInt = 42
y: t.CUInt32T = t.CUInt32T(x)    # (uint32_t)x
f: t.CFloat = float(x)           # (float)x
i: t.CInt = int(f)               # (int)f
```

### 指针类型转换

```python
ptr: t.CVoid | t.CPtr = some_ptr
int_val: t.CUInt64T = t.CUInt64T(ptr)  # (uint64_t)ptr — 指针转整数
```

## 结构体实例化

> 此处不理解参见 ([05-classes.md 中 结构体实例化与初始化](05-classes.md#结构体实例化与初始化))

直接使用类名作为构造函数：

```python
info: fat32_types.fat32_fileinfo
dp: fat32_types.fat32_dirobj
```

带初始化的实例化：

```python
obj: MyClass = MyClass(arg1, arg2)
```

使用 `c.Addr` 获取实例指针：

```python
obj_ptr: MyClass | t.CPtr = c.Addr(MyClass(arg1, arg2))
```

## delete 语句

`del` 语句可用于调用对象的 `__del__` 或 `__delete__` 方法：

```python
del obj        # 调用 obj.__del__() 或 obj.__delete__()
del arr[idx]   # 调用 arr.__delitem__(idx)
```
