前言
回炉重造C语言的第一天,当然,能多一次打基础的机会那肯定是极其好的,毕竟跟没有人会嫌弃钱多,是一个道理的。(因为我懒,可能懒得更新)
今天学的内容
由于我是晚到两天,所以就从字符判定开始讲起了,没办法
printf
函数功能:
将format所指定的数据打印到标准输出设备(终端)
参数:
Format:指定要打印的东西,可以编写字符串进去里面
例如:printf(“hello world\n”);
也可已指定格式的输出:
Printf(“数字位%d\n”, 123);
...:代表是一个变参函数,参数根据format里面的内容来填充
综合描述过程:
1,printf不是将数据直接输出,需要经过输出缓冲区
2,printf的缓冲区具备行缓冲特性,如果打印的数据没有添加换行符,则不会立即打印,将会一直等到遇到'\n'或者是缓冲区满了才会输出(强制清除缓冲区)
format的格式可以有哪些:
%d:打印一个int数据
%o:八进制打印一个int数据
%x:十六进制打印一个int数据
%hd:打印short数据
%hhd:打印char型的整数数据
%c:打印一个字符
%f:打印一个float
%lf:打印一个double
%llf:打印一个long double
%u:打印一个unsinged int
%hu:打印一个unsigned short
%s:打印一个字符串
%.2f:打印到小数点后2位
%10s:打印长度位10的字符串(如果未满10则用空格补齐)
%-10s:打印长度位10的字符串(如果未满10则用空格补齐)
printf("\033[1;33m Hello World. \033[0m \n"); \033[0m--清除颜色格式
颜色如下:
none = "\033[0m"
black = "\033[0;30m"
dark_gray = "\033[1;30m"
blue = "\033[0;34m"
light_blue = "\033[1;34m"
green = "\033[0;32m"
light_green -= "\033[1;32m"
cyan = "\033[0;36m"
light_cyan = "\033[1;36m"
red = "\033[0;31m"
light_red = "\033[1;31m"
purple = "\033[0;35m"
light_purple = "\033[1;35m"
brown = "\033[0;33m"
yellow = "\033[1;33m"
light_gray = "\033[0;37m"
white = "\033[1;37m"
字背景颜色范围: 40--49
字颜色: 30--39
40: 黑 30: 黑
41:红 31: 红
42:绿 32: 绿
43:黄 33: 黄
44:蓝 34: 蓝
45:紫 35: 紫
46:深绿 36: 深绿
47:白色 37: 白色
输出特效格式控制:
\033[0m 关闭所有属性
\033[1m 设置高亮度
\03[4m 下划线
\033[5m 闪烁
\033[7m 反显
\033[8m 消隐
\033[30m -- \033[37m 设置前景色
\033[40m -- \033[47m 设置背景色
printf(“\033[2J”);
光标位置等的格式控制:
\033[nA 光标上移n行
\03[nB 光标下移n行
\033[nC 光标右移n行
\033[nD 光标左移n行
\033[y;xH设置光标位置
\033[2J 清屏
scanf
- scanf这个函数是用来从键盘中获取数据到指定的内存中的
格式:
int scanf(const char *format, ...);
函数返回值:
成功通过scanf获取到多少个数据
他的引用方式例如:
scanf(“%d”, &number);
从键盘中获取一个整型数放到number中,他中间经历了以下逻辑:
- scanf一经调用,便会将”开关”合上,也就是键盘可以开始向缓冲区中输入数据了,但是scanf并不是键盘输入什么东西马上就获取什么东西,他会等待一个’\n’(键盘敲下回车)
- 一旦键盘敲下回车,他就会检查缓冲区当中的数据(如果缓冲区里面一开始是个’\n’,它会自动清除),会跟自己的””里面所声明的格式进行匹配,看看格式是否正确,如果格式是符合的,就将数据获取出来,并且记录scanf已经获取到了一个数据,并且看看是否””后面是否需要继续获取数据,如果需要则继续查看缓冲区是否有数据,按照1步骤重新监控数据,如果没有立即返回函数,返回成功获取到多少个数据。
- 如果缓冲区的数据格式不符合,则scanf立即返回,不会将缓冲区里面的数据拿出来
运算符
赋值运算:
var = value;
例如:
var = 100;
注意的地方:
等号坐标被我们称之为左值,左值必须是一个能够更改的内存
1,例如:
变量名 = 数据值;
int a;
a = 100;
注意:
不能够出现左边是一个运算
a+100 = 200;
具体的内存 = 数据值;
volatile:
由该关键字修饰的内存或者变量具备实时访问特性(防止优化)
广泛的用来去修饰寄存器的地址
算数运算法:
+:加法,一目取正
-:减法,一目取负
*:乘法
/:除法
%:取余,比较大的作用,将某个数据限制在指定的范围之内
++:
++a:
先将a+1重新赋值给a, ++a的表达式当做是新的a的值
a++:
表达的值用a的旧值,然后再将a+1重新赋值给a
--:
--a:
先将a-1重新赋值给a, --a的表达式当做是新的a的值
a--:
表达的值用a的旧值,然后再将a+1重新赋值给a
关系运算符:
>:大于
>=:大于等于
<:小于
<=:小于等于
==:等于
!=:不等于
以上判断关系如果成立返回1,不成立返回0
逻辑运算符:
&&:并且
在C语言中,如果&&的前面表达式为假,则接下来的判断语句全部都不会执行
||:或者
在C语言中,如果||的前面表达式为真,则接下来的判断语句全部都不会执行
!:逻辑取反(就是真变假,假变真)
非0数值逻辑取反变成0,0逻辑取反变成1
位运算符:(按二进制级别的操作)
~:按位取反运算
不要跟逻辑取!反搞混了
&:按位与运算
对比:
a&b:位与运算
a&&b:逻辑判断a条件跟b条件是否同时成立
&a:取a变量的内存地址
|:按位或运算
对比:
a|b:位或运算
a||b:逻辑判断a条件或者是b条件是否成立,有一个成立则成立
^:按位异或运算
相同得0,不同得1
简单的加密:
特点:任意的两个值异或出来都可以得出第三个值
<<:左移运算
所有的二进制数据全部进对应的位数,溢出的直接丢掉,空余出来的位置,直接补0
>>:右移运算
所有的二进制数据全部退对应的位数,溢出的直接丢掉,空余出来的位置,直接补0
复合赋值运算符:
+= ,-=, /=, *=, %=, >>=, <<=, &=, |=, ^=
例如:
a += 10;
等价于
a = a+10;
三目运算:
条件?成立则返回这个:不成则返回这个;
- b?a:b;
格式:
判断条件 ? 如果条件为真,这条表达式的值就是整个三目运算符的值 : 否则则是这条表达式;
逗号表达式:
整个表达式的值等于最后一个逗号表达式的值
例如:
a=10, b=200, c=a+b;
这个表达式的值等于c=a+b这个表达式的值,也就是210
整条逗号表达式的值由最后一条表达式所决定
用途:
在有限的表达式位置当中,为了更好的处理更多语句,我们才使用逗号表达式
类型转换
类型转换:
隐式类型转换:
- 赋值时,如果左边的精度比右边的精度高,右边会隐式类型转换配合左边的数据
例如:float fl = 123;
- 赋值时,如果右边的精度比左边的精度高,有可能会出现数据丢失,只保留左边的数据存储得下的数据。(编译器严格的情况下会给你报警告),一般这种操作为了消除警告,在有把握的情况下会进行强制类型转换
例如:short sh = 100000000;
- 运算的时候,当低精度数据类型与高精度数据进行运算的时候也会进行转换,将低精度转化为高精度
例如:1.0/2的时候,会先将2转化为浮点型数据,然后计算出结果,得出0.5。
但是如果是大家的类型是一样的,就不会出现隐式类型转换
例如:3/2的时候,是不会转化任何类型的,得出的数据还是整型,得出结果为1
强制类型转化:
强制类型转换时什么:
int a = -1;
(unsigned int )a;
本质就是强制改变变量或者是内存的分析方式。
将高精度往低精度转换我们可以用强制类型转换,这个时候就不会报警告
首先应该明确一点,我们应该要极少的使用这种转换方式,因为他有可能会给你带来数据的丢失,或者是数据解释异常
一般拿强制类型转换去做地址转换:
例如:某寄存器地址为0x12345678,但是这个值默认会解释为整型数,为了让他当做内存地址来使用,我们会给他强制类型转换一下(unsigned long *)0x12345678;
辅助函数
sizeof();
用来测量一个变量或者是类型有多大,以字节为单位
例如:
char *string = "hello";
char array[1024];
printf("size=%ld\n", sizeof(string));//这个是测量string这个变量有多大(指针变量跟 系统位数一样大)
printf("size=%ld\n", sizeof("hello"));//测量字符串这个常量有多大
printf("size=%ld\n", sizeof(array));
一定要记住的特点:
sizeof仅仅只是测量你放在sizeof()括号里面的那个变量或者常量有多大,他不会进去里面查看内存有多大,例如上面测量string,他测量的是string变量的大小,而不是跑到string所指的内存"hello"里面去看有多大。
strlen();
用来测量一块内存有多少个字符,不包含’\0’的
他会跑到内存当中去测量他的字符有多少个
char *string = "hello";
printf("strlen=%ld\n", strlen("hello"));
printf("strlen=%ld\n", strlen(string));
大家得出的结果都是5
strcpy();
字符串复制
char *strcpy(char *dest, const char *src);
将src这个字符串的内容拷贝到dest这个内存中
strcat();
字符串合并
char *strcat(char *dest, const char *src);
将src这个字符串的内容拷贝到dest这个字符串内容的后面(合并在一起)
上述两个函数中,dest这个参数必须是能够改变的内容,你肯定不能直接将字符串常量放进去
格式化其他输入输出
输入输出函数:
scanf:是从键盘当中获取指定格式的数据放到指定的内存当中
int scanf(const char *format, ...);
函数功能:
从键盘当中获取format指定格式的数据去放到后方的参数所指定的内存中
format:跟printf的格式声明是一样的
但是不能这样用:
scanf("input %d\n", &var);//这种用法错误,scanf是输入功能,没有打印功能,其format参数中不允许出现除格式指定之外的内容
他是一个变参函数:
他是不限制参数的个数的,后面...参数的内容及格式由前面的format参数所去指定
键盘输入参数的过程中,多个数据可以通过"空格"及"回车"来去分隔开来参数
综合描述过程:
1,scanf去获取数据并不是直接获取的,需要经过输入缓冲区
2,如果scanf获取数据失败,他将会直接退出,不会继续卡(阻塞)在那里
3,该函数获取数据的过程中,如果格式不对应,将会获取失败,并且不会将这个失败的数据清出输入缓冲区
返回值:
返回多少个成功获取到的数据个数
int sscanf(const char *str, const char *format, ...);
函数功能:从指定的内存str中获取格式为format的数据出来放到后面的内存中
getchar:从键盘中获取一个字符,并且将它返回出来
int getchar(void);
无参数;
返回值:
成功返回一个从键盘中(IO缓冲区中)获取的字符数据,如果缓冲区中没有数据,则将会阻塞在那里
失败返回 EOF
输出函数:
printf:将数据显示到终端上
int printf(const char *format, ...);
函数功能:
从键盘当中获取format指定格式的数据去放到后方的参数所指定的内存中
但是可以这样用:
printf("output %d\n", &var);//需要有一一对应关系
他是一个变参函数:
他是不限制参数的个数的,后面...参数的内容及格式由前面的format参数所去指定
综合描述过程:
1,printf不是将数据直接输出,需要经过输出缓冲区
2,printf的缓冲区具备行缓冲特性,如果打印的数据没有添加换行符,则不会立即打印,将会一直等到遇到'\n'或者是缓冲区满了才会输出(强制清除缓冲区)
%%:打印一个%
%d:打印一个有符号整数(int)
%u:打印一个无符号的整数(unsigned int)
%o:用八进制打印一个整数
%x:用十六进制打印一个整数
%hd:打印一个短整型数据(short)
%hhd:打印一个超短整型数据(char的数字)
%ld:打印一个长整型(long)
%lu:打印一个无符号长整型(unsigned long)
%lld:打印一个长长整型(long long)
%f:打印一个单精度浮点数(float)
%lf:打印一个双精度浮点(double)
%Lf:打印一个多精度浮点(long double)
%c:打印一个字符(char)
%s:打印一个字符串(char *)
%p:打印一个地址值(指针变量或者是地址的)
%e:用科学计数法打印一个浮点数
%.2f:保留小数点后两位打印一个浮点数
%10s:保证至少打印10个字符出来,不够空格来凑,右对齐方式
%-10s:保证至少打印10个字符出来,不够空格来凑,左对齐方式
返回值:
失败返回-1
int sprintf(char *str, const char *format, ...);
函数功能:将指定格式的字符串(format)输出到指定的内存(str)中
函数特点:
该函数具备自适应字符串的功能,结束标志是遇到\0
所以该函数有致命bug,除非你的str内存中大小够大,或者自己操作时候算好内存,不然容易崩溃
int snprintf(char *str, size_t size, const char *format, ...);
函数功能:将指定大小(size)的格式的字符串(format)输出到指定的内存(str)中
函数特点:
该函数具备自适应字符串的功能,结束标志是遇到\0
封顶就是拷贝size这么大道str的内存中
其中size的大小是包含了'\0'的大小
字符串的潜规则:
所有的字符串即字符串的判断都必定是以'\0'结尾,如果字符串中间夹杂'\0',遇到什么函数的分析都会一遇到'\0'马上停止分析
sizeof函数:
sizeof(放任意类型或者变量);
sizeof用来测量括号里面的家伙的大小,返回一个无符号的长整型数据
sizeof(int);可以用来测量int型多大
sizeof(变量):用来测量变量有多大
sizeof(字符串):测量字符串所占内存大小多大
sizeof(地址/指针变量):得到系统位数
strlen:测量指定字符内存的字符个数
unsigned long strlen(char *string);
一旦'\0'马上停止并且返回个数
特点:
不管你是指针还是字符串都可以测量内存里面的字符个
小练习
Test1
输入一个数字,将其范围100的所有数据通过printf打印出来,并且有输入判断
#include
int main(void)
{
int number;
int retval;
int num;
int num1 = 0;
while(1)
{
retval = scanf("%d",&number);
if(retval != 1)
{
printf("您输入的数据有误,请重新输入:\n");
while(getchar() != '\n');
continue;
}
if(getchar() != '\n')
{
printf("您输入的数据有误,请重新输入:\n");
while(getchar() != '\n');
continue;
}
for(num=number-100;num<=number+100;num++)
{
printf("%d\n",num);
}
}
return 0;
}
另一个代码:
待添加
Test2
随便输入一句话,输出其字符长度(scanf不经过处理读取不了空格,读取到空格就会停止)
#include
#include
int main(void)
{
char p[1000];
scanf("%s",&p);
printf("%ld\n", strlen(p));
return 0;
}
Test3
使用sprintf提前存储内容替换printf持续输出,比如:我是1,哈哈;我是2,哈哈······一直持续输出,一直到250。
#include
int main(void)
{
char buffer[1000];//定义char类型数据,作为缓存
int number;
for(number=0;number<=250;number++)//for循环持续输出
{
sprintf(buffer,"%s%d,%s","我是",number,"哈哈");
printf("%s\n",buffer);
}
return 0;
}
结语
今天的学习效果暂时来说很不错,打起精神,明天继续!