unsigned无符号正数
signed有符号
*有符号的二进制最高位作为符号位。
基本数据类型:
1,逻辑类型:只有两个量true和false,表示逻辑真值和逻辑假值。
2,整数类型:包括char, short, int和long。
3,浮点类型:包括float和double。
4,void类型:主要用于说明不返回值的函数或指向任一类型的指针等。
*正数的补码和原码相同。
*我们输入的都视为补码,当计算机输出时都会转换为原码输出!
bool类型
值域:非零(true),零(false、0)
bool
例如:
if ( -1 )
x=12 ;
else
x=18 ;
上面0.5是非零数值,逻辑值为真,所以x赋给的是12,而不是18。
注:
bool型必须有#include
_bool能够被识别,是基本数据类型,不需要头文件,但是如果代码中需要用true和false,需要加头文件定义。
使用char数据类型的变量需要特别注意,防止数据超出值域,思考下列几个语句:
char c1= 128; //出错,数据越界(-128)
char c1= 129; //出错,数据越界(-127)
unsigned char c2= -1; //出错,数据越界(255)
注:·一个字节长度:8位2进制数。
·有符号时:第一位1=负数,0=正数。
·规定-128的补码为:10000000
·强制数据类型的转换是指采用某种方式将某种数据类型强制转换成指定的数据类型。包括显式的数据类型转换,和隐式的数据类型转换。
例如,
int a=22, b=0 ;
float c = 24.87, d= 3.3;
b = (int) (a + c +d) ; // b为50
强制类型转换符后面的表达式如存在复杂运算,就一定要用小括号括起来
强制类型转换符是一种不安全的转换,一般都是将高级类型转换成低级类型,要丢失数据的精度;
强制类型转换并不改变表达式中变量的数据类型和其值。
#include
printf(“char:%d-%d\n”,SCHAR_MIN,S……具体查man手册
·常量是指在程序运行期间其数值不发生变化的数据。
·整型常量通常简称为整数。
·整数可以是十进制数、八进制数和十六进制数。
例如,十进制的数值3356可以有下列二种不同的表示形式:
八进制数 06434 ——以0开头的数。
十六进制数 0xd1c ——以0x开头的数。
一般不用二进制,二进制数是计算机运行的数据。
·浮点常量又称为实数,一般含有小数部分。
·在C语言中,实数只有十进制的实数。
·分为单精度和双精度。(了解)
单精度的数据类型是float
双精度的数据类型是double
单精度与双精度的区别是单精度的取值范围没有双精度的大(如图)
编译器默认的浮点类型是双精度
·实数有两种表示方法, 即一般形式和指数形式(科学计数法)。
一般形式的实数基本形式如下:[+|-]M.N
例如, 3.5 , -12.5, 3.1415926
·指数形式的实数一般是由尾数部分、字母e或E和指数部分组成。
·当一个实数的符号为正号时,可以省略不写,
其表示的一般形式如下:[+|-]M.N
1.176e+10 表示 1.176×1010
·字符常量是指一个单一字符, 其表示形式是由两个单引号包括的一个字符。
如:‘A’, ‘a’, ‘Q’, ‘0’, ‘9’, ‘+’, ‘:’, ‘?’, ‘$’
·在C语言中, 字符常量具有数值。字符常量的值就是该字符的ASCII码值。
*可以把字符常量看做一个字节的正整数。
例如,char a, b, u, v
a = ‘F’ ; // 将70送给a
b = ‘A’+2; // b存放的是 ‘C’ 字符
u = ’ ’ + ‘B’; // u存放的是 ‘b’ 字符
v= ‘b’ - 32; // v存放的是 ‘B’ 字符
它们分别相当于下列运算;
a= 70;
b= 65+2;
u= 32+66 ;
v= 97-32;
ASCII码常用值:
‘A’=65;
‘a’=97;
‘ ’=32;空格可以用来做大小写装换。即‘A’-‘a’=‘ ’=32;
所谓字符串常量是指用双引号括起来的一串字符来表示的数据。(字符串以\0结尾) “9”—‘9’,’\0’
下面给出几个字符串常量的例子:
“Hello!”, “StudentS”, “9”, “LINUX", “李四”
“北京海淀成府路XXX号", “姓名:”, “[email protected]", “”
·所谓标识常量是指用标识符代替常量使用的一种常量, 其名称通常是一个标识符。
·标识常量也叫符号常量,一般用大写英文字母的标识符。
·在使用之前必须预先定义。
说明形式为:
#define <标识常量名称> <常量>
如:
#define MAX 50
#define PI 3.1415926
#define NULL 0
#define EOF -1
#define ERROR -1
其中,MAX、PI、NULL、 EOF和ERROR都是标识常量, 它们代替的常量分别是50、3.1415926、0 、-1和-1 。
一般情况,每个标识常量说明式子只能给出一个标识常量,并且占据一个书写行。
定义一个宏名字之后,可以在其他宏定义中使用,例如:
#define ONE 1
#define TWO ONE+ONE
#define THREE ONE+TWO
如果一个串长于一行,可在行尾用反斜线“\”续行
#define LONG_STRING “This is a very very long \
String that is used as an example”
一个水分子的质量约为3.0*10-23g,1夸脱水大约有950g,编写一个程序,要求输入水的夸脱数,然后显示这么多水中包含多少水分子。
~/practice/level1/day2/constant/water.c
在软件开发过程中,经常有一些常用或者通用的功能或者代码段,封装成为宏定义
#define MAX( a, b) ( (a) > (b) ? (a) : (b) )
int max( int a, int b)
{
return (a > b a : b)
}
swap(x,y)交换函数
#define swap(x, y)\
x = x + y;\
y = x - y;\
x = x - y;
有一些任务根本无法用函数实现,但是用宏定义却很好实现。
比如参数类型没法作为参数传递给函数,但是可以把参数类型传递给带参的宏。
#define MALLOC(n, type) \
( (type *) malloc((n)* sizeof(type)))
宏可以增加程序的长度,如果相同的代码需要出现在程序的几个地方,更好的方法是把它实现为一个函数
也就是说定义一个宏,用宏定义的常量标识完全替代全文出现的常量。
==注意:完全替代在程序中容易出现bug,最好使用括号杜绝问题产生。 ==
1,变量在程序中用变量名表示。变量名由用户根据其用途任意命名。
2,变量名由字母、数字、下划线组成,不能以数字开头,不能和C的关键字重名。
3,在程序运行时,变量占据存储空间的大小由其数据类型决定。
4,变量在内存空间中的首地址,称为变量的地址。
变量在程序中使用时,必须预先说明它们的存储类型和数据类型。
变量说明的一般形式是:
<存储类型> <数据类型 > <变量名> ;
<存储类型>是关键词auto、register、static和extern
<数据类型>可以是基本数据类型,也可以是自定义的数据类型
auto说明的变量只能在某个程序范围内使用(局部),通常在函数体内或函数中的复合语句里。(默认是随机值)
在函数体的某程序段内说明auto存储类型的变量时可以省略关键字auto,如下:
auto int k ;
int j ;
double x;
register称为寄存器型,register变量是想将变量放入CPU的寄存器中,这样可以加快程序的运行速度。
如申请不到就使用一般内存,同auto ;(申请不到:大小超出等)
register变量必须是能被CPU所接受的类型。这通常意味着register变量必须是一个单个的值,并且长度应该小于或者等于整型的长度。
*不能用“&”来获取register变量的地址。
由于寄存器的数量有限,真正起作用的register修饰符的数目和类型都依赖于运行程序的机器。
在某些情况下,把变量保存在寄存器中反而会降低程序的运行速度。因为被占用的寄存器不能再用于其它目的;或者变量被使用的次数不够多,不足以装入和存储变量所带来的额外开销。
static变量称为静态存储类型的变量,既可以在函数体内,也可在函数体外说明。(默认是0)
局部变量使用static修饰,有以下特点:
在内存中以固定地址存放的,而不是以堆栈方式存放
只要程序没结束,就不会随着说明它的程序段的结束而消失,它下次再调用该函数,该存储类型的变量不再重新说明,而且还保留上次调用存入的数值。
局部变量使用static修饰的特点:
1,在内存中以固定地址存放的,而不是堆栈方式(堆栈:自己分配自己回收)存放。
2,只要程序没结束,就不会随着说明它的程序段的结束而消失,它下次再调用该函数,该存储类型的变量不再重新说明,而且还保留上一次调用存入的数值。
即:·循环时累加上一次的
·存储时间变长了。(程序段结束时因程序没有结束,不会消失)
当变量在一个文件中的函数体外说明,所有其他文件中的函数或程序段都可引用这个变量。
extern称为外部参照引用型,使用extern说明的变量是想引用在其它文件中函数体外部说明的变量。
static修饰的全部变量,其它文件无法使用
如:exturn int global_a;
这里说明 int global_a是别的文件中的。
因此编译时:gcc file1 file2 才可以。即加上exturn说引用的file名称才可以
表示一个变量也许会被后台程序改变,关键字 volatile 是与 const 绝对对立的。它指示一个变量也许会被某种方式修改,这种方式按照正常程序流程分析是无法预知的(例如,一个变量也许会被一个中断服务程序所修改)。
变量如果加了 volatile 修饰,则会从内存重新装载内容,而不是直接从寄存器拷贝内容。
volatile 的作用 是作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值。
volatile应用比较多的场合,在中断服务程序和cpu相关寄存器的定义。
C提供的算术运算符:+,-,*,/,%,++,如下:float/double不能取余
例如,
——~/practice/level1/day2/ope/demo.c
int a=15, b=8,c;
double x=15, y=8, z;
c = a + b ; c = a – b; c = a * b; c = a / b; // c 赋值为
c = a % b; // c 赋值为
z = x + y ; //z 赋值为
z = x - y; // z 赋值为
z = x * y ; // z 赋值为
z = x / y ; // z 赋值为
z = x % y ;
例如, ——~/practice/level1/day2/ope/demo2.c
== 注:不可以试用(a+b)++,但是可以将a+b赋值为c。
也就是:c=a+b; d=c++这样就可以。==
int a=5, b=6;
a>(b-1) 结果值为0
(a +1)== b 结果值为1
a>=(b-2) 结果值为1
a<100 结果值为1
(a+3)<=b 结果值为0
a != (b-1) 结果值为0
逻辑非“!”运算符的运算律如下:
例如,——~/practice/level1/day2/ope/demo3.c
int k=8;
! ( k ==0) 结果值为1
! ((k-8) == 0) 结果值为0
! (k<= 0) 结果值为1
逻辑或“||”运算符的运算规律如下:短路-逢1截止
例如 ——~/practice/level1/day2/ope/demo4.c
int x=5, y=18;
(x>=5) && (y<20) 结果值为1
((x+1)>=0) && (y<17) 结果值为0
((x-8)>=0) && (y==18) 结果值为0
((x-5)>0) && (y!=18) 结果值为0
((x>=5)) || (y<20) 结果值为1
((x+1)>=0) || (y<17) 结果值为1
((x-8)>=0) || (y==18) 结果值为1
((x-5)>0) || (y!=8) 结果值为1
C语言的位运算符如下:
例如: ——~/practice/level1/day2/ope/bit.c
unsigned char x=0x17, y;
y = ~x;
unsigned char无符号字符型只占1个字节,最小。
0x17=00010111
y=1110 1000=0xE8
printf("%#x\n",y)----#表示自动增加0x前缀
位逻辑与“&”运算符的运算规律如下:
例如, ——~/practice/level1/day2/ope/bit1.c
unsigned char x=0126, y=0xac, z;
z = x & y;
0126 (八进制) = 01 010 110 - 0 1 0 1 0 1 1 0
0xac(十六进制)=1010 1100 - 1 0 1 0 1 1 0 0
位逻辑或“|”运算符的运算规律如下:
例如: ——~/practice/level1/day2/ope/bit2.c
unsigned char x=076, y=0x89, z;
z = x | y;
位逻辑异或“^”运算符的运算规律如下:
例如: ——~/practice/level1/day2/ope/bit3.c
unsigned char x=75, y=0173, z;
z = x ^ y ;
位移位运算的一般形式:
<运算量> <运算符> <表达式>
其中:
<运算量> 必须为整型结果数值;
<运算符>为左移位(<<)或 右移位(>>)运算符;
<表达式> 也必须为整型结果数值。
<
例如: ——~/practice/level1/day2/ope/bit4.c
unsigned char a=0xe4, b;
b=a<<3;
赋值运算符为“=”,其运算的一般形式如下:
<左值表达式> = <右值表达式>
赋值复合运算符其运算的一般形式如下:
<变量> <操作符>= <表达式>
C语言的赋值复合运算符如下:
案例:——~/practice/level1/day2/ope/ass.c
#include
int main(int argc, char **argv)
{
int count, sum;
count = 0; sum = 0;
while (count++ < 20) { sum +=count; }
printf("sum = %d\n", sum);
return 0;
}
是三目运算符, 其运算的一般形式是:
<表达式1> ? <表达式2> : <表达式3>
例如: ——~/practice/level1/day2/ope/ass1.c
int x=82, y=101;
x >= y ? x+18 : y-100 //运算结果为1
x < (y-11) ? x-22 : y-1 //运算结果为60
int main()
{ int x, y=25;
x=70;
y= x++ > 70 ? 100 : 0 ;
printf(“x=%d y=%d”, x, y);
return 0;
}
运行结果: x=71 y=0↙
从左往右运算,且最终输出值有最右边的表达式结果。
左边进,右边出。
——~/practice/level1/day2/ope/ass2.c
float x=10.5, y=1.8, z=0;
z = (x+=5, y = x+0.2) ;
z = (x=y=5, x +=1) ;
z = (x=5, y=6, x+y ) ;
z = (z=8, x=5, y=3) ;
sizeof运算符
运算的一般形式:sizeof(<类型或变量名>)
注意:它只针对数据类型,而不针对变量!
例如:
sizeof(double)
sizeof(long)
……
简单记忆:单算关逻条赋逗
例如: ——~/practice/level1/day2/ope/pir.c
int x=1, y=0, z=0;
x++ && y++ || ++z //结果为 1 (2 1 1)
! (x+1>0) && y++ || ++z //结果为 1 (1 0 1)
x += y==z, y=x+2, z=x+y+x >0//x为2,y为4 ,z为1
x++ && y++ || ++z //结果为 1 (2 1 1)
先算&&,再算||
1 && 0 || 1
1 && 1
1)
! (x+1>0) && y++ || ++z //结果为 1 (1 0 1)
x += y==z, y=x+2, z=x+y+x >0//x为2,y为4 ,z为1
x += y==z, y=x+2,( z=(x+y+x >0))>优先于=优先于,
y==z 成立,所以x+=1 为2.
y=2+2=4
x+y+x=2+4+2=8 8>0 成立 为1.所以z=1