C语言
2020-06-01 17:07:36 3 举报
AI智能生成
谭浩强 c程序设计第四版的框架图,自己画的,用于考研
作者其他创作
大纲/内容
第六章 数组
一维数组
定义
类型符 数组名[常量表达式]
int a[10]
int a[10]
数组命名规则和变量命名一致
定义数组时,必须要指定数组长度,下标从0开始,
即长度为10的数组取不到a[10]
即长度为10的数组取不到a[10]
数组名的常量表达式可以是常量和符号常量
如a[5+3]是正确的,但是a[n]是错误de
如a[5+3]是正确的,但是a[n]是错误de
引用
数组名[下标]
初始化
定义数组时对全部数组元素赋值
int a[3]={1,2,3};
只给一部分赋值
int a[3]={1};
当赋值的元素少于数组总体元素的时候,剩余的元素自动初始化为 0:
对于short、int、long,就是整数 0;
对于char,就是字符 '\0';
对于float、double,就是小数 0.0。
对于指针类型为NULL
对于short、int、long,就是整数 0;
对于char,就是字符 '\0';
对于float、double,就是小数 0.0。
对于指针类型为NULL
如果想使一个数组的元素全部为0
int a[3]={0,0,0}
int a[3]={0}
可以不指定数据个数
int a[]={0,0,0}
二维数组
定义
类型 数组名[常量表达式][常量表达式]
引用
数组名[下标][下标]
下标值不能超出数组定义长度
初始化
分行给二维数组赋值
int a[2][3]={{1,2,3},{1,2,3}}
可以把所有的数据全部写入到一个花括号内
int a[2][3]={1,2,3,1,2,3}
可以对部分元素赋值
只对一列赋值
int a[2][3]={{1},{1}}
对各行中的某个元素赋值
int a[2][3]={{1},{0,0,3}}
效果:
1 0 0
0 0 3
效果:
1 0 0
0 0 3
可以对某一行赋值,其余保留初值
int a[3][3]={{3},{4,6}};//只对一二行赋值
int a[3][3]={{3},{},{4,6}};//只对一三行赋值,空出第二行
如果对全部元素都赋值时,一维长度可以省略,
但是二维长度不能省
但是二维长度不能省
int a[][3]={1,2,3,1,2,3}
int a[][3]={{3},{},{4,6}};//只对一三行赋值,空出第二行
字符数组
定义
char c[10];(与数组类似)
初始化
定长
char c[4]={'g' , '' , 'g' , ''},
不定长
char c[]={'g' , '' , 'g' , 'a'},
空出的部分,用‘\0’填充
引用其中的元素
c[下标]得到一个字符
字符串及其结束符
结束符
以字符‘\0’作为结束符
‘\0’代表ASCII码的0
‘\0’代表ASCII码的0
c系统用字符串数组存储字符串常量时
会自动加一个‘\0’。
(凡是字符串,系统都会在后面加,为了结束标志)
会自动加一个‘\0’。
(凡是字符串,系统都会在后面加,为了结束标志)
“c program”共有9个字符,放到一维数组中则占10个字符
字符串
初始化
使用字符串常量
char c[] ={"i am ok"};
char c[] ="i am ok";
char c[] ="i am ok";
逐个初始化
char c[3] = {'c','h','i'} //无结束符
char c[4] = {'c','h','i'}//有结束符
char c[] = {'c','h','i'}//有结束符
char c[4] = {'c','h','i'}//有结束符
char c[] = {'c','h','i'}//有结束符
注意
第一种赋值,一定有“\0”结尾,而第二个没有。
因为是否有“\0”结尾完全是看个人需要,
你想要那么你就在初始化的时候,
长度不写,或是留多一个位置,他会自己有结束符
因为是否有“\0”结尾完全是看个人需要,
你想要那么你就在初始化的时候,
长度不写,或是留多一个位置,他会自己有结束符
输入输出
逐个字符输入输出
用格式符%c
一次性输入输出
用格式符%s
说明
输出字符中不包含"\0"
用%s输出字符串时,使用的是数组名
printf("%s",s);而不是printf("%s",s[0]);
输出过程中,遇"\0"结束,
如果字符串数组中包含一个以上的"\0",
遇到第一个"\0"则结束输出
遇到第一个"\0"则结束输出
scanf可以接收一个字符串
scanf("%s",s);
scanf中输入项的s是已定义的字符数组名,
输入字符串应短于已定义的字符数组长度
输入字符串应短于已定义的字符数组长度
scanf输入项中的数组名不能加&,
因为C语言中数组就已经表示数组的地址
因为C语言中数组就已经表示数组的地址
C语言是不会检查越界行为的,这个需要自己控制。
因此你输入的字符串长度超出了你定义的字符数组长度
不会报错,还是会输出你输入的字符串,不管怎么样,
得遵守输入字符串长度小于数组长度
因此你输入的字符串长度超出了你定义的字符数组长度
不会报错,还是会输出你输入的字符串,不管怎么样,
得遵守输入字符串长度小于数组长度
输出字符串的过程
按字符串名s找到数组的起始位置,
然后逐个输出其中的字符,直到遇到"\0"为止
然后逐个输出其中的字符,直到遇到"\0"为止
字符串处理函数
puts输出字符串函数
puts(字符数组名);//是数组名,只能写一个,不能用逗号并列
puts与printf("%s")区别
puts输出时将字符串标志‘\0’转换成“\n”再输出
gets输入字符串函数
gets(字符数组);//数组名,只能写一个,不能用逗号并列
gets与scanf("%s")区别
scanf不能接受空格、制表符Tab、回车等;
而gets能够接受空格、制表符Tab和回车等;
而gets能够接受空格、制表符Tab和回车等;
scanf :当遇到回车,空格和tab键会自动在字符串后面添加’\0’,
但是回车,空格和tab键仍会留在输入的缓冲区中。
gets:可接受回车键之前输入的所有字符,
并用’\0’替代 ‘\n’.回车键不会留在输入缓冲区中
但是回车,空格和tab键仍会留在输入的缓冲区中。
gets:可接受回车键之前输入的所有字符,
并用’\0’替代 ‘\n’.回车键不会留在输入缓冲区中
scanf结束于空格,gets结束于回车
strcat字符串连接函数
strcat(字符数组1,字符数组2)
将字符串2拼接到字符串1后面
字符串数组1必须足够大,方便容纳新字符串,
假如定义str1[]="da2sd";就会出问题,长度不够
假如定义str1[]="da2sd";就会出问题,长度不够
连接前,两个字符串的后面都有“\0”,
连接时把字符串1后的“\0”取消,保留第二个的
连接时把字符串1后的“\0”取消,保留第二个的
strcpy,strncpy字符串复制函数
strcpy(字符数组1,字符数组2)
把字符串2复制到字符串数组1中去
字符串数组1的长度不应该小于字符串2的长度
将 str2 复制到 str1 后,str1 中原来的内容就被覆盖了,
尽管str2的长度比str1小很多
尽管str2的长度比str1小很多
strncpy(str1,str2,2)
将字符串中的前2个字符复制到str1中,
取代str1中原有的最前面的2个字符
取代str1中原有的最前面的2个字符
复制的长度不应该大于str1中原有的字符(不包括“\0”)
strcmp字符串比较函数
strcmp(字符串1,字符串2)
比较规则
将两个字符串自左向右逐个字符比较(按照ASCII码大小比较),
直到出现不同的字符或遇到“\0”
直到出现不同的字符或遇到“\0”
结果
str1=str2,函数返回0
str1>str2,函数返回正整数
str1<str2,函数返回负整数
str1>str2,函数返回正整数
str1<str2,函数返回负整数
strlen检测字符串长度函数
strlen(str)
返回字符串数组中元素个数(字符串实际长度),不包含"\0"
sizeof
用 sizeof 可以获得数据类型或变量在内存中所占的字节数
sizeof(a)/sizeof(a[0]) 都能自动求出数组的长度,
注意:数组的长度不等同于数组中元素个数
注意:数组的长度不等同于数组中元素个数
strlwr转小写函数
strlwr(str)
将字符串中的大写字母全部转为小写
strupr转大写函数
strupr(str)
将字符串中的小写字母全部转为大写
使用以上函数时,一定要县引入#include <string.h>
第七章 函数
概念
分类
无参函数
带参函数
库函数
自定义函数
注意
一个c程序由一个或多个程序模块组成,
一个源程序文件可以为多个C程序共用
一个源程序文件可以为多个C程序共用
一个源程序由一个或多个函数及其他有关内容组成
一个源程序文件是一个编译单位,
最小功能单位是函数.
最小编译单位是文件.
一个源程序文件是一个编译单位,
最小功能单位是函数.
最小编译单位是文件.
C程序的执行由main函数开始,结束于main
所有函数都是平行的,因此不能嵌套定义。
函数间可以相互定义,但是不能调用main函数
定义
语法形式
空函数
没有函数体,什么工作都不做
调用
语法形式
调用时参数传递
系统把实参的传递给被调用函数
实参可以是表达式,变量,常量,要有值
实参与形参的类型应该相同或赋值兼容,
就是实参的值可以强转为形参的类型
就是实参的值可以强转为形参的类型
调用过程
实参向形参的数据传递是“值传递”,单向传递
只能由实参传向形参,不能由实参传向形参
只能由实参传向形参,不能由实参传向形参
函数的返回值
函数的返回值在return中获得
返回值的类型应该与函数类型一致
void函数不需要用return,递归也是
被调用的函数声明
方式
递归
递归前输出,顺序输出
递归后输出,逆序输出
递归后输出,逆序输出
出口,递归体,递归条件可变
f+=f(a--,b--);
return f;
与
return f(a--,b--);
return f;
与
return f(a--,b--);
数组作为函数参数
数组元素做参数
值传递,单向,不改变值
数组名做参数
指针,地址传递,数组的首元素地址,会改变函数的值
形参与实参占同一段内存单元
局部变量与全局变量
函数内定义是局部变量,函数外定义时全局变量
局部变量局部有用,全局变量全局有用
变量存储方式以及生存期
存储方式
auto自动变量
函数调用完释放
static静态变量
分配存储单元
只赋值一次
程序运行间都不释放
不赋值会自动赋值
静态的局部变量,其他函数访问不了
生存期
一对{}一片天,{}外不是你的天
第八章 指针
定义
地址的形象化
通过地址找到变量
变量的间接访问方式
一个变量的地址就是该变量的指针
指针变量的值是地址
指针变量
定义
类型名 * 指针变量
int *p =3 ;
指针的定义必须含有基类型
说明
指针变量是是基本数据类型派生出来的类型,
他不能开基本数据类型,也就是意味着在指针的
定义中不能离开基类型
他不能开基本数据类型,也就是意味着在指针的
定义中不能离开基类型
指针变量是前面的*,表示该变量的类型的指针型变量。
如int *point 其中指针型变量的名字是point,而不是*point
如int *point 其中指针型变量的名字是point,而不是*point
一个变量指针的含义
存储单元编号表示的地址
指向存储单元的数据类型(int,float)
如何表示一个指针变量
指向整型数据的指针类型表示为int *,读作指向int的指针或是int指针
注意
指针变量中只能存放地址(指针),不要讲一个整数赋给一个指针变量
赋值
p = &a;
引用指针变量指向的变量
printf("%d",*p)
引用指针变量的值
printf("%d",p)
两个相关的运算符
&:取地址运算符。(得到某变量的地址)&a是变量a的地址
*:指针运算符或“间接访问”运算符(得到某个地址的内容)
*&j
这个*其实也是取地址的内容
&j得到j的地址
*取该地址里面的内容
*&是一对反作用的运算符在一起的时候相当于两个都没有
相当于j
这个*其实也是取地址的内容
&j得到j的地址
*取该地址里面的内容
*&是一对反作用的运算符在一起的时候相当于两个都没有
相当于j
指针变量作为函数参数
讲一个变量的地址传送到一个函数中
指针引用数组
数组元素的指针
数组元素的指针
数组名不代表整个数组,只是代表这个数组首元素的地址
p=s的作用时把a数组的首元素的地址赋给指针变量p,而不是
把a中的所有元素的值赋给p
p=s的作用时把a数组的首元素的地址赋给指针变量p,而不是
把a中的所有元素的值赋给p
数组中的指针运算
运算
p+1,p-1
p+1指向同一个数组元素中的下一个元素
p-1指向同一个数组元素中的上一个元素
p-1指向同一个数组元素中的上一个元素
p+i与&a[0]
如果p的初值为&a[0],则p+i与a+i就是数组a[i]地址
*(p+i)与*(a+i)
p+i和a+i所指向的数组元素,即a[i]
*(p+5),*(a+5),a[5]三者等同
*(p+5),*(a+5),a[5]三者等同
p1-p2
结果是p1与p2的地址之差除以数组元素的长度
就是表示p1和p2之间相差的元素个数
就是表示p1和p2之间相差的元素个数
p1+p2
两个地址不能相加,无无意义
p++;*p;
p++使p指向下一个元素a[1],然后执行*p时就会得到下一个元素a[1]
a++
a为数组名,错误使用方法
*p++
由于++和*是同一个优先级,结合方式从右到左,
因此等价于*(p++),先引用p的值,实现*p的运算,然后再使p自增1
得到a[0]
因此等价于*(p++),先引用p的值,实现*p的运算,然后再使p自增1
得到a[0]
*(p++)与*(++p)
前者先去*p值,然后使p加1,相当于a[i++],得到a[0]的值
后者是先使p加1,再去*p,相当于a[++i],得到a[1]的值
*(p--)与*(--p)
同上
(*p)++与++(*p)
前者是表示p所指的元素值+1,相当于++a[0],a[0]=a[0]+1;
后者先得到(*p)的元素,再+1,相当于a[0]++
类似于a++与++a的关系
引用多维数组
运算
注意
二维数组名(如a)指的是a的行元素
通过指针引用数组元素
下标法
如a[i]形式
指针法
如*(p+i)或*(a+i)
指向由m个元素组成的一维数组的指针变量
区分
int(*p)[4];包含四个整型变量的一维数组
int a[4];a有四个元素,每一个元素都是整形变量
int *p[4];指针数组,
[]的优先级大于*,[]先与p结合,再与*结合
[]的优先级大于*,[]先与p结合,再与*结合
*(*(p+2)+3); 得到a[2][3]的地址
关于数组的指针作为函数参数
f(float *p,int n);//定义
f(*score,12);//调用
f(*score,12);//调用
p是float *类型(指向float类型的指针),实参用*score,
即score[0],&score[0][0],score[0][0]
即score[0],&score[0][0],score[0][0]
f(float (*p)[4], int n);//定义
f(score,12);//调用
f(score,12);//调用
p的类型是float*[4],它不是指向整型变量,而是指向一维数组,
将实参score的值(代表数组0行开始的地址)
将实参score的值(代表数组0行开始的地址)
注意
实参与形参是指针类型,应当注意她们的类型必须一致。
不应把int*(指向元素地址) 传给int (*)[4]型(指向一维数组)
不应把int*(指向元素地址) 传给int (*)[4]型(指向一维数组)
指针引用字符串
引用
char *s=“im smd0”;等价于
char *s;s=“im smd0”;
char *s;s=“im smd0”;
注意
string被定义为指针变量,基类为字符型
它只能指向一个字符串类型数据,不能指向多个字符数据,
更不能把常量字符串存放与s中,指针只能存放地址,
也不是把字符串赋给*string
(就是*string只能指向地址,string可以指向同类型字符串)
更不能把常量字符串存放与s中,指针只能存放地址,
也不是把字符串赋给*string
(就是*string只能指向地址,string可以指向同类型字符串)
进一步解读:
你可以指向其他的字符串变量以达到修改的需求(相当于改地址),
但是你不能用新的常量去直接赋值或替换,
因为*p指向的是地址,不接受任何变量和常量
本质就是定义的常量不允许修改
你可以指向其他的字符串变量以达到修改的需求(相当于改地址),
但是你不能用新的常量去直接赋值或替换,
因为*p指向的是地址,不接受任何变量和常量
本质就是定义的常量不允许修改
字符串指针作参数
函数的形参和实参可以分别用字符数组名或字符串变量
指向函数的指针
用来存放某一函数的起始地址
int (*p)(int,int)表示
注意
定义的函数指针变量,并不意味这个指针变量可以指向任何函数,
他只能指向在定义时指定的类型的函数
他只能指向在定义时指定的类型的函数
对指向函数的指针不能进行算术运算
再给函数指针变量赋值时,只需给出函数名,不用给出参数
p=max而不是p=max(a,b)
p=max而不是p=max(a,b)
用函数数指针调用函数时,只需用(*p)代替函数名即可,在(*p)后添加参数列表
c=(*p)(a,b)
c=(*p)(a,b)
指针函数可以用作一个函数的参数传递
就好像回调函数
就好像回调函数
返回指针值的函数
类型名 *函数名(参数列表)
int *returnIntPointFun(int a){}
int *returnIntPointFun(int a){}
指针数组和多重指针
类型名 *数组名[数组长度]
多重指针
解析
代码
动态分配指针内存
malloc
分配一个长度为size的连续空间
void *malloc(int size)
void *malloc(int size)
calloc
内存的动态存储区分配n个长度为size空间
calloc(int n,int size)
calloc(int n,int size)
free
释放指针的空间
free(p)
free(p)
realloc
重新分配空间
realloc(p,50)
realloc(p,50)
小结
第九章自定义数据类型
定义和使用结构体
形式
注意
结构体类型的名字是由struct+结构体名字组成的
A结构体可以成为B结构体的成员
定义
先声明结构体类型,再定义其他类型的变量名
在声明类型的同时定义变量
区别
结构体类型
结构体变量
初始化和引用
定义结构体时,对它的成员初始化
定义结构体后,引用赋值
结构体中包含着另外的结构体,赋值
同类的结构体变量可以相互赋值
可以引用结构体的成员的地址
结构体变量的地址主要用于函数参数,传递结构体变量地址
结构体数组
定义形式
例子
初始化
在定义过程中初始化
定义后初始化
访问变量值
获取
修改
结构体指针
定义形式
定义结构体时指向
定义结束后指向
不能写成struct stu *pstu = stu1;
因为结构体指针是地址,要加&
因为结构体指针是地址,要加&
如果p指向结构体变量stu,以下等价
stu.成员名
(*p).成员名
p->成员名
注意
如果p的初值指向stu,即stu的第一个元素,
那么p+1则指向他的下一个元素
那么p+1则指向他的下一个元素
程序定义struct Student类型对象的指针变量,
不应用来指向stu的成员变量
如:p=stu[1].name是错误的
p=(struct Student*)stu[0].name则是对的
再执行p+1则得到下一个成员的name
不应用来指向stu的成员变量
如:p=stu[1].name是错误的
p=(struct Student*)stu[0].name则是对的
再执行p+1则得到下一个成员的name
用指针处理链表
具体参见数据结构的顺序表
共用体类型
几个不同的变量共享一段内存的结构
注意
结构体与共用体形式相似,但是意义不同。
1.结构体内存是各个成员大小之和,共用体则是最大那个
1.结构体内存是各个成员大小之和,共用体则是最大那个
但每次只能赋一种值, 赋入新值则冲去旧值。
出现你这种情况的原因可能是:int占4位,float占4位,char占1位,当赋值float后int的就完全更改了,当赋值char的时候,其实float的值也是更改了的,但是char因为占的位少,可能只改变了float的低位空间,也就是小数点后很多位的值,这样输出来的时候因为float就显示小数点后的几位,很后面的就被约为0了,所以结果没有变
出现你这种情况的原因可能是:int占4位,float占4位,char占1位,当赋值float后int的就完全更改了,当赋值char的时候,其实float的值也是更改了的,但是char因为占的位少,可能只改变了float的低位空间,也就是小数点后很多位的值,这样输出来的时候因为float就显示小数点后的几位,很后面的就被约为0了,所以结果没有变
特点
在一瞬间只能存放一个成员
可以初始化,但是初始化表只有一个常量
共用体的成员是最后一次赋值的成员
共用体变量地址和各成员地址一样
不能对共用体变量名赋值,应该是对其成员,取值也一样
枚举类型
如果一个变量是几种可能的值,可以定义为枚举
不能对枚举元素赋值,它为常量
每个枚举变量代表一个数字,默认从0开始
workday =mon,等同于workday=1
workday =mon,等同于workday=1
可以显式地定义数值
typeof声明新类型名
用一个新的类型名代替原有的类型名,
不创造新类型
不创造新类型
第一章 程序设计和C语言
计算机程序
一组计算机可以识别和执行的指令
计算机语言
二进制,01组成的计算机指令集合
c语言特点
c语言程序
注释
单行
多行
c语言结构
一个程序由一个或
多个源程序文件组成
多个源程序文件组成
预处理指令
#include
全局声明
函数外都是全局声明
函数定义
子主题
函数是c的主要组成部分
一个函数包含两部分
函数头
函数类型,函数名,参数类型,参数名
函数体
声明部分,执行部分
程序总是从main函数开始执行
程序中对计算机的操作是由函数中的c语句完成的
在每个数据声明和语句的最后必须有一个分号
C语言本身不提供输入输出语句,
但是可以引用库中的输入输出函数
但是可以引用库中的输入输出函数
程序应该包含注释
c程序运行
输入编辑源程序》》对源程序进行编译,得到二进制目标文件.obj
》》连接处理,得到可执行程序.exe》》运行
》》连接处理,得到可执行程序.exe》》运行
第二章 算法--程序的灵魂
程序=算法+数据结构
算法
解决一个问题所采用的方法和步骤
简单的算法举例
算法的特征
有穷
确定
有0个或多个输入
有一个或多个输出
有效性
算法表示
自然语言
流程图
N-S流程图
伪代码
计算机语言
C语言
三大基本程序结构
顺序结构
选择结构
if
switch
循环结构
当型while
直到型do...while
第三章 顺序程序设计
数据的表现形式以及运算
常量与变量
常量
整型常量
1000,-235
实型常量
十进制小数形式
123.456
指数形式
-346.58e-25(1346.58^-25)
字符常量
普通字符
‘a,‘b’
转义字符
‘\t', '\n’
字符串常量
“boy”,“123”
符号常量
#define PI 3.14 //注意行末没有分号
变量
先定义,再使用
int a=3;//a为变量
常变量
const int a=3;
标识符
一个对象的名字
合法标识符
只能是字母,数字,下划线组成
第一个字母只能为下划线或字母
sum,_sum
数据类型
整型
基本类型(int)
Turbo C 2.0分配2个字节(16位二进制)
Visual C++分配4个字节(32位)
范围-32768~32767,超出范围会溢出,输出结果显示不正确
短整型(short int)
short or short int
2字节,范围-32768~32767
长整型(long int)
long int or long
-2^31~2^31-1
4字节
双长整型(long long int)
long long int / long long
8字节
大小比较
sizeof(short)<sizeof(int)<sizeof(long)<sizeof(long long)
整型变量的符号属性
字符型数据
字符与字符代码
字母
数字
专门符号29个
空格符
字符变量
char c = '?';
printf(“%c”,c);
printf(“%c”,c);
字符类型也属于整型,可以使用signed(0-255)和unsigned(-128-127)
signed和unsigned都不加的变量按照signed处理(Visual C++情况)
char c = 255; //出现警告,输出-1
unsigned char c = 255; //不出现警告,输出255
unsigned char c = 255; //不出现警告,输出255
浮点数据类型
float型(单精度浮点型)
4字节,6位有效数字
double(双精度浮点型)
8个字节,15位有效数字
long double(长双精度浮点型)
16个字节,19位有效数字
8个字节
15位有效数字
常量类型确定
整数
界限:32767 | 2147483647
浮点型常量
float对于3.14159会发出警告,要求用double
运算符与表达式
基本运算符
使用“/”会直接去除小数部分,采用“向0取整”
如-5/3=-1
如-5/3=-1
% 的右边必须为整数
自加与自减
++i:先运算,后使用
i++:先使用,再运算
自增和自减只能用于变量,不能用于常量或表达式
如5++,++(a+b)均为错误
如5++,++(a+b)均为错误
表达式和运算符的优先级和结合性
数字运算一致
不同类型的混合运算
+-*/运算的两个数中一个数为float或double,
结果都为double,float转为double再运算
结果都为double,float转为double再运算
如果,int double,float运算,int和double都会转化成double再运算
字符(char)会根据ASSII码转换成int 再运算
总结:一切看大哥的
强制转化
形式
(类型名)(表达式)
(int)x+y,先把x转为int,再与y相加
c运算符
子主题
c语句
分类
控制语句*9
调用语句
一个函数+一个分号
printf("000");
表达式语句
表达式+分号
i=+1;
有分号--语句
无分号--表达式
无分号--表达式
空语句
;
赋值语句
赋值运算符
=
复合赋值运算符
+=,-=,/=,*=
a-=b相当于a=a-b
b中包含表达式,相当于加了一个括号
x%=y+3
x%=(y+3)
x=x%(y+3)
x%=(y+3)
x=x%(y+3)
赋值表达式
变量 赋值运算符 表达式
a=b=c=5;
表达式赋值为5.abc值都为5
a=5+(c=6)
先算括号内的,再算加号的,c=6,a=11
a=(b=3*4)
3*4的值赋给了b,再赋值给a,a=b=12
(a=b)=3*4
报错,(a=b)为表达式,不能至于等号左边
a=(a=b)=3*4
同上
a+=a-=a*a
假设a=12,先算a-=a*a,得到a=12-144=-132
再算a+=-132,相当于a=a+(-132)=-132-132=-264
再算a+=-132,相当于a=a+(-132)=-132-132=-264
从后开始,逐层解开
赋值过程中的类型转换
将浮点型赋给整型,对浮点数取整,再赋值
如 int i = 2.34;//i= 2
如 int i = 2.34;//i= 2
整型赋值给单双精度时,数值不变,但以浮点数存入变量
如float f = 2; //f=2.0
如float f = 2; //f=2.0
将一个double型转为float型时,先将双精度转为单精度,
即只取6-7位有效数字
如double d = 12.456789e100;//指数为100,超出了float的范围,无法输出正确信息
即只取6-7位有效数字
如double d = 12.456789e100;//指数为100,超出了float的范围,无法输出正确信息
字符型数据赋值给整型,将字符转为ASCII码赋值为整型
将一个占字节多的整型赋值给一个占字节少的整型变量,会出现截断
int a = 32767; short b ; b=a+1;//输出-32768
int a = 32767; short b ; b=a+1;//输出-32768
赋值表达式与赋值语句
变量赋初值
int a = 5;
float f = 5.6;
char c = 'c';
float f = 5.6;
char c = 'c';
数据输入和输出
概念
c语言不提供输入输出语句,
但是又输入和输出的函数库扩展
但是又输入和输出的函数库扩展
标准输入和输出函数
输出
putchar(输出一个字符)
puts(输出一个字符串)
输出字符串并自动换行,该函数只能输出字符串。
printf格式输出)
通过格式控制符%s输出字符串,不能自动换行。
除了字符串,printf() 还能输出其他类型的数据。
除了字符串,printf() 还能输出其他类型的数据。
代码演示
注意,输出字符串时只需要给出名字,
不能带后边的[ ],
不能带后边的[ ],
错误写法:
printf("%s\n", str[]);
puts(str[10]);
printf("%s\n", str[]);
puts(str[10]);
输入
getchar(输入一个字符)
gets(输入一个字符串)
直接输入字符串,并且只能输入字符串。
scanf(格式输入)
通过格式控制符%s输入字符串。
除了字符串,scanf() 还能输入其他类型的数据。
除了字符串,scanf() 还能输入其他类型的数据。
代码演示
注意
scanf() 读取字符串时以空格为分隔,遇到空格就认为当前字符串结束了,
所以无法读取含有空格的字符串。
gets() 认为空格也是字符串的一部分,只有遇到回车键时才认为字符串输入结束,
所以,不管输入了多少个空格,只要不按下回车键,对 gets() 来说就是一个完整的字符串。
换句话说,gets() 用来读取一整行字符串。
所以无法读取含有空格的字符串。
gets() 认为空格也是字符串的一部分,只有遇到回车键时才认为字符串输入结束,
所以,不管输入了多少个空格,只要不按下回车键,对 gets() 来说就是一个完整的字符串。
换句话说,gets() 用来读取一整行字符串。
就目前学到的知识而言,int、char、float 等类型的变量用于 scanf() 时都要在前面添加&,
而数组或者字符串用于 scanf() 时不用添加&,它们本身就会转换为地址。读者一定要谨记这一点。
而数组或者字符串用于 scanf() 时不用添加&,它们本身就会转换为地址。读者一定要谨记这一点。
使用系统库函数时,
要在程序文件头中用预处理指令#include
要在程序文件头中用预处理指令#include
#include <stdio.h>
printf输出数据
格式
1) printf("字符串\n");
2) printf("输出控制符",输出参数);
3) printf("输出控制符1 输出控制符2…", 输出参数1, 输出参数2, …);
4) printf("输出控制符 非输出控制符",输出参数);
输出控制符
%x、%X、%#x、%#X 的区别
最好是加一个#,否则如果输出的十六进制数正好没有字母的话会误认为是一个十进制数呢!
总之,不加#容易造成误解。但是如果输出 0x2f 或 0x2F,那么人家一看就知道是十六进制。
而且%#x和%#X中,笔者觉得大写的比较好,因为大写是绝对标准的十六进制写法。
总之,不加#容易造成误解。但是如果输出 0x2f 或 0x2F,那么人家一看就知道是十六进制。
而且%#x和%#X中,笔者觉得大写的比较好,因为大写是绝对标准的十六进制写法。
如何输出 %d、\ 和双引号
注意
“输出控制符”和“输出参数”无论在“顺序上”
还是在“个数上”一定要一一对应。
否则就会出现错误
还是在“个数上”一定要一一对应。
否则就会出现错误
scanf输入数据
格式
1) scanf("输入控制符", 输入参数);
2) scanf("输入控制符非输入控制符", 输入参数);
3)输入多个
注意事项
1) 参数的个数一定要对应
输入控制符”和“输入参数”无论在“顺序上”
还是在“个数上”一定要一一对应。
还是在“个数上”一定要一一对应。
2) 输入的数据类型一定要与所需要的数据类型一致
如果不一致,编译不会报错,运行时报错
getchar不仅可以从输入设备获得一个可显示的字符
还可以获得屏幕上无法显示的字符,如控制字符
还可以获得屏幕上无法显示的字符,如控制字符
getchar(a)
第四章 选择结构程序设计
选择结构
if
括号内必须为表达式
else不一定是与最近的if配对,
switch
括号内必须为表达式,类型应该为整数类型(包括字符型,不能表达char *,字符串)
每个case常量必须互不相同
case语句,如果没有break结束,运行完毕后会自动跳到下一个case运行
("}"前一个执行结束后,没有break会自动结束)
("}"前一个执行结束后,没有break会自动结束)
关系运算符和关系表达式关系
>(大于)、>=(大于等于)、<(小于)、
<=(小于等于)、==(等于)和 !=(不等于)
6 种二元关系运算符。
<=(小于等于)、==(等于)和 !=(不等于)
6 种二元关系运算符。
在以上 6 种关系运算符中,前 4 个的优先级高于最后两个。
逻辑运算符和逻辑表达式关系
||, &&, !
||(or) < &&(and) < !(no)
逻辑表达式中的false由0表示,true由非0表示,0都为false,非0都为true
算术运算符
+,-,*,/,%
乘除大于加减
算术、逻辑、关系、赋值,条件运算符的优先级顺序为:
逻辑非 (!)>单目运算符(++,--)>算术(+-*/)=单目运算符(x++)>关系(>==<)>逻辑(逻辑 与&&、或||)>条件(?,:)>赋值(=)
条件运算符以及表达式
三目运算符:表达式1?表达式2:表达式3
条件运算符
?和:
先算表达式1,再算表达式2和表达式3
max=(a>b)?a:b,先搞定max=(a>b),再搞定a,b
条件运算符优先于赋值运算符
max=(a>b)?a:b,
先把a>b的结果赋值给max,再去做后面的
条件运算符优先级优先级低于关系运算符和算术运算符都要低,去掉括号意思就不同了
先把a>b的结果赋值给max,再去做后面的
条件运算符优先级优先级低于关系运算符和算术运算符都要低,去掉括号意思就不同了
条件表达式中可以写语句,不用加分号
(a>b)?printf('a'):printf('b')
第五章 循环结构程序设计
循环结构
while
while(表达式){
语句块 ;
}
语句块 ;
}
表达式为真是,执行循环体
do....while
do{
语句块;
}while(表达式);
语句块;
}while(表达式);
先执行一次循环,再去判断表达式,真继续执行,否就跳出
for
for(初值;条件表达式;初值增长){
语句块;
}
语句块;
}
三个部分都可以省略,但是要留下分号
break与continue
break
跳出循环体,结束整个循环
continue
结束本次循环,继续下次循环
0 条评论
下一页
为你推荐
查看更多