《C程序设计语言》笔记(一)
一:导言
1:printf中的格式化字符串:
%ld 按照long整型打印
%6d 按照十进制整数打印,至少6个字符宽,不够的话空格补齐
%6f 浮点数打印,至少6个字符宽
%.2f 浮点数打印,精确到小数点2位
%6.2f 浮点数打印,至少6个字符宽,小数点后有2位
%.0f 不打印小数点和小数部分
2:较早版本C语言,可以按照下面的方式定义函数:
power(base, n)
int base, n;
{
...
}
而且,早期C语言,可以在程序的开头按照下面这种形式声明power函数:
int power();
函数声明中不允许包含参数列表。
ANSIC仍然支持旧式的函数声明与定义。这种形式的声明和定义,在linux下使用gcc编译,不会产生错误。
3:C语言中,所有函数参数都是“通过值”传递的。也就是说,传递给被调用函数的参数值存放在临时变量中,而不是存放在原来的变量中。所以,在被调用函数中,参数可以看做是局部变量,比如:
int power(int base, int n)
{
int p;
for(p= 1; n > 0;
--n)
{
p = p * base;
}
return p;
}
二:类型、运算符与表达式
1:局部变量一般使用较短的变量名,外部变量使用较长的名字。
2:类型限定符signed和unsigned可用于限定char类型或任何整型。
类型长度定义的符号常量以及其他与机器和编译器有关的属性可以在标准头文件<limits.h>和<float.h>中找到。
3:long类型的常量以字母l或L结尾,比如123456789L。如果一个整数太大以至于无法用int类型表示时,也将被当做long类型处理。
无符号常量以u或U结尾。后缀ul或UL表明是unsignedlong类型。
没有后缀的浮点数常量为double类型。后缀f或F表示float类型,而后缀l或L表示long double类型。
,也可以写为0x1f或0X1F。
可以用’\ooo’表示任意字节大小的位模式。其中,ooo代表1-3位八进制数字。这种位模式还可以用’\xhh’表示。
。字符串中,使用\”表示双引号。
编译时,可以将多个字符串常量连接起来,比如:”hello,” “world”等价于”hello, world”。注意,两个字符串之间是空格,不是逗号,所以只有printf(“hello,
” “world\n”); 才能打印正确,而printf(“hello, ”, “world”)不会。
4:枚举类型
a:,以此类推。如果只指定了部分枚举名的值,那么未指定值的枚举名的值将依着最后一个指定值向后递增。比如:
enum months {JAN= 1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC}; FEB的值为2,MAR的值为3,依次类推。
调试程序可以以符号的形式打印出枚举变量的值。
b:以下代码定义了这种新的数据类型 - 枚举型
enum DAY
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
};
enum DAY是一种类型,而不是变量,它是枚举类型,这比较类似于结构体类型的定义。注意,定义枚举类型,也要以”;”结尾。
c:用枚举类型声明变量的方式如下: enum DAY yesterday; 其中yesterday是变量名,它是一种枚举类型的变量。其他定义枚举类型变量的方式有:
enum
{
saturday, sunday = 0, monday, tuesday, wednesday, thursday, friday
} workday; //变量workday的类型为枚举型enum DAY
enum week { Mon=1, Tue, Wed, Thu, Fri Sat, Sun} days; //变量days的类型为枚举型enum week
enum BOOLEAN { false, true } end_flag, match_flag; //定义枚举类型并声明了两个枚举型变量
d:可以用typedef关键字将枚举类型定义成别名,并利用该别名进行变量声明:
typedef enum workday
{
saturday, sunday = 0, monday, tuesday, wednesday, thursday, friday
} workday; //此处的workday为枚举型enum workday的别名
workday today, tomorrow; //变量today和tomorrow的类型为枚举型workday,也即enum workday
enum workday中的workday可以省略:
typedef enum
{
saturday, sunday = 0, monday, tuesday, wednesday, thursday, friday
} workday; //此处的workday为枚举型enum workday的别名
workday today, tomorrow; //变量today和tomorrow的类型为枚举型workday,也即enum workday
e:同一个程序中不能定义同名的枚举类型,不同的枚举类型中也不能存在同名的命名常量。
错误声明一:存在同名的枚举类型
typedef enum
{
wednesday, thursday, friday
} workday;
typedef enum WEEK
{
saturday, sunday = 0, monday,
} workday;
错误声明二:存在同名的枚举成员
typedef enum
{
wednesday, thursday, friday
} workday_1;
typedef enum WEEK
{
wednesday, sunday = 0, monday,
} workday_2;
f:枚举类型变量的赋值:
typedef enum {ONE, TWO, THR}number;
numbera = ONE; //ok
numberb = 100; //ok 可以用超出范围的整型值
numberc = 2.3; //ok 可以用浮点数
numberd = 'c'; //ok 可以用字符常量
numbere = "hh"; //error:incompatible types when initializing type ‘number’ using type ‘char *’
g:可以直接用枚举类型的常量给变量赋值:
typedef enum {ONE, TWO, THR}number;
int a = ONE; //ok
floatg = ONE; //ok
doubleh = ONE; //ok
chari = ONE; //ok
5:如果变量不是自动变量,则只能进行一次初始化操作。这是在程序开始执行之前进行的,并且初始化表达式必须为常量表达式。如果定义外部变量、内部静态变量如下,则会出错:
int a = f(); // error: initializer element is not constant
static int b =f(); // error: initializer elementis not constant
自动变量的初始化时,其初始化表达式可以是任何表达式。
6:在有负操作数的情况下,整数除法截取的方向,以及模运算结果的符号取决于具体机器的实现。
7:在关系表达式或逻辑表达式中,如果关系为真,则表达式的结果值为数值1;如果为假,则结果值为数值0。比如:
int c = (3 < 4); //1
int b = (1 > 2); //0
int d = (3 < 4) || (1 > 2); //1
int e = (3 < 4) && (1 >2); //0
在if,while,for等语句的测试部分,“真”就意味着非0。
8:转换
a:一般来说,自动转换是指把“比较窄的”操作数,转换为“比较宽的”操作数,并且不丢失信息的转换。
b:需要注意,当把一个char类型的值转换为int类型的值时,其结果是否为负数,对于不同的机器,会有不同的结果。
c;C语言的定义,保证了机器的标准打印字符集中的字符不会是负值。
d:在一个表达式中,凡是可以使用整型的地方,都可以使用带符号或无符号的char、short、enum类型的对象。如果原始类型的所有值都可用int类型表示,则其值被转换为int类型;否则,将被转换为unsigned
int类型。这称为整型提升。比如:
char a = 0;
short c = 0;
sizeof(a) 为1,sizeof(c)为2, sizeof(a+1)为4,sizeof(c+1)为4,后两个之所以为4,是因为发生的整型提升。注意:sizeof(‘a’); 的值,也是4.
e:很多情况下会进行隐式的算数类型转换。如果二元操作符的两个操作数具有不同的类型,那么在进行运算之前,需要先把“低”类型提升为“高”类型,运算的结果为高类型。这种方式的转换为称为“普通算术类型转换”:
首先,如果任何一个操作数为longdouble类型,则将另一个操作数转换为long double类型。
否则,如果任何一个操作数为double类型,则将另一个操作数转换为double类型。
否则,如果任何一个操作数为float类型,则将另一个操作数转换为float类型。
否则,同时对两个操作数进行整型提升;然后,如果任何一个操作数为unsigned long int类型,则将另一个操作数转换为unsigned long int类型。
否则,如果一个操作数为long int类型且另一个操作数为unsignedint类型,则结果依赖于long int类型是否可以表示所有的unsigned int类型的值。如果可以,则将unsigned int类型的操作数转换为long int;如果不可以,则将两个操作数都转换为unsigned long int类型。
否则,如果一个操作数为long int类型,则将另一个操作数转换为long int类型。
否则,如果任何一个操作数为unsignedint类型,则将另一个操作数转换为unsigned int类型。
否则,将两个操作数都转换为int类型。
注意:新版本的C标准有两个变化:第一,对float类型操作数的算术运算可以只用单精度而不是双精度,而在之前的版本,所有的浮点运算都是双精度。也就是float类型,不在自动提升为double类型。第二,当较短的无符号类型与较长的带符号类型一起运算时,不将无符号类型的属性传递给结果类型;而在旧版本中,无符号类型总是处于支配地位。
f:强制类型转换:(类型名)表达式。它的含义是:表达式首先被赋值给类型名指定的某个变量,然后再用该变量替换上述整条语句。
g:当函数被调用时,声明将对参数进行自动强制转换。比如sqrt函数原型是double sqrt(double);则函数调用sqrt(2),不需要使用强制类型转换运算符,就可以自动将整数2强制转换为double类型的值2.0。
9:s[j++] = s[i]; 该语句等价于s[j]
= s[i]; j++; 使用第一种方式,更加简洁!
10:在对unsigned类型的无符号值进行右移位时,左边空出的部分将用0填补;填补)。
11:x = x & ~077; 本语句将把x的最后6位设置为0。注意,该表达式与机器字长无关,他比形式为x&0177700的表达式要好,因为后者假定x是16位的数值。而且,这种可移植的形式并没有增加额外开销,因为~077是常量表达式,可以在编译时求值。
12:e1 op= e2等价于e1 = (e1) op (e2),它们的区别是,前一种形式e1只计算一次。也就是说:x *=
y+1,等价于x = x * (y+1)
13:赋值表达式的类型是它的左操作数的类型,其值是赋值完成后的值。
14:的一个二进制位。
15:除了运算符&&、||、?:和逗号运算符之外,C语言没有指定同一运算符中,多个操作数的计算顺序,所以,x
= f() + g();这样的语句中,函数f和g谁先调用是不确定的。
参数的求职顺序也没有指定,比如这样的语句也要避免:
printf(“%d %d\n”, ++n, power(2, n));
C语言标准对大多数这类问题有意未做具体规定。如果代码的执行结果,与求值顺序相关,则这是不好的程序设计风格。
16:运算符的优先级和结合性:
三:控制流
1:switch语句是一种多路判定语句,它测试表达式是否与一些常量整型值中的某一个值匹配。
在switch语句中,case的作用只是一个标号,因此,某个分支中的代码执行完后,程序将进入下一分支继续执行,除非在程序中显示的跳转。
作为一种良好的程序设计风格,在switch语句最后一个分支,也就是default分支的后面也加一个break语句,虽然逻辑上没有必要,但是会降低犯错的可能性。
2:for(e1; e2; e3){} 中,3个组成部分都可以省略,但是分号必须保留。如果省略了e2,则认为其值永为真值。
3:逗号运算符是C中优先级最低的运算符,在for中会经常用到。被逗号分隔的一对表达式将按照从左到右的顺序进行求值,表达式右边的操作数的类型和值即为其结果的类型和值。
4:尽量少的使用goto语句,但是,某些场合下goto语句还是用得着的,最常见的用法是终止程序在某些深度嵌套的结构中的处理过程,比如一次跳出两层或多层循环。比如:
for(...)
for(...){
...
if(disaster)goto error;
}
...
error:
...
标号的命名同变量命名的形式相同。标号的作用域是整个函数。
《C程序设计语言》笔记(一)的更多相关文章
- python程序设计语言笔记 第一部分 程序设计基础
1.1.1中央处理器(CPU) cpu是计算机的大脑,它从内存中获取指令然后执行这些指令,CPU通常由控制单元和逻辑单元组成. 控制单元用来控制和协调除cpu之外的其他组件的动作. 算数单元用来完成数 ...
- C程序设计语言笔记-第一章
The C Programming language notes 一 基础变量类型.运算符和判断循环 char 字符型 character ...
- 北京大学Cousera学习笔记--6-计算导论与C语言基础--计算机的基本原理-认识程序设计语言 如何学习
1.是一门高级程序语言 低级语言-机器语言(二进制) 汇编语言-load add save mult 高级语言:有利于人们编写理解 2.C语言的规范定义非常的宽泛 1.long型数据长度不短于int型 ...
- MOOC 编译原理笔记(一):编译原理概述以及程序设计语言的定义
编译原理概述 什么是编译程序 编译程序指:把某一种高级语言程序等价地转换成另一张低级语言程序(如汇编语言或机器代码)的程序. 高级语言程序-翻译->机器语言程序-运行->结果. 其中编译程 ...
- 20145213《Java程序设计学习笔记》第六周学习总结
20145213<Java程序设计学习笔记>第六周学习总结 说在前面的话 上篇博客中娄老师指出我因为数据结构基础薄弱,才导致对第九章内容浅尝遏止地认知.在这里我还要自我批评一下,其实我事后 ...
- javascript高级程序设计阅读笔记(一)
javascript高级程序设计阅读笔记(一) 工作之余开发些web应用作为兴趣,在交互方面需要掌握javascript和css.HTML5等技术,因此读书笔记是必要的. javascript简介 J ...
- 《c++程序设计》笔记
本文是学习谭浩强老师的<c++程序设计>后的笔记. 1.概述 c++是贝尔实验室在c语言的基础上发展而来,与c兼容.用c语言写的程序可以不加修改用于c++.从c++的名字可以看出它是c的超 ...
- 003-scanf函数使用和表达式-C语言笔记
003-scanf函数使用和表达式-C语言笔记 学习目标 1.[掌握]输入函数scanf的基本使用方法 2.[掌握]输入函数scanf运行原理和缓冲区理解 3.[掌握]算术运算符和算术表达式的使用 4 ...
- 操作系统和程序设计语言的API使用的字符编码分析
1.Java的运行环境中,String是什么编码? 使用java做程序设计语言,字符编码是和jvm相关的,和操作系统无关. java默认的编码是jvm在安装的时候就确定了的,它是根据你的系统的环境确 ...
- 扩展《C程序设计语言》练习2-3程序通用性
最近开始自学C语言,在看K&R的<C程序设计语言>.练习2-3要求写一个函数,将输入的十六进制数字字符串转换成与之等价的整数值,配套答案没有扩展程序的通用性,所以我就稍微改造改造. ...
随机推荐
- HDFS 数据错误与恢复
- LINUX用户身份切换
Su 命令作用 su的作用是变更为其它使用者的身份,超级用户除外,需要键入该使用者的密码. 使用方式 su [-fmp] [-c command] [-s shell] [--help] [--ver ...
- tensorflow中张量的理解
自己通过网上查询的有关张量的解释,稍作整理. TensorFlow用张量这种数据结构来表示所有的数据.你可以把一个张量想象成一个n维的数组或列表.一个张量有一个静态类型和动态类型的维数.张量可以在图中 ...
- k8s(openshift) 部署istio1.1
准备工作: openshift 默认不允许UID为0的容器运行,要先授权scc以便安装istio # oc adm policy add-scc-to-user anyuid -z istio-ing ...
- 洛谷P3298 泉
时空限制 1000ms / 128MB 题目描述 作为光荣的济南泉历史研究小组中的一员,铭铭收集了历史上x个不同年份时不同泉区的水流指数,这个指数是一个小于. 2^30的非负整数.第i个年份时六个泉区 ...
- js的剪贴板事件
定义 剪贴板操作包括剪切(cut).复制(copy)和粘贴(paste)这三个操作,快捷键分别是ctrl+x.ctrl+c.ctrl+v.当然也可以使用鼠标右键菜单进行操作 关于这3个操作共对应下列6 ...
- Java 基本数据类型 相互转换
int -> String String s=String.valueOf(12345); String -> int int i=Integer.parseInt("123&q ...
- NLog系列之NLong.config变量配置篇
$ {cached} - 将缓存应用于另一个布局输出. $ {db-null} - 为数据库渲染DbNull $ {exception} - 通过调用Logger方法之一提供的异常信息 $ {lev ...
- 百分比宽度并排元素浮动之后,设置margin,padding换行的问题
今天遇到一个问题, 如下图,右边的div加了内边距换行: 解决方法: box-sizing: border-box;
- jstree设置checkbox单选
jstree设置插件checkbox只允许单选 jstree version console.log($.jstree.version); 3.3.8 单选配置参数: $.jstree.default ...