c语言学习
数据类型
常量和变量
数值表示方法
整型变量的分类
字符常量
字符串常量
个数据类型的混合运算
强制类型转换
c语言左结合和右结合
局部变量和全局变量
预处理
指针
指针小结
结构体
枚举类型
类型定义符
位运算
位域(位段)
文件
数据类型
基本数据类型
构造数据类型
数组类型
结构体类型
联合类型
指针类型(存储地址)
空类型
常量和变量
常量和符号常量
#define N 30
整型常量
十进制:每天前缀
八进制:前缀0
十六进制:前缀为0X或0x
长整型数:后缀为“L”或“l”
无符号数:后缀为“U”或“u”
数值表示方法
原码:第一位表示符号位
补码
正数的补码和源码相同
负数的补码:将该数的绝对值的二进制形式按位取反再加一。
整型变量的分类
说明符 内存 表示范围
基本型 int 2字节 -32768-32767
短整型 short或int 2字节 -32768-32767
长整型 long或int 4字节 -2147483648~2147483647
无符号short型 unsigned short 2字节 0-65535
无符号int型 unsigned int 2字节 0-65535
无符号长整型 unsigned long 4字节 0~4294967295
单精度 float 4字节 3.4E-38 ~ 3.4E+38只能提供7位有效数字
双精度 double 8字节 1.7E-308 ~ 1.7E+308可提供16位有效数字
long double 16字节 1.2E-4932~1.2E4932
注意数据的溢出
实型常数不分单、双精度,都按双精度double型处理
字符常量
使用单引号
转义字符:使用“\”开头
C语言允许对整型变量赋以字符值,也允许对字符变量赋以整型值。在输出时,允许把字符变量按整型量输出,也允许把整型量按字符量输出
整型量为二字节量,字符量为单字节量,当整型量按字符型量处理时,只有低八位字节参与处理
字符串常量
由双引号括起来
c语言中没有相应的字符串变量
可以用字符数组来存储字符串
字符常量占一个字节的内存空间。字符串常量占的内存字节数等于字符串中字节数加1。增加的一个字节中存放字符"\0" (ASCII码为0)。这是字符串结束的标志。
个数据类型的混合运算
转换按数据长度增加的方向进行
所有的浮点运算都是以双精度进行的
char型和short型参与运算时,必须先转换成int型
赋值号右边量的类型将转换为左边量的类型
强制类型转换
(类型说明符) (表达式)
(float) a 把a转换为实型
(int)(x+y) 把x+y的结果转换为整型
c语言左结合和右结合
左结合就是如果连续两个同一优先级的运算符号挨着,那么相当于左边的一个加括号(比如 a + b + c 相当于 (a +b ) + c)
右结合就是如果连续两个同一优先级的运算符号挨着,那么相当于右边的一个加括号(a= b= c 这里相当于 a = (b=c))
局部变量和全局变量
局部变量:局部变量也称为内部变量。局部变量是在函数内作定义说明的。其作用域仅限于函数内, 离开该函数后再使用这种变量是非法的。
预处理
指针
指针:表示,优先级和++相同,结合性自右向左
指针运算符和指针变量说明中的指针说明符不是一回事。在指针变量说明中,“”是类型说明符,表示其后的变量是指针类型。而表达式中出现的“”则是一个运算符用以表示指针变量所指的变量。
把字符串的首地址赋予指向字符类型的指针变量:char pc=“C Language”;
空指针
设p为指针变量,则p==0表明p是空指针,它不指向任何变量
指针数组
下标法,即用a形式访问数组元素。在前面介绍数组时都是采用这种方法。
指针法,即采用(a+i)或(p+i)形式,用间接访问的方法来访问数组元素,其中a是数组名,p是指向数组的指针变量,其处值p=a。
p++,由于++和同优先级,结合方向自右而左,等价于*(p++)。
(*p)++表示p所指向的元素值加1。
指向***数组的指针变量
int (*p)[4]
它表示p是一个指针变量,它指向包含4个元素的一维数组。
应注意“(*指针变量名)”两边的括号不可少,如缺少括号则表示是指针数组(本章后面介绍),意义就完全不同了
函数指针变量
函数指针变量定义的一般形式为: 类型说明符 (*指针变量名)();
例如:int (*pf)();
指针数组的概念
指针数组说明的一般形式为: 类型说明符 *数组名[数组长度]
int *pa[3]:表示pa是一个指针数组,它有三个数组元素,每个元素值都是一个指针,指向整型变量
二维数组指针变量是单个的变量,其一般形式中"(*指针变量名)"两边的括号不可少。
int (*p)[3];
表示一个指向二维数组的指针变量。该二维数组的列数为3或分解为一维数组的长度为3。
main函数的参数
main (int argc,char *argv[])
argc参数表示了命令行中参数的个数
argv参数是字符串指针数组,其各元素值为命令行中各字符串(参数均按字符串处理)的首地址。指针数组的长度即为参数个数
指针小结
int i;定义整型变量i
int *pp为指向整型数据的指针变量
int a[n];定义整型数组a,它有n个元素
int *p[n];定义指针数组p,它由n个指向整型数据的指针元素组成
int (*p)[n];p为指向含n个元素的一维数组的指针变量
int f();f为带回整型函数值的函数
int *p();p为带回一个指针的函数,该指针指向整型数据
int (*p)();p为指向函数的指针,该函数返回一个整型值
int **p;P是一个指针变量,它指向一个指向整型数据的指针变量
指针运算的小结
现把全部指针运算列出如下:
指针变量加(减)一个整数:
例如:p++、p–、p+i、p-i、p+=i、p-=i
一个指针变量加(减)一个整数并不是简单地将原值加(减)一个整数,而是将该指针变量的原值(是一个地址)和它指向的变量所占用的内存单元字节数加(减)。
指针变量赋值:将一个变量的地址赋给一个指针变量。
p=&a; (将变量a的地址赋给p)
p=array; (将数组array的首地址赋给p)
p=&array; (将数组array第i个元素的地址赋给p)
p=max; (max为已定义的函数,将max的入口地址赋给p)
p1=p2; (p1和p2都是指针变量,将p2的值赋给p1)
注意:不能如下:
p=1000;
指针变量可以有空值,即该指针变量不指向任何变量:
p=NULL;
两个指针变量可以相减:如果两个指针变量指向同一个数组的元素,则两个指针变量值之差是两个指针之间的元素个数。
两个指针变量比较:如果两个指针变量指向同一个数组的元素,则两个指针变量可以进行比较。指向前面的元素的指针变量“小于” 指向后面的元素的指针变量。
10.8.3 void指针类型
ANSI新标准增加了一种“void”指针类型,即可以定义一个指针变量,但不指定它是指向哪一种类型数据。
结构体
结构体的定义
先定义结构,再说明结构变量。
如:
struct stu
{
int num;
char name[20];
char sex;
float score;
};
struct stu boy1,boy2;
在定义结构类型的同时说明结构变量。
例如:
struct stu
{
int num;
char name[20];
char sex;
float score;
}boy1,boy2;
直接说明结构变量。
例如:
struct
{
int num;
char name[20];
char sex;
float score;
}boy1,boy2;
结构数组的定义
struct stu
{
int num;
char *name;
char sex;
float score;
}boy[5];
指向结构变量的指针
struct 结构名 *结构指针变量名:struct stu *pstu;
(*pstu).num
pstu->num
指向结构数组的指针
动态存储分配
分配内存空间函数malloc
调用形式:(类型说明符*)malloc(size)
功能:在内存的动态存储区中分配一块长度为"size"字节的连续区域。函数的返回值为该区域的首地址。
例如:
pc=(char )malloc(100);
表示分配100个字节的内存空间,并强制转换为字符数组类型,函数的返 回值为指向该字符数组的指针,把该指针赋予指针变量pc。
分配内存空间函数 calloc
(类型说明符)calloc(n,size)
功能:在内存动态存储区中分配n块长度为“size”字节的连续区域。函数的返回值为该区域的首地址。
例如:
ps=(struet stu*)calloc(2,sizeof(struct stu));
其中的sizeof(struct stu)是求stu的结构长度。因此该语句的意思是:按stu的长度分
配2块连续区域,强制转换为stu类型,并把其首地址赋予指针变量ps。
释放内存空间函数free
调用形式: free(void*ptr);
功能:释放ptr所指向的一块内存空间,ptr是一个任意类型的指针变量,它指向被释放区域的首地址。被释放区应是由malloc或calloc函数所分配的区域。
枚举类型
enum 枚举名{ 枚举值表 };
enum weekday { sun,mon,tue,wed,thu,fri,sat } a,b,c;
a=sun;
b=mon;
c=tue;
d=(enum weekday)2;
只能把枚举值赋予枚举变量,不能把元素的数值直接赋予枚举变量
类型定义符
typedef 原类型名 新类型名
typedef char NAME[20];
表示NAME是字符数组类型,数组长度为20。
然后可用NAME 说明变量,如: NAME a1,a2,s1,s2;
完全等效于: char a1[20],a2[20],s1[20],s2[20]。
typedef struct stu
{ char name[20];
int age;
char sex;
} STU;
定义STU表示stu的结构类型,然后可用STU来说明结构变量
STU body1,body2;
位运算
& 按位与
| 按位或
^ 按位异或
~ 求反运算
<< 左移运算
右移运算
位域(位段)
所谓“位域”是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数
struct bs
{
int a:8;
int b:2;
int c:6;
};
一个位域必须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。
struct bs
{
unsigned a:4
unsigned :0 /空域/
unsigned b:4 /从下一单元开始存放/
unsigned c:4
}
文件
文件指针
FILE *指针变量标识符;
打开文件
文件指针名=fopen(文件名,使用文件方式);
例:fp=(“file a”,“r”);
fp=(“c:\hzk16”,“rb”);
在打开一个文件时,如果出错,fopen将返回一个空指针值NULL。
文件关闭
fclose(文件指针);
文件的读和写
读字符函数 :fgetc
fgetc函数的功能是从指定的文件中读一个字符
函数调用的形式为:字符变量=fgetc(文件指针)
使用fgetc 函数后,文件内部的位置指针将向后移动一个字节
字符写函数:fputc
fputc函数的功能是把一个字符写入指定的文件中
函数调用的形式为: fputc(字符量,文件指针);
写入成功则返回写入的字符,否则返回一个EOF
字符串读函数:fgets
fgets(字符数组名,n,文件指针);
字符串写函数:fputs
fputs(字符串,文件指针);
数据块读和写函数:fread和fwrite
fread(buffer,size,count,fp);
buffer 是一个指针,在fread函数中,它表示存放输入数据的首地址。在fwrite函数中,它表示存放输出数据的首地址。
size 表示数据块的字节数。
count 表示要读写的数据块块数。
fp 表示文件指针。
格式化读写函数:fscanf和fprinf
fscanf(文件指针,格式字符串,输入表列);
fscanf(fp,"%d%s",&i,s);
fprintf(文件指针,格式字符串,输出表列);
fprintf(fp,"%d%c",j,ch);
rewind
把文件内部的位置指针移到文件首。
fseek
fseek函数用来移动文件内部位置指针
fseek(文件指针,位移量,起始点);
文件检测函数
feof(文件指针):判断文件是否处于文件结束位置,如文件结束,则返回值为1,否则为0。
ferror(文件指针):检查文件在用各种输入输出函数进行读写时是否出错。如ferror返回值为0表示未出错,否则表示有错。