1. C语言运算符基础解析
刚接触C语言时,运算符就像是一把瑞士军刀,看似简单却功能强大。我在大学第一次接触指针运算时,就深刻体会到了运算符的威力——它能直接操作内存地址,这在其他高级语言中几乎是不可能的事情。
C语言的运算符主要分为以下几类:算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符和其他特殊运算符。每种运算符都有其特定的使用场景和行为特征。比如初学者常犯的错误是混淆"="和"==",前者是赋值运算符,后者才是比较运算符。
注意:C语言中运算符的优先级是个大坑,建议新手在不确定时多用括号明确运算顺序,这比死记硬背优先级表要实用得多。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 算术运算符深度剖析
2.1 基本算术运算
加减乘除这四则运算在C语言中分别对应+、-、*、/运算符。但有个特别之处是取模运算符%,它返回除法后的余数。这里有个经典陷阱:
c复制int a = 5;
int b = 2;
float c = a / b; // 结果是2.0而不是2.5
这是因为整数相除结果还是整数,要得到浮点数结果需要至少一个操作数是浮点型:
c复制float c = (float)a / b; // 正确写法
2.2 自增自减运算符
++和--运算符让很多新手头疼,主要是因为它们有前缀和后缀两种形式:
c复制int i = 5;
int j = i++; // j=5, i=6
int k = ++i; // k=7, i=7
我在实际项目中总结的经验是:在复杂表达式中避免使用自增自减运算符,单独使用时后缀形式更直观。
3. 关系与逻辑运算符
3.1 关系运算符
关系运算符(>, <, >=, <=, ==, !=)用于比较操作数的大小关系,返回0(假)或1(真)。但要注意浮点数的比较:
c复制float a = 0.1 + 0.2;
if(a == 0.3) // 这个条件很可能不成立!
{
//...
}
正确的做法是允许一定的误差范围:
c复制if(fabs(a - 0.3) < 0.00001)
{
//...
}
3.2 逻辑运算符
逻辑运算符(&&, ||, !)用于组合多个条件。&&和||有短路特性,这在某些场景下很有用:
c复制if(p != NULL && p->data > 0) // 如果p为NULL就不会访问p->data
{
//...
}
4. 位运算符的妙用
4.1 基本位运算
位运算符(&, |, ^, ~, <<, >>)直接操作整数的二进制位。这在嵌入式开发和性能优化中很常见:
c复制unsigned char flags = 0;
flags |= 0x01; // 设置第0位
flags &= ~0x02; // 清除第1位
4.2 位运算实用技巧
- 判断奇偶:
c复制if(num & 1) // 奇数
- 交换两个变量的值(不用临时变量):
c复制a ^= b;
b ^= a;
a ^= b;
- 取绝对值(32位整数):
c复制int mask = x >> 31;
x = (x ^ mask) - mask;
5. 赋值运算符的进阶用法
5.1 复合赋值运算符
+=, -=这类运算符不仅简洁,有时还能帮助编译器生成更优的代码:
c复制a += b; // 优于 a = a + b;
5.2 条件运算符
三目运算符(?:)是if-else的简洁替代:
c复制int max = (a > b) ? a : b;
但要注意嵌套使用会降低可读性:
c复制// 不推荐
int x = (a > b) ? ((a > c) ? a : c) : ((b > c) ? b : c);
6. 运算符优先级与结合性
6.1 常见优先级问题
下面这个表达式的结果可能出乎意料:
c复制int a = 5, b = 10, c = 15;
int result = a + b * c; // 155而不是225
建议的解决方案:
- 查优先级表(但很难记全)
- 多用括号明确意图
6.2 结合性陷阱
当优先级相同时,结合性决定计算顺序:
c复制int a = 10, b = 20, c = 30;
a = b = c; // 从右向左结合
7. 类型转换与运算符
7.1 隐式类型转换
C语言会自动进行类型提升:
c复制int i = 5;
float f = 3.14;
double d = i + f; // i先转为float,然后结果转为double
7.2 强制类型转换
显式转换可以避免警告并明确意图:
c复制int a = 5, b = 2;
double result = (double)a / b;
8. 运算符重载(C++特性)
虽然标题主要讲C语言,但考虑到C++的关联性,简单提一下运算符重载:
cpp复制class Vector {
public:
Vector operator+(const Vector& other) {
Vector result;
result.x = x + other.x;
result.y = y + other.y;
return result;
}
};
9. 常见错误与调试技巧
9.1 运算符使用错误
- 误用=代替==:
c复制if(a = 5) // 总是为真,且改变了a的值
- 误用&&代替&:
c复制if(a & b) // 位运算而非逻辑运算
9.2 调试建议
- 使用printf或调试器查看中间结果
- 复杂表达式拆分成多步
- 注意编译器的警告信息
10. 性能优化中的运算符选择
10.1 位运算优化
某些运算用位操作更快:
c复制// 乘以2
x = x << 1;
// 除以2
x = x >> 1;
10.2 避免昂贵的运算
比如在循环中重复计算不变的值:
c复制// 不好
for(int i=0; i<strlen(s); i++) {...}
// 优化
int len = strlen(s);
for(int i=0; i<len; i++) {...}
11. 运算符在数据结构中的应用
11.1 指针运算
指针加减运算在数组操作中很常见:
c复制int arr[5] = {1,2,3,4,5};
int *p = arr;
p++; // 现在指向arr[1]
11.2 结构体操作
虽然不能直接对结构体使用算术运算符,但可以通过指针操作:
c复制typedef struct {
int x;
int y;
} Point;
Point p1 = {1,2}, p2 = {3,4};
Point sum;
sum.x = p1.x + p2.x;
sum.y = p1.y + p2.y;
12. 现代C++中的运算符新特性
12.1 三路比较运算符(C++20)
cpp复制auto result = a <=> b;
if(result < 0) {
// a < b
} else if(result == 0) {
// a == b
} else {
// a > b
}
12.2 用户定义字面量
cpp复制long double operator"" _km(long double val) {
return val * 1000.0;
}
auto distance = 5.0_km; // 5000米
13. 运算符与多线程编程
在多线程环境下,某些看似原子的操作实际上不是:
c复制counter++; // 不是原子操作
应该使用原子操作或互斥锁:
c复制// C11原子操作
#include <stdatomic.h>
atomic_int counter;
atomic_fetch_add(&counter, 1);
14. 运算符在嵌入式开发中的特殊用法
14.1 寄存器操作
c复制#define PORTB (*(volatile uint8_t *)0x25)
PORTB |= (1 << 5); // 设置PB5为高
14.2 位域操作
c复制struct {
unsigned int flag1 : 1;
unsigned int flag2 : 1;
} status;
status.flag1 = 1;
15. 运算符的边界情况处理
15.1 整数溢出
c复制int a = INT_MAX;
a++; // 未定义行为
15.2 除零错误
c复制int x = 0;
int y = 5 / x; // 运行时错误
16. 运算符重载的最佳实践
在C++中重载运算符时要注意:
- 保持运算符的直观语义
- 考虑异常安全性
- 必要时实现为友元函数
cpp复制class Complex {
friend Complex operator+(const Complex&, const Complex&);
// ...
};
17. 运算符与模板元编程
C++模板元编程中运算符有特殊用法:
cpp复制template<int N>
struct Factorial {
static const int value = N * Factorial<N-1>::value;
};
template<>
struct Factorial<0> {
static const int value = 1;
};
18. 运算符在算法中的应用
18.1 快速幂算法
c复制int pow(int a, int b) {
int result = 1;
while(b) {
if(b & 1) result *= a;
a *= a;
b >>= 1;
}
return result;
}
18.2 位图排序
c复制void bitmap_sort(int arr[], int n) {
const int SIZE = 1000000;
char bitmap[SIZE/8] = {0};
// 设置位
for(int i=0; i<n; i++) {
bitmap[arr[i]/8] |= 1 << (arr[i]%8);
}
// 输出结果
for(int i=0; i<SIZE; i++) {
if(bitmap[i/8] & (1 << (i%8))) {
printf("%d ", i);
}
}
}
19. 运算符与字符串处理
19.1 字符串拼接
c复制char str1[20] = "Hello";
char str2[] = " World";
strcat(str1, str2); // 注意缓冲区溢出风险
19.2 字符串比较
c复制if(strcmp(str1, str2) == 0) {
// 字符串相等
}
20. 运算符在文件操作中的应用
20.1 文件状态检查
c复制FILE *fp = fopen("test.txt", "r");
if(fp == NULL) {
perror("Error opening file");
return;
}
20.2 位操作处理文件权限
c复制struct stat st;
stat("test.txt", &st);
if(st.st_mode & S_IRUSR) {
// 用户有读权限
}
21. 运算符与内存管理
21.1 指针算术
c复制int *arr = malloc(10 * sizeof(int));
int *p = arr + 5; // 指向第6个元素
21.2 内存对齐
c复制#define ALIGN(p, a) (((uintptr_t)(p) + ((a)-1)) & ~((uintptr_t)(a)-1))
void *aligned_malloc(size_t size, size_t align) {
void *p = malloc(size + align - 1);
return (void *)ALIGN(p, align);
}
22. 运算符在图形编程中的应用
22.1 颜色混合
c复制uint32_t blend_colors(uint32_t c1, uint32_t c2, float ratio) {
uint8_t r = (uint8_t)(((c1 >> 16) & 0xFF) * ratio + ((c2 >> 16) & 0xFF) * (1-ratio));
uint8_t g = (uint8_t)(((c1 >> 8) & 0xFF) * ratio + ((c2 >> 8) & 0xFF) * (1-ratio));
uint8_t b = (uint8_t)((c1 & 0xFF) * ratio + (c2 & 0xFF) * (1-ratio));
return (r << 16) | (g << 8) | b;
}
22.2 矩阵运算
c复制void matrix_multiply(float a[3][3], float b[3][3], float result[3][3]) {
for(int i=0; i<3; i++) {
for(int j=0; j<3; j++) {
result[i][j] = 0;
for(int k=0; k<3; k++) {
result[i][j] += a[i][k] * b[k][j];
}
}
}
}
23. 运算符在游戏开发中的特殊用法
23.1 碰撞检测
c复制bool check_collision(Rect a, Rect b) {
return !(a.x + a.w < b.x ||
a.x > b.x + b.w ||
a.y + a.h < b.y ||
a.y > b.y + b.h);
}
23.2 随机数生成
c复制unsigned int seed = 12345;
int rand() {
seed = (seed * 1103515245 + 12345) & 0x7fffffff;
return seed;
}
24. 运算符在密码学中的应用
24.1 简单加密
c复制char* xor_encrypt(char *input, char *key) {
char *output = strdup(input);
for(int i=0; i<strlen(input); i++) {
output[i] = input[i] ^ key[i % strlen(key)];
}
return output;
}
24.2 哈希计算
c复制unsigned int simple_hash(char *str) {
unsigned int hash = 5381;
int c;
while((c = *str++)) {
hash = ((hash << 5) + hash) + c; // hash * 33 + c
}
return hash;
}
25. 运算符在数值计算中的注意事项
25.1 浮点数比较
c复制bool nearly_equal(float a, float b, float epsilon) {
float abs_a = fabs(a);
float abs_b = fabs(b);
float diff = fabs(a - b);
if(a == b) {
return true;
} else if(a == 0 || b == 0 || diff < FLT_MIN) {
return diff < (epsilon * FLT_MIN);
} else {
return diff / fmin(abs_a + abs_b, FLT_MAX) < epsilon;
}
}
25.2 大整数运算
c复制typedef struct {
uint32_t digits[100];
int length;
} BigInt;
void bigint_add(BigInt *a, BigInt *b, BigInt *result) {
uint64_t carry = 0;
int max_len = a->length > b->length ? a->length : b->length;
for(int i=0; i<max_len; i++) {
uint64_t sum = (uint64_t)a->digits[i] + b->digits[i] + carry;
result->digits[i] = sum & 0xFFFFFFFF;
carry = sum >> 32;
}
if(carry) {
result->digits[max_len] = carry;
result->length = max_len + 1;
} else {
result->length = max_len;
}
}
26. 运算符在并发编程中的陷阱
26.1 内存屏障
c复制// 写操作
shared_var = new_value;
__sync_synchronize(); // 内存屏障
// 读操作
__sync_synchronize(); // 内存屏障
local_copy = shared_var;
26.2 原子操作
c复制int atomic_add(int *ptr, int value) {
int old = *ptr;
while(!__sync_bool_compare_and_swap(ptr, old, old + value)) {
old = *ptr;
}
return old;
}
27. 运算符在嵌入式脚本中的应用
27.1 简单解释器实现
c复制typedef enum {
OP_ADD,
OP_SUB,
OP_MUL,
OP_DIV
} OpCode;
int interpret(OpCode *code, int *operands, int length) {
int stack[100];
int sp = 0;
for(int i=0; i<length; i++) {
switch(code[i]) {
case OP_ADD: stack[sp-2] += stack[sp-1]; sp--; break;
case OP_SUB: stack[sp-2] -= stack[sp-1]; sp--; break;
case OP_MUL: stack[sp-2] *= stack[sp-1]; sp--; break;
case OP_DIV: stack[sp-2] /= stack[sp-1]; sp--; break;
default: stack[sp++] = operands[i]; break;
}
}
return stack[0];
}
27.2 表达式求值
c复制int eval_expr(const char *expr) {
// 实现一个简单的表达式求值器
// 这里省略了词法分析和语法分析部分
// 实际实现会使用栈来处理运算符优先级
}
28. 运算符在编译器设计中的角色
28.1 词法分析
c复制TokenType get_operator_token(const char *op) {
switch(op[0]) {
case '+': return (op[1] == '+') ? TK_INC : TK_ADD;
case '-': return (op[1] == '-') ? TK_DEC : TK_SUB;
case '*': return TK_MUL;
case '/': return TK_DIV;
case '%': return TK_MOD;
// 其他运算符...
}
}
28.2 语法分析
c复制Expr *parse_expr(int prec) {
Expr *lhs = parse_primary();
while(1) {
int curr_prec = get_precedence(current_token);
if(curr_prec < prec) break;
Token op = current_token;
next_token();
Expr *rhs = parse_expr(curr_prec + (is_right_assoc(op) ? 0 : 1));
lhs = new_binary_expr(op, lhs, rhs);
}
return lhs;
}
29. 运算符在虚拟机设计中的实现
29.1 字节码解释
c复制void interpret(VM *vm) {
while(1) {
Bytecode bc = fetch_bytecode(vm);
switch(bc.op) {
case OP_ADD: {
Value a = pop(vm);
Value b = pop(vm);
push(vm, a + b);
break;
}
// 其他操作...
}
}
}
29.2 即时编译
c复制void jit_compile_add(JitCompiler *compiler) {
emit_load_reg1(compiler); // 加载第一个操作数
emit_load_reg2(compiler); // 加载第二个操作数
emit_add(compiler); // 生成加法指令
emit_store_result(compiler); // 存储结果
}
30. 运算符在硬件描述语言中的差异
虽然这不是C/C++,但了解Verilog/VHDL中的运算符差异很有帮助:
verilog复制// Verilog中的位拼接运算符
wire [7:0] a = {4'b1010, 4'b1100}; // 结果为8'b10101100
// 条件运算符
assign out = sel ? in1 : in2;
31. 运算符在函数式编程中的对应概念
C++11引入的lambda表达式可以看作是一种特殊的运算符:
cpp复制auto add = [](int a, int b) { return a + b; };
int sum = add(3, 4); // sum = 7
32. 运算符在元编程中的高级应用
32.1 SFINAE技术
cpp复制template<typename T>
auto test_add(T t) -> decltype(t + t, std::true_type{}) {
return {};
}
template<typename>
std::false_type test_add(...) {
return {};
}
// 检查类型是否支持+运算符
constexpr bool can_add = decltype(test_add<T>(std::declval<T>()))::value;
32.2 表达式模板
cpp复制template<typename L, typename R>
struct AddExpr {
L lhs;
R rhs;
auto operator[](int i) const { return lhs[i] + rhs[i]; }
};
template<typename L, typename R>
AddExpr<L,R> operator+(L lhs, R rhs) {
return {lhs, rhs};
}
33. 运算符在数据序列化中的应用
33.1 简单序列化
c复制typedef struct {
int x;
float y;
char z[20];
} Data;
void serialize(Data *data, uint8_t *buffer) {
memcpy(buffer, &data->x, sizeof(data->x));
buffer += sizeof(data->x);
memcpy(buffer, &data->y, sizeof(data->y));
buffer += sizeof(data->y);
memcpy(buffer, data->z, sizeof(data->z));
}
33.2 字节序转换
c复制uint32_t ntohl(uint32_t netlong) {
uint8_t *p = (uint8_t *)&netlong;
return ((uint32_t)p[0] << 24) |
((uint32_t)p[1] << 16) |
((uint32_t)p[2] << 8) |
p[3];
}
34. 运算符在信号处理中的特殊用法
34.1 位操作处理信号
c复制sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGINT); // 添加SIGINT到信号集
34.2 掩码操作
c复制#define SET_BIT(mask, bit) ((mask) |= (1 << (bit)))
#define CLEAR_BIT(mask, bit) ((mask) &= ~(1 << (bit)))
#define TEST_BIT(mask, bit) ((mask) & (1 << (bit)))
35. 运算符在时间处理中的应用
35.1 时间计算
c复制struct timespec diff_timespec(struct timespec start, struct timespec end) {
struct timespec temp;
if((end.tv_nsec - start.tv_nsec) < 0) {
temp.tv_sec = end.tv_sec - start.tv_sec - 1;
temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec;
} else {
temp.tv_sec = end.tv_sec - start.tv_sec;
temp.tv_nsec = end.tv_nsec - start.tv_nsec;
}
return temp;
}
35.2 定时器实现
c复制#define TIMER_INTERVAL 1000 // 1秒
uint32_t last_tick = 0;
void check_timer(uint32_t current_tick) {
if(current_tick - last_tick >= TIMER_INTERVAL) {
last_tick = current_tick;
// 执行定时任务
}
}
36. 运算符在图形用户界面编程中的应用
36.1 坐标计算
c复制// 检查点是否在矩形内
bool point_in_rect(Point p, Rect r) {
return p.x >= r.x && p.x <= r.x + r.w &&
p.y >= r.y && p.y <= r.y + r.h;
}
36.2 颜色操作
c复制uint32_t blend_colors(uint32_t c1, uint32_t c2, float alpha) {
uint8_t r1 = (c1 >> 16) & 0xFF;
uint8_t g1 = (c1 >> 8) & 0xFF;
uint8_t b1 = c1 & 0xFF;
uint8_t r2 = (c2 >> 16) & 0xFF;
uint8_t g2 = (c2 >> 8) & 0xFF;
uint8_t b2 = c2 & 0xFF;
uint8_t r = r1 * alpha + r2 * (1 - alpha);
uint8_t g = g1 * alpha + g2 * (1 - alpha);
uint8_t b = b1 * alpha + b2 * (1 - alpha);
return (r << 16) | (g << 8) | b;
}
37. 运算符在音频处理中的应用
37.1 音量调节
c复制void adjust_volume(int16_t *samples, int count, float factor) {
for(int i=0; i<count; i++) {
samples[i] = (int16_t)(samples[i] * factor);
// 处理溢出
if(samples[i] > INT16_MAX) samples[i] = INT16_MAX;
if(samples[i] < INT16_MIN) samples[i] = INT16_MIN;
}
}
37.2 混音
c复制void mix_samples(int16_t *dst, const int16_t *src, int count) {
for(int i=0; i<count; i++) {
int32_t mixed = dst[i] + src[i];
// 简单的饱和处理
dst[i] = (mixed > INT16_MAX) ? INT16_MAX :
((mixed < INT16_MIN) ? INT16_MIN : mixed);
}
}
38. 运算符在图像处理中的应用
38.1 像素操作
c复制void invert_image(uint8_t *img, int width, int height) {
for(int i=0; i<width*height; i++) {
img[i*3] = 255 - img[i*3]; // R
img[i*3+1] = 255 - img[i*3+1]; // G
img[i*3+2] = 255 - img[i*3+2]; // B
}
}
38.2 卷积运算
c复制void apply_kernel(uint8_t *src, uint8_t *dst, int width, int height,
float kernel[3][3]) {
for(int y=1; y<height-1; y++) {
for(int x=1; x<width-1; x++) {
float sum = 0;
for(int ky=-1; ky<=1; ky++) {
for(int kx=-1; kx<=1; kx++) {
sum += src[(y+ky)*width + (x+kx)] *
kernel[ky+1][kx+1];
}
}
dst[y*width + x] = (uint8_t)fmin(fmax(sum, 0), 255);
}
}
}
39. 运算符在物理模拟中的应用
39.1 向量运算
c复制typedef struct {
float x, y;
} Vec2;
Vec2 vec2_add(Vec2 a, Vec2 b) {
return (Vec2){a.x + b.x, a.y + b.y};
}
Vec2 vec2_mul(Vec2 v, float s) {
return (Vec2){v.x * s, v.y * s};
}
39.2 碰撞响应
c复制void resolve_collision(Body *a, Body *b, Vec2 normal) {
Vec2 relative_vel = vec2_sub(b->velocity, a->velocity);
float vel_along_normal = vec2_dot(relative_vel, normal);
if(vel_along_normal > 0) return;
float restitution = fmin(a->restitution, b->restitution);
float j = -(1 + restitution) * vel_along_normal;
j /= a->inv_mass + b->inv_mass;
Vec2 impulse = vec2_mul(normal, j);
a->velocity = vec2_sub(a->velocity, vec2_mul(impulse, a->inv_mass));
b->velocity = vec2_add(b->velocity, vec2_mul(impulse, b->inv_mass));
}
40. 运算符在人工智能中的应用
40.1 矩阵运算
c复制void matrix_multiply(float *a, float *b, float *result,
int m, int n, int p) {
for(int i=0; i<m; i++) {
for(int j=0; j<p; j++) {
float sum = 0;
for(int k=0; k<n; k++) {
sum += a[i*n + k] * b[k*p + j];
}
result[i*p + j] = sum;
}
}
}
40.2 激活函数
c复制float relu(float x) {
return x > 0 ? x : 0;
}
float sigmoid(float x) {
return 1 / (1 + expf(-x));
}
41. 运算符在区块链技术中的应用
41.1 哈希计算
c复制void sha256_hash(const uint8_t *data, size_t len, uint8_t hash[32]) {
SHA256_CTX ctx;
sha256_init(&ctx);
sha256_update(&ctx, data, len);
sha256_final(&ctx, hash);
}
41.2 工作量证明
c复制bool check_pow(uint64_t nonce, const uint8_t block_hash[32],
uint64_t difficulty) {
uint8_t hash[32];
SHA256_CTX ctx;
sha256_init(&ctx);
sha256_update(&ctx, block_hash, 32);
sha256_update(&ctx, (uint8_t*)&nonce, sizeof(nonce));
sha256_final(&ctx, hash);
// 检查前导零是否符合难度要求
int zero_bits = 0;
for(int i=0; i<32; i++) {
if(hash[i] == 0) {
zero_bits += 8;
} else {
zero_bits += __builtin_clz(hash[i]);
break;
}
}
return zero_bits >= difficulty;
}
42. 运算符在量子计算模拟中的应用
42.1 量子门操作
c复制void apply_hadamard(Complex *state, int qubit, int size) {
const Complex inv_sqrt2 = {1/sqrt(2), 0};
for(int i=0; i<(1<<size); i++) {
if(i & (1 << qubit)) continue;
int j = i | (1 << qubit);
Complex tmp1 = complex_add(state[i], state[j]);
Complex tmp2 = complex_sub(state[i], state[j]);
state[i] = complex_mul(tmp1, inv_sqrt2);
state[j] = complex_mul(tmp2, inv_sqrt2);
}
}
42.2 量子态测量
c复制int measure_qubit(Complex *state, int qubit, int size, float rand) {
float prob0 = 0;
for(int i=0; i<(1<<size); i++) {
if(!(i & (1 << qubit))) {
prob0 += complex_norm_sq(state[i]);
}
}
return rand > prob0 ? 1 : 0;
}
43. 运算符在金融计算中的应用
43.1 复利计算
c复制double compound_interest(double principal, double rate,
int years, int compounds_per_year) {
return principal * pow(1 + rate/compounds_per_year,
years * compounds_per_year);
}
43.2 期权定价
c复制double black_scholes(double S, double K, double T,
double r, double sigma, char type) {
double d1 = (log(S/K) + (r + sigma*sigma/2)*T) / (sigma*sqrt(T));
double d2 = d1 - sigma*sqrt(T);
if(type == 'C') {
return S*cdf_normal(d1) - K*exp(-r*T)*cdf_normal(d2);
} else {
return K*exp(-r*T)*cdf_normal(-d2) - S*cdf_normal(-d1);
}
}
44. 运算符在生物信息学中的应用
44.1 DNA序列处理
c复制uint64_t dna_to_bits(const char *dna, int len) {
uint64_t result = 0;
for(int i=0; i<len; i++) {
result <<= 2;
switch(dna[i]) {
case 'A': result |= 0; break;
case 'C': result |= 1; break;
case 'G': result |= 2; break;
case 'T': result |= 3; break;
}
}
return result;
}
44.2 序列比对
c复制int hamming_distance(uint64_t a, uint64_t b, int len) {
uint64_t diff = a ^ b;
int distance = 0;
for(int i=0; i<len; i++) {
if(diff & 3) distance++;
diff >>= 2;
}
return distance;
}
45. 运算符在密码破解中的应用
45.1 暴力破解
c复制void brute_force(const char *charset, int max_len,
bool (*check)(const char*)) {
char *attempt = malloc(max_len + 1);
memset(attempt, 0, max_len + 1);
int *indices = calloc(max_len, sizeof(int));
int len = 1;
while(len <= max_len) {
// 生成当前组合
for(int i=0; i<len; i++) {
attempt[i] = charset[indices[i]];
}
if(check(attempt)) {
printf("Found: %s\n", attempt);
free(attempt);
free(indices);
return;
}
// 递增索引
int pos = 0;
while(pos < len) {
indices[pos]++;
if(indices[pos] < strlen(charset)) {
break;
}
indices[pos++] = 0;
}
if(pos == len) {
len++;
}
}
free(attempt);
free(indices);
}
