-->

常用的输入输出函数

printf()函数

int printf(const char * format,...);//函数原型

这个函数会输出到标准输出(显示屏)。

第一个参数是字符串,他除了%这个字符不能正常输出,其余的都可以输出,如果想要输出这个字符%%两个百分号即可。

如果想输出双引号,需要在前面加上一个转义字符\"\"这样就可以输出一对双引号

以下说明的都是在第一个参数中:

%:转化说明符。可以用0个或者多个转换说明符。在这个转换说明符中有可选的最小字段宽度、可选的精度、可选的长度修饰符。

标志说明以下必须放在%后面,被称为标志字符

  • #可以把对应进制的前导符输出

    printf("%#o\n",123);//输出123的八进制,并且前面带有前导符0
    printf("%#x\n",123);//输出123的十六进制,并且前面带有前导符0x
    
  • -用于让输出数据左对齐,一般的数据输出是右对齐的,加上这个可以用于左对齐,后面跟着精度举例子。
    以上的标志说明符只能用于C99标准或以下

  • 字段宽度:用十进制数来确定宽度,用于指定让字符串输出的列数

    printf("%10d\n",123);//输出 _______123  占10列,默认右对齐
    printf("%-10d%d\n",123,456);//输出 123_______456  123占10列,默认右对齐,456默认左对齐
    // 如果不想自己定义字符串所占的列数,那么可以用*。这个符号可以自己输出字符串的列数
    printf("%-*10d%d\n",10,20,30);//输出 20________30
    
  • 转换精度:小数点后面的输出位数,用.表示

    printf("%.3f\n",3.1415);//输出是小数点后3位也就是,3.142,注意系统会提高精度四舍五入
    //如果不加数字
    printf("%.f\n",3.1415);//那么他会输出3,默认为0
    
  • 长度修饰符

    • hh:把整形数据转换成字符型,针对输出内容,对数据本身无影响;

    • h:(half)把整形数据转换成短整形型,针对输出内容,对数据本身无影响;

    • l:(long)把整形数据转换成长整形,针对输出内容,对数据本身无影响;

    • ll:把整形数据转换成长长整形型,针对输出内容,对数据本身无影响;

      printf("%#hhx\n",0x12345678);//输出的结果是低地址存放的数据
      

    上面这个为什么不能立刻说出答案?
    是因为每一个架构的存储方式不一样,有的低地址存放高位,有的低地址存放低位

image

一般情况下电脑运用的是x86,一般是小端模式。arm架构一般使用大端模式。

  • 转换修饰符
符号 说明
d 十进制数字输出
o,u,x,X 分别以八进制、无符号、十六进制输出
f 浮点型输出,默认保留小数点后6位
c 字符输出
s 字符串输出
int main()
{
    printf("hello");
    sleep(5);
    printf("world");
    //最后执行的结果,会把hello放在输出缓冲区中,延迟五秒,然后再把world放在缓冲区中,然后等到}结束程序才从缓冲区刷新出来的
}

int main()
{
    printf("hello\n");
    sleep(5);
    printf("world\n");
    //最后执行的结果,会把hello放在输出缓冲区中,然后输出hello,延迟五秒,然后再把world放在缓冲区中,然后,输出world0,
}

/*
*所以输出的字符串都会放在缓冲区中,想要刷新缓冲区有4个条件
*1.输出字符中有'\n'
*2.缓冲区大小一般为4kb(4096字节),写满4kb也会直接刷新
*3.结束程序,系统也会刷新缓冲区
*4.手动刷新fflush(stdout);函数也可以刷新,参数是标准输出
*/
  • 需要注意的是,不只有输出有缓冲区,输入也有缓冲区,
  • 输入的缓冲区也是要在标准输入(键盘)中输入换行符,也就是回车
  • 一般情况有一些编译器不支持stdin标准输入,所以一般不用fflush

sizeof()

在这个关键字中,可以检测出数据类型的大小,但是在这括号里面的运算只是在里面有效,是不算运算的,

int a=0;
sizeof(++a);
printf("%d\n",&a);
//a的值,还是0
  • 还有就是运算的时候,在sizeof里面,如果不同的类型相加
char ch;
int in;
short sh;
float f;
double d;
long l;
sizeof(ch+sh); //4
sizeof(ch+ch); //4
sizeof(in+ch); //4
sizeof(f+d); //8
sizeof(l+in); //8

上面的结果表示,实际在计算的过程中,由于两个数据类型不匹配,导致计算的时候,会把小字节的数据类型转换成大字节的数据,转换最小为4个字节,最大为8个字节
int 和long ,int 会变成long。char和char,会变成int。其他也是差不多

这就是自动类型转换,在赋值运算中,赋值号的两边的数据类型不同时,会把赋值号的右边的值转换为左边的值。也就是(先转后赋值)。要是在不同数据类型混合运算中,将参与运算的所有数据先转换成同一种类型在计算(先转在计算)。

强制类型转换

int a;
float b;
a = (int)b;//强制转换为整形
(int *)//强制转换为整形指针

无论是哪一种都是将数据转换都是先转后计算,除非后面有括号(int)(3.14*2)就会先算后转换

scanf()函数

这个函数主要说[],^,-这三个操作符

char a[10] ;
sanf("%s",a);
//[] 这个是匹配字符,-这个是连接字符
sanf("%[0-9]s",&a);
//在输入字符串的时候,只有0-9才会输入进去缓冲区,如果匹配到了字母就会立刻截断
//15656fadgf,输入这串东西,回车清空缓冲,a=1565,遇到字符直接截断
sanf("%[^0-9]s",&a);
//^这个是不匹配字符,如果输入了0-9就会截断、
//fafaf948,a=fafaf

运算符

逗号运算符:会把最后一个赋值给接收的变量

int a = 1,b = 2,c = 3;
int c = 0;
c = a,b++,++c;
//结果是c = a = 1;b = 3;c = 4;
/* 截断 */
int a = 1,b = 2,c = 3;
int c = 0;
c = (a,b++,++c);
//结果是c = 4;a = 0;b = 3;c = 4;

注意关系运算符的结果基本都是int型

逻辑与&&潜规则(expression1 && expression2)在这两个表达式中,如果第一个表达式为假,他不会执行第二个表达式。

逻辑或||潜规则(expression1 || expression2)在这两个表达式中,如果第一个表达式为真,他不会执行第二个表达式。

语句

;//这个是空语句
lable://有冒号的是标签语句  case default 都算
goto return break continue//跳转语句
7+a;//表达式语句,要有运算符和操作对象(可以是变量或常量)
if switch//选择语句
{}//复合语句

循环语句:

while(表达式){}:首先会执行表达式,然后进入符合语句,再去判断表达式依次循环

do{}while(表达式);:首先会执行复合语句,然后在进入表达式,然后再执行复合语句,依次循环

for(表达式1;表达式2;表达式3){}:先执行表达式1,在进入这个循环的时候,表达式1只执行一次,然后执行表达式2,然后执行符合语句,然后执行表达式3,然后执行表达式2,依次循环。

数组

//数组的定义
int buf[5];   char buf[6];
//初始化
int buf[5] = {1};//这样子表示把第一个元素赋值为1,其他元素系统自动赋值为0

给所有的数组一次性赋值
如果想要一次性给所有的数组赋值,那么可以使用这两个函数bzero()和memset()

  • bzero()函数
//函数原型
void bzero(void *s, size_t n);

//包含头文件
#include <strings.h>

函数的作用

传入一个起始地址s,和需要赋值的长度n,然后可以从第一个地址开始的,每一个字节都赋值为\0字符,无返回值

函数参数

参数 说明
void *s 开始赋值的地址
size_t n 从开始到第n个全部赋值(单位字节)
返回值
  • memset()函数
//函数原型

void *memset(void *s, int c, size_t n);

//包含头文件
#include <string.h>

函数的作用

传入一个起始地址s,和需要赋值的长度n,然后将前n个字节都赋值为c,注意是前n个字节。

函数参数

参数 说明
void *s 开始赋值的地址
int c 赋值的数据
size_t n 从开始到第n个全部赋值,每一个字节都一样的值(单位字节)
返回值 s的首地址
  • 无论是定义普通的变量还是数组,数据类型不仅代表定义变量或者元素的宽度,还可以代表偏移一位的大小
//例如,都知道数组名是地址
int buf[5];
//buf+1 --> buf[1],偏移到了下一个元素,也就是说,定义的数据类型可以指定偏移的宽度,buf是第一个元素的地址,+1就代表偏移了4个字节。如果定义的是char型数组,那么+1就会偏移1个字节
int a;//这也是一样的
//&a+1 --> 地址也是偏移了4个字节
  • 定义一个数组int buf[5];如果使用取地址符号&取数组名的地址,&buf那么那就代表整一个数组,意思是地址还是和buf相同的,但是一个代表一个数组的首元素,另一个代表一整个数组
  • 也就是在偏移的时候,代表一个数组的只会偏移一个元素的大小,代表一整个数组会偏移一整个数组的大小
int buf[5];//数组的大小为5*4  首地址0x0000 0000
&buf+1 --> 0x0000 0014 加了20个字节刚好一整个数组的大小,
buf+1 --> 0x0000 0004 加了1个字节,刚好一个元素的大小
  • 如果数组名和sizeof单独遇上,int buf[5]; sizeof(buf);那么他会表示整个数组的大小,意思是得出来的结果是4*5=20,也就是一个数组的大小20,注意只有单独遇上,有运算符都不行
posted @ 2024-06-02 10:12  wuju  阅读(104)  评论(0)    收藏  举报