C语言学习杂记(2)—C的数据

计算机的计算和存储都是数据。在C语言里,数据同样是基础,学好数据的知识是必须的。
先看一个最简单的例子

#include <stdio.h>

int main(void)
{
    int weight;
    float cost;
    float value;

    printf("please input your weight.\n");
    scanf("%d", &weight);
    printf("please input your single cost.\n");
    scanf("%f", &cost);
    value = weight * cost;
    printf("your total cost is %.2f\n", value);

    return 1;
}
效果图

C中的基本数据类型如下,而我们可以把他们分成两类(整数类型、浮点数类型)。
K&R关键字:int、long、short、unsigned、char、float、double
C90新增:signed、void
C99新增:_Bool、_Complex、_Imaginary
整数,就是不带小数点的数。浮点数,整数之间的那些数。

一、int类型

C之所以提供多种整数类型,原因在于为程序员针对不同用途场景提供多种选择。C的整数类型间的区别在于其提供数值的范围和是否可以取负。int是基本类型,我们可以根据任务和机器选择其他类型。

1、声明int类型。为变量赋值,可以在声明的时候赋值,还可以通过scanf的方式。
int param;
int cows, dogs;
int weight, cost = 3; // 尽量避免这样的声明,因为从字面上感觉weight也是被赋值为3了。实际上,weight仍然是未赋值状态。
scanf("%d", &cows);
2、十进制、八进制、二进制和十六进制

计算机内部数据表示使用的是二进制,它带来的好处是简单,它只有两个数值0和1。
十进制是我们日常的表示方法,我们人有十个手指头,数值为0-9。
虽然二进制很简单,但是书写起来却是很麻烦的一件事,所以我们可以把3个二进制位表示为八进制;把4个二进制位表示为十六进制。同二进制和十进制一样,八进制数值为0-7,十六进制数值为0-9、A-F。
声明进制如下:

十进制 八进制 十六进制
int a = 13 int a = 015 int a = 0xD

打印如下:

十进制 八进制 十六进制
%d %o %x
%d %#o %#x
3、其他整数类型(short、long、unsigned、signed修饰)

[a->signed|unsigned] | [b->short|long|long long] | [c->int] param
当a或者b存在时,可以省略c;如果类型本身为有符号数,可省略signed。
例如:

int a;
long int estate;
long johns;
short int eyes;
short count;
unsigned long etc;
signed int gg;
signed cool;
long long ago;

在声明long和无符号常量时,我们可以使用后缀u代表无符号,使用l或L代表长整形。比如:3uLL、3ULL、3ull、3ul、3Ull。但是我们一般使用L,而非l,因为l和大写的i很像。

要打印这些类型时,我们可以考虑一些规则。signed使用%d,unsigned使用%u,long使用%l(小写的L),short使用%h,他们可以和进制结合起来(再复习一下,o表示八进制,x表示十六进制,#表示显示进制符号——0/0x)。
例如:

#include <stdio.h>

int main(void)
{
    unsigned int un = 30000000;
    short end = 200;
    long big = 65537;
    long long verybig = 12345678908642;
    printf("un = %u and not %d\n", un, un);
    printf("big = %ld and not %hd\n", big, big);
    printf("verybig = %lld and not %ld\n", verybig, verybig);
    
    return 1;
}

二、char类型

char类型使用一个字节来表示,一个字节有8个二进制位,所以最多有256个可能数,标准ASCII编码范围从0~127。而一些系统对其进行了扩展,但也是限定在8位之内。

1、声明
char response;
char iter, latan;
2、常量及初始化

char类型理论上仍然是一个数字,所以我们可以使用范围内的int来表示。另外,我们也可以使用字符用单引号引起来表示。例如:

char boild = 'A';
char let = 65;
char etc = '\n';
3、转义字符

正如\n所表示,有时我们需要转义字符,比如:回车、换行、跳格、制表符等。转义字符的声明是使用反斜杠+特殊说明来表示。这儿的特殊说明可以简单列举如下:

字符 意义
\n 换行
\b 退格
\0oo 八进制值(o表示一个八进制数字)
\xhh 十六进制值(hh表示一个十六进制数字)

上述表格中,我们尤其强调一下八进制值和十六进制值。我们为什么要这样表示,而不直接使用0oo和0xhh表示呢。有两个原因,一个是前者能很直观地表述程序员的意图(是一个字符,而非数字),另一个原因是前者可以方便地嵌入到字符串中,例如:"\007"。

三、_Bool

这个类型是c99才引入的,它只有两个值:0和1,1代表true,0代表false。

四、inttype.h,引入可移植类型

上述整数类型已经足够多了,但是它却不能很明确地表示int是4个字节,long long是8个字节,short是2个字节。为了解决这些问题,c99引入可选名字集合,以确定描述信息,前提是引用头文件inttype.h。例如:int16_t表示一个16位有符号整数类型,uint32_t表示一个32位无符号整数类型。
除了限制字长和有无符号,它还包含其他特性。速度特性,如:int_fast8_t。最小长度特性,如:int_least8_t。最大最小峰值,如:intmax_t和uintmax_t分别表示最大有符号整数和最大无符号整数。为打印提供的特定宏,如PRId16打印16位有符号值等。

五、浮点类型

c语言中,浮点类型包括:float、double、long double。而为了表示很大和很小的数,科学家研究出了科学计数法,例如:123.00使用1.23e2或1.23E2表示。e或E表示10的幂。如果系统支持c99的十六进制格式浮点数,则可以使用a或A代替e或E
浮点数的表示,一般使用以下格式表示:
[+|-] | [小数点前] | [小数点.] | [小数点后] | [e|E + 整数表示10的幂]
float和double的打印使用%f,long double使用%Lf,科学计数法使用%e。例如%e、%f、%Lf、%Le、%La

#include <stdio.h>

int main(void)
{
    float a = 33.234;
    printf("%%a is %a %%e is %e\n", a, a);

    return 1;
}

输出如下:

zhangfb@zhangfb-pc:~/workspace/formal/c/first$ gcc two.c
zhangfb@zhangfb-pc:~/workspace/formal/c/first$ ./a.out
%a is 0x1.09df3cp+5 %e is 3.323400e+01

浮点数和整数都存在上溢和下溢的问题,如:两个很大的数相加,超出实际能表示的最大数。浮点数和整数又不太一样,浮点数存在精度的问题,两个浮点数相乘,可能出现实际的值和数学计算出的值不一致的情况,例如3.33*2.333333,使用数学方法计算得出7.76999889,但是float在某些系统上最大的精度为6,也就是说只能表示小数点后6位,这时,最后两位89就会丢失。

六、复数和虚数

这两种类型,用得最多的是科学和工程领域,所以暂时不做说明。

总结

这儿,我以条例的方式,列出一些日常容易犯的错误和一些好的建议。

1、使用和类型相匹配的声明
int a = 3; // 推荐写法
int b = 3.3; // 应避免写法
int cost = 33.98; // 应避免写法,C会简单地舍弃小数点及其后面部分,而非四舍五入
float alpha = 32.3323499; // 应避免写法,float精度为6,所以会舍弃掉最后一位
2、类型前缀

一些有经验的程序员会有自己的变量命名规范,例如int类型的变量名为i_开头,unsigned short类型的变量名以us_开头。这种方式无分好坏,因人而异,比如在Java语言中,推荐变量名中不加入类型前缀。而C语言是推荐这种命名方式。

3、输入输出函数的变量个数确定

调用scanf和printf函数时,因为参数个数不固定,编译器不会检查个数和格式是否匹配,如果少写或多写了一些参数,会出现一些让人意外的情况。例如:

int a = 3;
float b = 33.2343;
int c, d;

printf("a is %d and b is %.2f\n", a);
printf("a is %d\n", a, b);
printf("please input c.\n");
scanf("%d", &c, &d);
printf("c is %d\n", c);
4、类型长度规范

整数类型:short <= unsigned short <= int <= unsigned int <= long <= unsigned long <= long long <= unsigned long long
浮点类型:float <= double <= long double

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容