循环语句
1、while循环
while(条件成立)
{执行语句......}
getchar()——从键盘获取一个字符
putchar()——把一个字符打印到屏幕上
EOF——end of file,文件结束标志,本质上EOF=-1,所以当某个变量等于EOF时终止循环,要输入的不是-1这个值,因为本质上-1仍然是一个值,-1不等于EOF,而是Ctrl+Z,代表输入的是EOF。即在windows中,Ctrl+Z为文件结束标志。
输入函数的输入过程
1、键盘输入一串字符,保存在输入缓冲区;
2、输入函数:scanf、getchar按自己本身规则从输入缓冲区中读取字符,且只读取'\n’之前的值,进行下一次读取前要清空缓冲区。
例:键盘输入123456\n,输入函数则读取123456
如果键盘输入123\n456,输入函数则读取123
2、for循环
结构:for(i=0;i<10;i++)→for(i初始部分;条件判断部分;调整部分)
循环中影响循环结果的有三个部分:i初始部分;条件判断部分;调整部分
重点:二分法查找数字
strlen()——求字符串长度
sleep(1000)——系统睡眠1000毫秒(1秒)
system("cls")——清空屏幕
strcmp——函数是用来比较两个字符串的大小关系的
例:strcmp(password,"123456")==0,用来确定两个字符串是不是完全一致。
重点:猜数字游戏
rand——生成随机数的函数,包含在头函数<stdlib.h>中
时间戳——定义电脑起始时间(1970.1.1 0:0:0),现时刻到起始时刻的时间差,单位为秒。
srand((unsigned int) time (NULL));——以时间戳设置随机起点
goto语句
flag;
.
.
.
.
.
goto flag;//直接跳转到flag处,继续运行程序
关机命令——shut down -s -t-30(60s后关机)
取消关机——shutdown -a
函数
C语言库函数包含类别:
1、IO函数;
2、字符串操作函数;
3、字符操作函数;
4、内存操作函数;
5、时间\日期函数;
6、数学函数;
7、其他。
memset——把一个数组的前n位替换成某个字符
例:
char arr[]="hello world"; memset(arr,'*',5); //此时arr[]="***** world"
void——表示此函数不返回任何值
形参和实参
当实参传给形参时,形参是实参的一份临时拷贝,对形参的改变不会影响实参
用函数交换两个变量的值,要用指针传参,否则形参不影响实参,交换过程无效。
P.S.数组传参的时候,实际上传递的是首元素的地址
函数调用
1、嵌套调用
同时有A、B、C三个函数,A函数可以调用B和C来进行计算
2、链式访问
例:
printf("%d",printf("%d",printf("%d",43)));
打印结果为:4 3 2 1,(printf的返回值是打印字符的个数)
工程的结构:
函数的声明放在头文件里,自己创建的头文件引用,例:
#include "add.h"
函数的定义放在xxx.c文件里
以上两者属于一个模块,自定义函数,以便在主程序中可以直接调用,精简主程序,使之更加清晰明了。
#ifndef __CALC_H__ #define __CALC_H__ #end if
上示代码是为了防止程序读取两遍头文件,从而造成内存占用增大。
函数递归——函数自己调用自己
例:
void printf(int n) { if(n>9) { printf("%d\n",n%10); } }
递归的限制条件
1、存在限制条件,当递归满足限制条件,便停止递归;
2、每次递归后要更加接近限制条件。
.
内存分为栈区、堆区、静态区,堆区由动态内存分配;静态区包含全局变量、静态变量;栈区包含局部变量、函数形参,同时函数调用也会开辟空间。
因为函数调用也会开辟空间,递归函数无限递归会导致栈区被完全占用,又称栈溢出(stack onerflow)
作业:汉诺塔——递归
青蛙跳台阶——波菲那契函数
数组
char ch1[]={a,b,c,d}→a,b,c,d
char ch2[]="abcd"→a,b,c,d,\0
%p——打印地址
数组在内存中是连续存放的。
二维数组:
int arr[3][4]//三行四列 int arr[3][4]={1,2,3.4,5} //1 2 3 4 //5 0 0 0 //0 0 0 0 int arr[3][4]={{1,2},{3,4},5} //1 2 0 0 //3 4 0 0 //5 0 0 0
在建立一个新的二维数组是,行数可以省略,而列数不能省略。
数组名是首元素地址(绝大多数情况)
例外:
1、sizeof(arr)→计算的是整个数组的大小
2、&arr →取出的是整个数组的地址
strlen——用来计算字符串的长度
sizeof——数组/字符串占存储大小
操作符
算数操作符
+ - * /:整数、浮点数都可以使用
/——两侧都是整数时,执行整数除法;只要有一侧是浮点数,执行小数除法
%:只有整数可以使用
移位操作符
移动的是二进制位
例:
a=7(D)=0111(B)
int变量大小为4个字节,所以a的大小为4*8=32个bit位
所以a存储时,存储为000...(28)....000 01111
当左移时:左边丢弃,右边补0
a<<1:000...(27)...000 01110
当右移时,有两种情况:
1、算术右移:右边丢弃,左边补原符号位(即正数补0,负数补1)
2、逻辑右移:右边丢弃,左边补0
位操作符
&——按位与
^——按位或
|——按位异或(相同为0,不同为1)
练习
1、a=3,b=5,不用第三个未知量交换值
a=a^b; b=a^b; a=a^b;
初始a^b的结果为密码,此密码和a异或为b,和b异或为a。
即a^b^a=b、a^b^b=a
同一数和本身异或结果为0,0和任意数异或仍为原数,即:a^a=0、a^0=a.
2、计算一个整数在存储时所包含的1的数量
1)移位+循环
2)n=n&(n-1)——效果为每次从右往左依次去掉一个1
赋值操作符
= += -= *= /= &= |= != ^=
单目操作符
定义:只有一个操作数的操作符
例:!a——逻辑取反(真1,假0)
- 负值 + 正值
& 取地址 * 解引用操作符
sizeof——可以算变量的大小,也可以算变量数据类型的大小(单位:字节)
是操作符,不是函数
~:按位取反
int a=0; ~a=-1;
++/--:前置——先++/--,在使用
后置——先使用,再--
int a=0; int b=a++; a=0; int c=++a;
(类型):强制数据类型转换
例:int a=(int)3.14 把3.14强制转换为整数
关系操作符
> < >= <= == !=
条件操作符(三目操作符)
表达式1?表达式2:表达式3
含义:表达式1为真时,执行表达式2;表达式1为假时,执行表达式3.
例:
max=a>b?a:b; //a>b为真,输出a;否则,输出b。
逗号表达式
exp1,exp2,exp3.................
从左向右依次计算,结果为最后一个表达式的结果
下表引用操作符:
例:数组arr[10]
函数调用操作符
printf()——中()就是函数调用操作符
结构体
struct Book { char name[20]; int price; }; int main() { struct Book a={"C语言",35}; printf("%s 价格:%d\n",a.name,a.price); struct Book * pa=&a; printf("%s 价格:%d\n",a->name,a->price); return 0; }
表达式求值
隐式类型转换:1、整形提升;2、算数转换
1、整形提升——按变量的数据类型的符号位提升
符号位是0/1,就用0/1来补齐提升的位数
char a=3; char b=127; char c=a+b;
a、b储存存储为一个字节,所以a、b存储形式为
a=00000011 b=01111111
当进行a+b运算时,a和b要进行整形提升,a、b符号位都是0,所以整型提升后,a、b值为
a=00000000 00000000 00000000 00000011 b=00000000 00000000 00000000 01111111
计算后c=00000000 00000000 00000000 10000010
c是char类型,所以支撑存储一个字节,从最后截断,最终c=10000010
而c如果要整形提升,则提升为
c=10000010 c=11111111 11111111 11111111 10000010
2、算数转换——类型大小大于int(小于int的要进行整型提升)
在算数计算过程中,可能有不同数据类型的值进行运算,此时要先进行算数转换,将不同数据类型的数值统一为一个数据类型。算数转换过程是自动进行的(除了用强制类型转换操作的),即如果是一个int类型数值和一个unsigned int类型数值进行计算,则将int类型转换为unsigned int类型。
数据类型从低到高自动转换
操作符的属性:
1、操作符优先级
2、操作符的结合性
3、是否控制求值顺序