惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Docker
小众软件
小众软件
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
酷 壳 – CoolShell
酷 壳 – CoolShell
Apple Machine Learning Research
Apple Machine Learning Research
月光博客
月光博客
人人都是产品经理
人人都是产品经理
大猫的无限游戏
大猫的无限游戏
V
V2EX
阮一峰的网络日志
阮一峰的网络日志
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - Franky
WordPress大学
WordPress大学
有赞技术团队
有赞技术团队
Hugging Face - Blog
Hugging Face - Blog
Jina AI
Jina AI
博客园 - 聂微东
S
SegmentFault 最新的问题
量子位
宝玉的分享
宝玉的分享
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园_首页

Dejavu's Blog

甲骨文 ARM 实例部署 Gemma 4 模型 Headscale + Tailscale 组建虚拟专用网 在 Linux 上使用 Yubikey OpenPGP 应用 BuyVM VPS 块存储挂载教程 Alpine Linux 服务器配置指南 Alpine Linux 安装 Cloudflared Docker 多容器共享中心数据库 安装 Komari 服务器监控工具 Scaleway VPS 安装 Debian Linux Debian 13 下部署 AsmBB 论坛 使用 Kopia 自动化备份服务器数据 给 Docker 启用 IPv6 支持 Netcup 服务器安装自定义 ISO 镜像 烽火 HG5582A 光猫开启桥接模式 Docker 自托管 Shlink 短链服务 部署 Obsidian LiveSync 实时同步服务指南 我的 2025 年不完全回顾 Linux 下 Intel 核显驱动配置与硬件加速 Fedora Linux 安装配置记录 2025 年优雅地自托管 RSS 服务 Woodpecker CI 和 Gitea 实现 Hugo 自动部署 Gitea/Forgejo 集成 Woodpecker CI/CD 在 Blinko 中使用 Ollama 作为 AI 供应商 Docker 部署 Gitea/Forgejo Plausible CE 启用城市级地理位置识别 Blinko 开源 AI 知识库 Docker 部署指南 Netcup 免税账号注册及购买服务器全记录 Docker 自托管 Cloudreve Pro 私有网盘服务 GiffGaff SIM 卡使用体验和注意事项 简体中文互联网在变得糟糕吗?
C 学习笔记(三)
Dejavu Moe · 2020-08-02 · via Dejavu's Blog

下面通过几个简单问题的解决,来了解 C 的运算符和变量在实际应用中的作用

第一个 C 程序

打印输出 “Hello World!

#include<stdio.h>
int main()
{
    printf("Hello World!");
    return 0;
}

常量

下面是一个简单的「金额找零」的代码片段

int price = 0;

printf("Please input price:");
scanf("%d,&price");

int change = 100 - price;

printf("Take your change %d dollars \n",change);

固定不变的数,是常数,直接写在程序里,称作 字面量(literal),我们可以更好地修饰这个常量

这是 C99 的写法,补充下上面的代码片段

#include<stdio.h>
{
    const int AMOUNT = 100;
    int price = 0;
    
    printf("Please input price:");
    scanf("%d,&price");

    int change = AMOUNT - price;
    
    printf("Take your change %d dollars \n",change);
    
    return 0;
}

Q: 这样做有什么好处呢?

A: 比如,别人第一次看这个 100 可能不知道是什么,但是看到 AMOUNT 可以知道这是跟数量(金额)有关

const 修饰符

const 是一个修饰符,像上面这样加在 int 前面,表示给这个变量加上一个 const 属性,即这个变量的值一旦 初始化(赋初值),就不能再修改了!一般习惯性的在 const 后面的变量名使用大写。

比如修改上面的程序,在 int price = 0 ; 后面对该变量赋值,会报错 read-only variable is not assignable AMOUNT 90;

#include<stdio.h>
{
    const int AMOUNT = 100;
    int price = 0;
    
    AMOUNT = 90;
    
    printf("Please input price:");
    scanf("%d,&price");

    int change = AMOUNT - price;
    
    printf("Take your change %d dollars \n",change);
    
    return 0;
}

如果这个 AMOUNT 的值让用户输入来进行初始化呢?const 后面的变量值习惯性大写,这里让用户输入,恢复我们习惯的小写

#include<stdio.h>
{
    int amount = 100;
    int price = 0;
    
    printf("Please input price:");
    scanf("%d,&price");
    
    printf("Please input par value:")
    scanf("%d",&amount);
    
    int change = amount - price;
    
    printf("Take your change %d dollars \n",change);
    
    return 0;
}

浮点数

Q:美国人习惯使用英制计量单位,用几尺几寸来报自己的身高,如果遇到一个美国人告诉你他是 5 英尺 7 寸,那他的身高是多少呢?

参考:尺+(寸/12)*0.3048=米数

#include<stdio.h>
int main()
{
	printf("请分别输入身高的英尺数和英寸数,如:1 2 \n");

	int foot;
	int inch;

	scanf("%d,%d", &foot, &inch);
	printf("他的身高是 %f 米\n",((foot+inch/12)*0.3048));

	return 0;
}

对于实际的 5 英尺 7 英寸,正确的计算结果应该是:(5+7/12)*0.3048=1.7019 米,但是上面的程序结果出现问题了,这是为什么呢?

这是因为,在C语言中:

  • 两个整数运算结果只能是整数
  • 比如:在 C 中,10/3=3
  • 1010.0 是两个不同的数

计算时间差

Q:输入两个时间,每个时间分别输入小时和分钟的值,然后输出两个时间的差

常规的,我们的思路是定义不同的变量来存储 hourminute,比如:

int hour1, minute1;
int hour2, minute2;

scanf("%d %d"&hour1, &minute1);
scanf("%d %d"&hour2, &minute2);

但是因为 hourminute 之间不是十进制,在计算的时候假如发生需要“借位”的情况,那岂不是不行了?所以可以统一单位,比如把 hour 也转化为 minute,两个不同的时间 t1t2,有:

  • hour*60 + minute ——> minute 单位
  • t/60——> hour 部分
  • t%60——> minute 部分

这个简单的程序思路有了,可以写出来:

#include<stdio.h>

int main()
{
    int hour1, minute1;
    int hour2, minute2;

    scanf("%d %d", &hour1, &minute1);
    scanf("%d %d", &hour2, &minute2);

    int t1 = hour1*60 + minute1;
    int t2 = hour2*60 + minute2;

    int t = t2-t1;

    printf("时间差是%d小时%d分", t/60, t%60);

    return 0;
}

运算符优先级

运算符优先级

优先级运算符运算结合关系实例
1+单目不变自右向左a*+b
1-单目取负自右向左a*-b
2*自左向右a*b
2/自左向右a/b
2%取余自左向右a%b
3+自左向右a+b
3-自左向右a-b
4=赋值自右向左a=b

赋值运算符

赋值也是运算,也有结果,比如:

  • a=8 ——> a 被赋值 8
  • a=b=8 ——> a=(b=8)

嵌入式赋值

下面这样的写法容易产生错误,并且会大大降低代码的可读性,非常不推荐

int a = 6;
int b;
int c = 1+(b=a);

结合关系

  • 一般自左向右
  • 单目 +/- 和赋值 = 自左向右

下面是一段 C 代码,这种写法和上面「嵌入式赋值」类似——太复杂、容易产生错误,而且会大大降低代码的可读性,同样非常不推荐

result = a = b = 3 + c;
result = 2;
result = (result = result*2)*6*(result = 3 + result);

应该按照程序的实际顺序改写成若干个表达式!

计算复利

Q:在银行存定期的时候,可以选择到期自动转存,并将到期的利息自动并入本金合并转存。如果一年的定期利率是 3.3%,那么连续转存三年后,最初存入的 x 元定期会得到多少本息余额?

首先,可以知道 本息合计 = x*(1+3.3%)^3,对于 3 年的本息复利

int x;
printf("Plese input x:");
scanf("%d",&x);
double amount = x*(1+0,033)*(1+0.033)*(1+0.033)
printf("%f",amount);

交换变量

比如需要交换两个变量的值,就需要第三个变量(假设t就这这个变量)来帮助交换,可以表述为:

  • 交换前:a = 2b = 3t

  • 交换后:a = 3b = 2t

程序实现如下:

#include<stdio.h>

int main()
{
    int a = 2;
    int b = 3;
    int t;
    
    t = a;
    a = b;
    b = t;
    
    printf("a=%d,b=%d",a,b);
    
    return 0;
}

复合赋值

5个算术运算符:+-*/% 可以和 = 结合起来,形成 复合赋值运算符+=-=*=/=%=

注意在这两个运算符之间不要有空格

比如:

  • total += 5 ——> total = total + 5
  • total += (sum+100)/2 ——> total = total + (sum+100)/2
  • total *=sum + 12 ——> total = total * (sum+12)
  • total /= 12 + 6 ——> total = total / (12+6)

递增/递减运算符

++-- 是两个很特殊的运算符,它们是 单目运算符,这两个运算符分别叫做递增和递减运算符,它们的作⽤用就是给这个变量 +1 或者 -1

  • ++-- 可以放在变量的前面,叫做 前缀形式,也可以放在变量的后面,叫做 后缀形式
  • a++ 的值是 a1 以前的值,而 ++a 的值是加了 1 以后的值

对于递增/递减运算符的前缀后缀,可以列表如下:

表达式运算表达式的值
count++count 的值加 1count 原来的值
++countcount 的值加 1count+1 后的值
count--count 的值减 1count 原来的值
--countcount 的值减 1count-1 后的值

验证一下

#include<stdio.h>

int main()
{
	int a;
	a = 10;
	
	printf("a++=%d\n",a++); 
	printf("a=%d\n",a);
	
	printf("++a=%d\n",++a);
	printf("a=%d",a);
    
    return 0;
}

编译链接运行:

这部分开始跟着翁恺老师的 C 语言慕课学习的,大约是前两周内容,下面要加快点速度了。