先来一个小代码可以检验一下上一上的学习
cpp
#include "stdio.h"
#include "string.h"
int main()
{
char a [1000];
for(int i = 0 ; i < 1000 ; i++)
{
a[i] = -1 -i;
}
printf("strlen(a) = %d\n", strlen(a));
return 0;
}
这个输出值是多少?255

127+128 = 255
然后是今天的知识C语言的输入和输出
输入:从键盘中获取值
输出:将变量打印到终端
//格式化输入输出 printf scanf
Printf("提示信息+占位符",数据名)
二、转换说明符表格
| 类别 | 占位符 | 对应类型 | 输出格式 | 示例代码 | 示例输出 |
|---|---|---|---|---|---|
| 整数 | %d 或 %i |
int |
有符号十进制整数 | printf("%d", 123); |
123 |
%u |
unsigned int |
无符号十进制整数 | printf("%u", 123u); |
123 |
|
%o |
unsigned int |
无符号八进制整数 | printf("%o", 123); |
173 |
|
%x |
unsigned int |
无符号十六进制(小写) | printf("%x", 255); |
ff |
|
%X |
unsigned int |
无符号十六进制(大写) | printf("%X", 255); |
FF |
|
| 字符 | %c |
int (可转 char) |
单个字符 | printf("%c", 'A'); |
A |
%lc |
wint_t |
宽字符 | printf("%lc", L'中'); |
中 |
|
| 字符串 | %s |
char* |
字符串 | printf("%s", "Hello"); |
Hello |
%ls |
wchar_t* |
宽字符串 | printf("%ls", L"中文"); |
中文 |
|
| 指针 | %p |
void* |
指针地址(十六进制) | int x; printf("%p", &x); |
0x7ffe... |
| 浮点数 | %f 或 %F |
double |
十进制浮点数(小写/大写) | printf("%f", 3.14); |
3.140000 |
%e 或 %E |
double |
科学计数法(小写/大写) | printf("%e", 3.14); |
3.140000e+00 |
|
%g 或 %G |
double |
自动选择 %f 或 %e |
printf("%g", 3.14); |
3.14 |
|
%a 或 %A |
double |
十六进制浮点数(C99) | printf("%a", 3.14); |
0x1.91eb8...p+1 |
|
| 特殊 | %% |
无 | 输出百分号本身 | printf("%%"); |
% |
%n |
int* |
将已写字符数存入参数 | int n; printf("123%n", &n); |
n=3 |
三、长度修饰符表格
| 长度修饰符 | 配合转换符 | 对应类型 | 示例 | 说明 |
|---|---|---|---|---|
hh |
%hhd, %hhu |
signed char, unsigned char |
printf("%hhd", c); |
C99 |
h |
%hd, %hu, %hx |
short, unsigned short |
printf("%hd", s); |
|
l (小写L) |
%ld, %lu, %lx |
long, unsigned long |
printf("%ld", l); |
|
%lf, %le, %lg |
double |
printf("%lf", d); |
l 对 f/e/g 无效(C99起) |
|
%lc, %ls |
wint_t, wchar_t* |
printf("%ls", ws); |
宽字符/串 | |
ll (两个L) |
%lld, %llu, %llx |
long long, unsigned long long |
printf("%lld", ll); |
C99 |
j |
%jd, %ju |
intmax_t, uintmax_t |
printf("%jd", imax); |
C99 |
z |
%zd, %zu |
size_t, ssize_t |
printf("%zu", sz); |
C99 |
t |
%td |
ptrdiff_t |
printf("%td", diff); |
C99 |
L (大写) |
%Lf, %Le, %Lg |
long double |
printf("%Lf", ld); |
四、标志(flags)表格
| 标志 | 作用 | 示例代码 | 示例输出 |
|---|---|---|---|
- |
左对齐(默认右对齐) | printf("%-10d", 123); |
123 |
+ |
显示正负号(正数也显示+) | printf("%+d", 123); |
+123 |
空格 |
正数前加空格,负数前加- | printf("% d", 123); |
123 |
0 |
用0填充宽度(而非空格) | printf("%05d", 123); |
00123 |
# |
特殊格式: %#o - 八进制加0 %#x - 十六进制加0x %#X - 十六进制加0X %#g - 保留小数点后0 |
printf("%#x", 255); |
0xff |
五、宽度和精度表格
| 格式 | 说明 | 示例代码 | 示例输出 |
|---|---|---|---|
%数字 |
最小字段宽度 | printf("%5d", 123); |
123 |
%* |
宽度从参数中读取 | printf("%*d", 5, 123); |
123 |
%.数字 |
精度: 整数-最小位数 浮点数-小数位数 字符串-最大字符数 | printf("%.2f", 3.14159); |
3.14 |
%.* |
精度从参数中读取 | printf("%.*f", 2, 3.14159); |
3.14 |
%数字.数字 |
宽度和精度组合 | printf("%8.2f", 3.14159); |
3.14 |
六、类型与占位符对应关系完整表
| 数据类型 | 推荐占位符 | 其他可用占位符 | 头文件 | 示例 |
|---|---|---|---|---|
char |
%c |
%d, %hhd (C99) |
char c = 'A'; printf("%c", c); |
|
signed char |
%hhd (C99) |
%d |
signed char sc = -128; printf("%hhd", sc); |
|
unsigned char |
%hhu (C99) |
%u, %c |
unsigned char uc = 255; printf("%hhu", uc); |
|
short |
%hd |
%d (可能警告) |
short s = 123; printf("%hd", s); |
|
unsigned short |
%hu |
%u |
unsigned short us = 456; printf("%hu", us); |
|
int |
%d |
%i, %x, %o |
int i = 123; printf("%d", i); |
|
unsigned int |
%u |
%x, %o |
unsigned int ui = 123; printf("%u", ui); |
|
long |
%ld |
%li, %lx, %lo |
long l = 123L; printf("%ld", l); |
|
unsigned long |
%lu |
%lx, %lo |
unsigned long ul = 123UL; printf("%lu", ul); |
|
long long (C99) |
%lld |
%lli, %llx, %llo |
long long ll = 123LL; printf("%lld", ll); |
|
unsigned long long (C99) |
%llu |
%llx, %llo |
unsigned long long ull = 123ULL; printf("%llu", ull); |
|
float |
%f |
%e, %g, %a (C99) |
float f = 3.14f; printf("%f", f); |
|
double |
%lf<sup>1</sup> |
%f, %e, %g, %a |
double d = 3.14; printf("%lf", d); |
|
long double |
%Lf |
%Le, %Lg, %La (C99) |
long double ld = 3.14L; printf("%Lf", ld); |
|
char* (字符串) |
%s |
char* str = "hello"; printf("%s", str); |
||
void* (指针) |
%p |
int x; printf("%p", &x); |
Printf("提示信息+占位符",数据名)
Printf函数是行缓冲
Scanf()的输入必须格式化
cpp
int num;
scanf("num = %d",&numm);
printf("num = %d",num);
//输入必须完全和里面格式相同
//scanf 必须输入 num = 1
scanf()还会产生输入垃圾,在scanf里面不要加'\n'//可以在后面加上getchar()吃掉垃圾
printf()最好加'\n'
cpp
#include <stdio.h>
int main()
{
int num ;// %d
char ch ;//%c
float fnum;//%f
double dnum;//%lf
int a[3];//%d
char c[100];//%s
scanf("%d %c %f %lf %d %d %d %s",&num,&ch,&fnum,&dnum,&a[0],&a[1],&a[2],c);
printf("num = %d\n",num);
printf("ch = %c\n",ch);
printf("fnum = %f\n",fnum);
printf("dnum = %lf\n",dnum);
printf("a[0] = %d\n",a[0]);
printf("a[1] = %d\n",a[1]);
printf("a[2] = %d\n",a[2]);
printf("c = %s\n",c);
return 0;
}
大家可以试一试这个代码去检验一下,对于前面知识的理解
如果想要注释大段代码
可以使用
cpp
#if 0
#endif
想要解引用只要把0改成1就行
变量的三大要点
字节长度,作用域,存储区域
作用域
声明:告知编译器有这个变量但是没有分配内存
定义:告知编译器有这个变量并分配内存
所以用一个关键字就可以达到外部声明 extern
可以扩大作用域
局部变量只能在局部使用
全局变量只能在这个文件使用
如果使用extern就可以跨文件使用
存储区域:变量保存的位置
物理内存保存数据(稀缺资源),操作系统来管理,
操作系统把每个程序运行分配4G的虚拟地址空间,
通过映射来达到目的,所以我们据需要知道虚拟地址的区域划分
栈空间:保存局部变量,函数的形参。
特点:分配和释放又操作系统在管理。未初始化的变量系统会初始化为随机值
堆空间:存储malloc,realloc,calloc
特点由用户自己管理
数据段
Or段 :保存常量
Bss段:保存全局变量
静态数据区:static修饰的变量
Int num = 5;
定义了整型,分配了四个字节,如果时全局变量,保存在BSS段,程序全局可见,如果是局部变量,保存在栈空间,只有所在函数可见
然后我们就可以使用typedef
可以提高代码移植性,可读性,与运行效率
然后下一部分就是运算符
运算符是一种告诉编译器执行特定的数学或逻辑操作的符号。C 语言内置了丰富的运算符,并提供了以下类型的运算符:
- 算术运算符,关系运算符,逻辑运算符,位运算符,赋值运算符,杂项运算符,
|-------------|------------------|----------------|
| 运算符 | 描述 | 实例 |
| + | 把两个操作数相加 | A + B 将得到 30 |
| - | 从第一个操作数中减去第二个操作数 | A - B 将得到 -10 |
| * | 把两个操作数相乘 | A * B 将得到 200 |
| / | 分子除以分母 | B / A 将得到 2 |
| % | 取模运算符,整除后的余数 | B % A 将得到 0 |
| ++ | 自增运算符,整数值增加 1 | A++ 将得到 11 |
| -- | 自减运算符,整数值减少 1 | A-- 将得到 9 |
这几个里有点难度的就是 ++ , --了
主要是 i++ 先用后算 ++i 先算后用
来一题试上一试
cpp
#include <stdio.h>
int main()
{
int i = 2;
int num = (i++) + (i++) +(++i)+(i++);
printf("num = %d\n",num);
printf("i = %d\n",i);
return 0;
}
cs
int main()
{
int i = 2;
printf(" %d , %d , %d , %d \n",i++,++i,++i,i++);
printf("i = %d\n",i);
return 0;
}
函数传参从右开始传
判断
C 语言提供了以下类型的判断语句。点击链接查看每个语句的细节。
| 语句 | 描述 |
|---|---|
| if 语句 | 一个 if 语句 由一个布尔表达式后跟一个或多个语句组成。 |
| if...else 语句 | 一个 if 语句 后可跟一个可选的 else 语句,else 语句在布尔表达式为假时执行。 |
| 嵌套 if 语句 | 您可以在一个 if 或 else if 语句内使用另一个 if 或 else if 语句。 |
| switch 语句 | 一个 switch 语句允许测试一个变量等于多个值时的情况。 |
| 嵌套 switch 语句 | 您可以在一个 switch 语句内使用另一个 switch语句。 |
cpp
if(判断)
{
}
else if()
{
}
else
{
}
cpp
switch (a)
case 1 :{
break;
}
case 2 :{
break;
}
case 3 :{
break;
}
case 4 :{
break;
}
循环
C 语言提供了以下几种循环类型。点击链接查看每个类型的细节。
| 循环类型 | 描述 |
|---|---|
| while 循环 | 当给定条件为真时,重复语句或语句组。它会在执行循环主体之前测试条件。 |
| for 循环 | 多次执行一个语句序列,简化管理循环变量的代码。 |
| do...while 循环 | 除了它是在循环主体结尾测试条件外,其他与 while 语句类似。 |
| 嵌套循环 | 您可以在 while、for 或 do..while 循环内使用一个或多个循环。 |
cpp
while(判断)
{
}
cpp
for(表达式1;判断;表达式2)
{
}
cpp
do
{
}while(判断);
连续判断可以用for
cpp
#include <stdio.h>
int main()
{
int i = 0 ;
char src[100];
for(i = 0; i < 100 ; i++)
{
scanf("%c",&src[i]);
if(src[i] == '#')
{
break;
}
}
src[i] = '\0';
int count = 0;
int max = 0;
for(int i = 0 ; i < 100 ; i++)
{
for(;src[i]>='a' && src[i]<='z';i++)
{
count++;
}
if(count>max)
{
max = count;
}
count = 0;
}
printf("max = %d\n",max);
return 0;
}