当前位置: 首页 > news >正文

C基础学习(认真看就能学会C语言)

  • 1、书接上回,运算符的使用
    • 1.1 sizeof运算符
    • 1.2 逗号运算符
    • 1.3 运算符的优先级
  • 2、常用的输入输出函数
    • 2.1 putchar/getchar函数
      • 2.1.1 putchar函数
      • 2.2.2 getchar函数
    • 2.2 puts/gets函数
      • 2.2.1 puts函数
      • 2.2.2 gets函数
    • 2.3 printf/scanf函数
      • 2.3.1 printf函数
      • 2.3.2 scanf函数
  • 3、if...else分支语句
    • 3.1 语法格式
    • 3.2 案例

1、书接上回,运算符的使用

1.1 sizeof运算符

	sizeof运算符用来计算数据类型的占用内存空间的大小,单位为字节。格式:sizeof(数据类型名);64位系统:返回long int类型,使用格式化字符-》%ld32位系统:返回int类型,使用格式化字符-》%d
#include <stdio.h>int main(int argc, const char *argv[])
{
//#define  X86_64
#ifdef  X86_64printf("unsigned char size = %ld\n", sizeof(unsigned char));printf("unsigned short size = %ld\n", sizeof(unsigned short));printf("unsigned int size = %ld\n", sizeof(unsigned int));printf("unsigned long size = %ld\n", sizeof(unsigned long));printf("unsigned long long size = %ld\n", sizeof(unsigned long long));printf("float size = %ld\n", sizeof(float));printf("double size = %ld\n", sizeof(double));printf("long double size = %ld\n", sizeof(long double));
#else printf("unsigned char size = %d\n", sizeof(unsigned char));printf("unsigned short size = %d\n", sizeof(unsigned short));printf("unsigned int size = %d\n", sizeof(unsigned int));printf("unsigned long size = %d\n", sizeof(unsigned long));printf("unsigned long long size = %d\n", sizeof(unsigned long long));printf("float size = %d\n", sizeof(float));printf("double size = %d\n", sizeof(double));printf("long double size = %d\n", sizeof(long double));#endifreturn 0;
}

image-20230407094054767

image-20230407094128062

1.2 逗号运算符

格式:(表达式1, 表达式2, 表达式3,....);最后一个表达式的结果被返回。
#include <stdio.h>int main(int argc, const char *argv[])
{int a = 10;int b = 20;int c = 30;int d = (a++, ++b, --c); // a = 11 b = 21 c = 29 d = 29// 逗号运算符里边的所有的表达式都被执行了,// 只是最后一个表达式的结果被返回。// 在使用逗号运算符时,必须在最外边添加(),不可以省略printf("a = %d, b = %d, c = %d, d = %d\n",a, b, c, d);// int f = ++a,++b; // 错误return 0;
}

1.3 运算符的优先级

运算符优先级从高到低: 单算移关与,异或逻条赋,逗号单 :+(正数) -(负数) ++ -- ~(按位取反)  !(非)算 : + - * / %移 : << >>关 : > < >= <= != ==与 : &(按位与)异 : ^(按位异或)或 :|(按位或)逻 :&& || 条 : ?:赋 : = += -= *= /= %= &= |= ^= <<= >>=逗号 : ,同级运算符结合的问题:单条赋:从右到左结合, 比如:a = b = 1; 从右到左结合,先把1赋值给b,再把b赋值给a剩余的都是从左到右结合比如:a && b && c;  从左到右结合,先进行a && b,结果在&&c
可以参考《运算符优先级.docx》文档,已经上传有道云笔记中。

2、常用的输入输出函数

学习任何一个函数,都要先掌握函数的功能,参数,返回值。
系统提供的函数都有可以使用man查看对应的帮助手册。
man man ---> 查看man的帮助手册1   可执行程序或 shell 命令2   系统调用(内核提供的函数)3   库调用(程序库中的函数)4   特殊文件(通常位于 /dev)5   文件格式和规范,如 /etc/passwd6   游戏7   杂项(包括宏包和规范,如 man(7),groff(7))8   系统管理命令(通常只针对 root 用户)9   内核例程 [非标准man 3 库函数的名字,比如 man 3 putchar

2.1 putchar/getchar函数

2.1.1 putchar函数

#include <stdio.h>
int putchar(int c);|		|	  |---> 函数的形参,调用函数时需要传递一个实参。|		|----> 函数的名字|---> 函数返回值的类型,可以使用对应类型的变量接收函数的返回值功能:输出一个字符到终端
参数:@ c : 要输出的字符1> 可以是一个字符常量2> 可以是一个字符类型的变量3> 可以是一个字符对应的ASCII码值4> 可以是一个整数,输出整数对应ASCII码表中的字符,如果超过ascii码表的最大值,输出一个乱码。5> 可以是一个经过运算的表达式,表达式的结果是一个整数。
返回值:成功返回写到终端上的字符的对应的整数值,失败返回错误码EOF(-1);
#include <stdio.h>
int main(int argc, const char *argv[])
{// 1. 可以传递字符常量 int retVal = putchar('A');// 有可能失败,因此需要进行出错处理if (retVal == -1){printf("输出字符失败\n");return -1;}else{printf("输出字符成功:%c --- %d\n", retVal, retVal);}// 2. 可以传递字符类型的变量char ch = 'a';putchar(ch);putchar('\n');  // 输出一个换行符 // 3. 可以传递一个整数值putchar(97);   // a 的ascii码值为97putchar(10);   // /n 的ascii码值为10// 4. 可以是一个结果为整型的表达式putchar('A'+33); putchar(5+5);return 0;
}

2.2.2 getchar函数

#include <stdio.h>
int getchar(void);
功能:从终端获取一个字符
参数:无
返回值:成功:返回接收字符对应的ascii码值失败:返回错误码EOF(-1)
#include <stdio.h>
int main(int argc, const char *argv[])
{char a, b, c;// 使用getchar连续接收3个字符a = getchar();b = getchar();c = getchar();printf("a = %c, b = %c, c = %c\n", a, b, c);return 0;
}

image-20230407134054886

image-20230407134200192

#include <stdio.h>
int main(int argc, const char *argv[])
{char a, b, c;// 使用getchar连续接收3个字符a = getchar();getchar(); // 处理垃圾字符,只能处理一个垃圾字符b = getchar();getchar();c = getchar();printf("a = %c, b = %c, c = %c\n", a, b, c);return 0;
}

image-20230407134359481

2.2 puts/gets函数

2.2.1 puts函数

#include <stdio.h>
int puts(const char *s);
功能:向终端输出一个字符串
参数:@ s : 输出字符串的首地址1> 可以是字符串常量2> 可以是字符数组的名字3> 可以是指向一个字符串的字符指针
返回值:成功:返回一个非负的整数, 发送成功的字符串的个数(字符串长度+1)失败:返回错误码EOF(-1)注:puts函数在发送字符完成之后,会自动补发一个'\n'换行符
#include <stdio.h>int main(int argc, const char *argv[])
{// c语言的字符串的结尾为'\0',输出字符串时遇到'\0'停止输出// 1. 可以传递一个字符串常量// 字符串发生结束之后自动补发一个'\n'字符int retVal = puts("hello world!!!");// EOF系统提供的错误码,本质就是一个宏定义 // #define  EOF  -1if ( retVal != EOF){printf("发生字符串成功:%d\n", retVal);}else{printf("发生字符串失败\n");return EOF;}puts("");  // 发生一个换行符// 2. 可以传递一个字符数组// 数组名就表示字符数组的首地址char name[20] = "zhangsan";puts(name);// 3. 可以传递一个执行字符串的字符指针char *str_p = "nihao"; // 字符指针指向一个字符串串常量// str_p中存放的就是字符串常量的首地址puts(str_p);// 输出字符串时遇到'\0'结束puts("hello\0world");  // 输出helloreturn 0;
}

2.2.2 gets函数

#include <stdio.h>char *gets(char *s);
功能:从标准输入获取一个字符串
参数:@ s : 将接收的字符串存到哪个地址中
返回值:成功:返回s,及接收字符串的缓冲区的首地址失败:返回NULL注:gets可以接收中断所有输入的字符包括空格,当输入回车时,输入结束,最终会在字符串的结尾补一个'\0'.即使输入的字符串的长度大于接收字符串缓冲区的长度,也可以接收,并不会进行越界的检查,但你在此打印字符串时,就会越界访问内存空间,就会出现段错误。
#include <stdio.h>int main(int argc, const char *argv[])
{// 将接收的字符串存放一个字符数组的缓冲区char buffer[20];   //缓冲区最多接收19个字符,最后存一个'\0'printf("please input a string, char number < 20 > ");// 从终端获取字符串,有多少接收多少,并不会进行越界的检查// 如果越界之后,访问非法空间时,执行程序可能会报段错误// 一旦出现段错误一般都是访问了非法的内存空间。// 在实际的开发中一般解bug遇到最多的错误就是段错误,// 这种错误在程序编译时不会报错,执行时才会报错。char *retVal = gets(buffer);if (retVal == NULL){puts("从标准输入获取字符串失败");return -1;}puts(buffer);return 0;
}

2.3 printf/scanf函数

2.3.1 printf函数

#include <stdio.h>int printf(const char *format, ...);功能:向终端输出一个格式化字符串
参数:@ format : 参数控制格式的字符串@ ... : 可变参数, 可变参数有几个由format中的格式字符决定,可变参数会依次替换format中的格式化占位符,要求参数的类型和格式化字符要一一对应。
返回值:成功返回正数,失败返回负数

格式化字符:

image-20230407150235730

image-20230407150255315

#include <stdio.h>int main(int argc, const char *argv[])
{int x = 0x12345678;printf("Dct x = %d\n", x);printf("Dct x = %u\n", x);printf("Oct x = %o\n", x);printf("Oct x = %#o\n", x);printf("Hex x = %x\n", x);printf("Hex x = %#x\n", x);printf("char c = %c\n", 'A');printf("string str = %s\n", "hello world!");double Pi = 3.141500;printf("Pi = %lf\n", Pi); // 默认输出小数点后6位printf("Pi = %le\n", Pi); printf("Pi= %g\n", Pi);  // 3.1415printf("Pi = %10lf\n", Pi);  // 占10位宽度,默认右对齐, 不足补空格,// 超过10位宽度原样输出printf("Pi = %010lf\n", Pi); // // 占10位宽度, 默认右对齐,不足补0,// 超过10位宽度原样输出printf("Pi = %10.3lf\n", Pi);// 浮点数,.3保留小数的后三位,不足3位补0printf("Pi = %-10.5lf\n", Pi);// - : 左对齐return 0;
}

2.3.2 scanf函数

#include <stdio.h>int scanf(const char *format, ...);
功能:从终端接收数据
参数:@ format : 格式控制字符串@ ... : 可变参数,需要提供的是变量的地址,只有提供的是地址时,才可以将通过终端读取的数据存到变量对应的空间中。
返回值:成功返回正数,失败返回负数。

image-20230407154328201

image-20230407154346962

#include <stdio.h>int main(int argc, const char *argv[])
{char c;// 变量名前加&符号,表示对变量取地址printf("please input char type data > ");scanf("%c", &c);printf("c = %c\n", c);short s;printf("please input short type data > ");scanf("%hd", &s);printf("s = %hd\n", s);int i;printf("please input int type data > ");scanf("%d", &i);printf("i = %d\n", i);float f;printf("please input float type data > ");scanf("%e", &f);printf("f = %e\n", f);char name[20];printf("please input string type data > ");scanf("%s", name);printf("name = %s\n", name);return 0;
}
#include <stdio.h>int main(int argc, const char *argv[])
{
#if  0// 1. 可以同时接收多个参数int a, b;printf("please input two number(int,int) > ");// 当输入多个参数时,多个参数的输入可以以空格,tab键,回车分隔,// 系统会自动的吃掉空格,tab键和回车符。scanf("%d%d", &a, &b);printf("a = %d, b = %d\n", a, b);
#endif 
#if  0// 2. scanf格式化字符串中除了格式化字符以外,// 还有很多其他的字符,需要按照格式化字符串原样进行输入,// 否则结果出错int year,mouth,day;printf("please input year, mouth, day > ");scanf("year=%d,mouth=%d,day=%d", &year,&mouth,&day);printf("%d:%d:%d\n", year,mouth,day);
#endif 
#if 0// 3. scanf默认不可以获取带有空格的字符串,// 默认遇到一个空格之后,输入结束char name[20];// printf("please input your name > ");// scanf("%s", name);// printf("name = %s\n", name);// 方式1:使用gets可以接收带空格的字符串// printf("please input your name > ");// gets(name);// printf("name = %s\n", name);// 方式2 : 使用[^\n]符号,除了\n以外的所有字符都接收printf("please input your name > ");scanf("%[^\n]s", name);printf("name = %s\n", name);
#endif #if 0// 以下几种情况,当输入数据之后,系统无法自动吃掉// 空格,tab键,回车符,scanf函数处于阻塞无法退出,// 当按下任意一个字符之后,在回车就会退出。// 因此在使用scanf函数时,格式化字符串的结果不要有// 空格, \t \n \rint a, b, c;//scanf("%d\n", &a);scanf("%d\t", &b);// scanf("%d ", &c);
#endif#if 0 // 将\n \t \r, 空格写到格式化字符的前边,// 系统会自动的吃掉\n,\t,\r,空格。int a, b, c;//scanf("\n%d", &a);scanf("\t%d", &b);// scanf(" %d", &c);
#endif return 0;
}

image-20230407160036020

scanf接收字符时,处理垃圾字符的问题。

#include <stdio.h>int main(int argc, const char *argv[])
{int a, b;char oper;printf("请输入一个表达式(l # r) > ");// 输入三个参数时,三个参数以空格分割,空格也是一个字符// 被%c接收之后,赋值给oper,对于程序来说,空格就是一个// 垃圾字符,需要处理垃圾字符// scanf("%d%c%d", &a, &oper, &b);// 方式1:使用%*c 吃掉一个垃圾字符
#if 0// scanf("%d%*c%c%*c%d", &a, &oper, &b);scanf("%d", &a);scanf("%*c");  // 吃掉垃圾字符scanf("%c", &oper);scanf("%*c");scanf("%d", &b);
#endif // 方式2:使用getchar()函数接收一个垃圾字符scanf("%d", &a);getchar();   // 吃掉垃圾字符scanf("%c", &oper);getchar();scanf("%d", &b);// 在接收字符类型的变量时需要思考是否需要吃掉垃圾字符if (oper == '+'){printf("a + b = %d\n", a + b);}if (oper == '-'){printf("a - b = %d\n", a - b); }return 0;
}

3、if...else分支语句

3.1 语法格式

1. ifif (表达式){C语句块;}执行过程:“表达式”成立,执行“C语句块”,“表达式”不成立,跳过“C语句块”,向下继续执行2. if...else...if (表达式){C语句块1;}else {C语句块2;}执行过程:“表达式”成立,执行“C语句块1”,“表达式”不成立,执行“C语句块2”,执行完成之后在向下执行3. if...else if ... else...if (表达式1){C语句块1;}else if (表达式2){C语句块2;}else if (表达式3){C语句块3;}...此处省略很多else if...else		/* else 分支可以省略不写*/{C语句块n;}执行过程:判断表达式1是否成立,如果成立执行C语句块1,执行完C语句块1之后,后边的所有的判断都不在进行判断,即使成立。如果表达式1不成立,则判断表达式2,如果成立执行C语句块2,执行完C语句块2之后,后边的所有的判断都不在进行判断,即使成立。其他的都是一样的依次类推。只有前边所有的表达式都不成立时,才会执行else分支对应的C语句块n.表达式:只要是一个可以表示真假的表达式都可以。一般为逻辑表达式,判断表达式

3.2 案例

1. 从终端输入一个字符,判断字符为大写字符,小写字符,数字。
#include <stdio.h>int main(int argc, const char *argv[])
{char ch;printf("please input a char > ");scanf("%c", &ch);if (ch >= 'a' && ch <= 'z'){printf("%c是一个小写字符\n", ch);}else if (ch >= 'A' && ch <= 'Z'){printf("%c是一个大写字符\n", ch); }else if (ch >= '0' && ch <= '9'){printf("%c是一个数字\n", ch); }else{printf("%c既不是大小写字符,也不是数字\n",ch);}return 0;
}
-------------------------------------#include <stdio.h>int main(int argc, const char *argv[])
{char ch;printf("please input a char > ");scanf("%c", &ch);if ((ch < 'a' || ch > 'z') && (ch < 'A' || ch > 'Z') && (ch < '0' || ch > '9')){printf("%c既不是大小写字符,也不是数字\n",ch);return -1;}if (ch >= 'a' && ch <= 'z'){printf("%c是一个小写字符\n", ch);}else if (ch >= 'A' && ch <= 'Z'){printf("%c是一个大写字符\n", ch); }else{printf("%c是一个数字\n", ch); }return 0;
}
从终端输入薪资,选则不同的交通工具。
#include <stdio.h>
int main(int argc, const char *argv[])
{int salary;printf("请输入你的薪资 > ");scanf("%d", &salary);if (salary < 0){printf("输入的薪资不合理请重新输入\n");return -1;}if (salary <= 10000){printf("地铁\n");}else if (salary <= 30000){printf("出租\n");}else if (salary <= 50000){printf("自驾\n");}else if (salary <= 100000){printf("专职司机\n");}else{printf("自由选择\n");}return 0;
}
练习题1:在终端输入一个整数,用来表示学生的成绩输出学生成绩对应的等级[90,100]	A[80, 90)	B[70, 80)	C[60, 70)	D[0,60)		E
#include <stdio.h>
int main(int argc, const char *argv[])
{int score;printf("请输入成绩 > ");scanf("%d", &score);if ( score < 0 || score > 100){printf("输入成绩不合理请重新输入\n");return -1;}if (score >= 90 && score <=100){printf("等级A\n");}else if (score >= 80 && score < 90){printf("等级B\n");}else if (score >= 70 && score < 80){printf("等级C\n");}else if (score >= 60 && score < 70){printf("等级D\n");}else{printf("等级E\n");}if (score >= 90 /*&& score <=100*/){printf("等级A\n");}else if (score >= 80 /* && score < 90 */){printf("等级B\n");}else if (score >= 70 /* && score < 80 */ ){printf("等级C\n");}else if (score >= 60 /* && score < 70 */){printf("等级D\n");}else{printf("等级E\n");}// 如果if...else分支中只有1条c语句,可以省略{}if (score >= 90)printf("等级A\n");else if (score >= 80 && score < 90)printf("等级B\n");else if (score >= 70 && score < 80)printf("等级C\n");else if (score >= 60 && score < 70)printf("等级D\n");elseprintf("等级E\n");return 0;
}
练习题2:在终端输入一个整数,用来表示年份,输出这一年是平年还是闰年闰年:能被4整除且不能被100整除,或者能被400整除#include <stdio.h>
int main(int argc, const char *argv[])
{int year;printf("请输入年份 > ");scanf("%d", &year);if (year <= 0){printf("输入的年份不合理\n");return -1;}if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)){printf("%d年是闰年\n", year);}else {printf("%d年是平年\n", year); }return 0;
}
练习题3:在终端输入三个整数,分别表示三角形的三边长输出能否构成三角形如果能构成三角形,再输出能构成什么类型的三角形:等腰、等边、直角、普通。使用if嵌套。#include <stdio.h>
int main(int argc, const char *argv[])
{int a, b, c;puts("请输入三角形的三个边长(a,b,c) > ");scanf("%d%d%d", &a, &b, &c);if (a <= 0 || b <= 0 || c <= 0){puts("输入的边长至少有一个小于等于0");return -1;}if (a + b > c && a + c > b && b + c > a){puts("可以构成三角形");if (a == b && b == c /* && a == c */ ){puts("等边三角形");}else if (a == b || b == c || a == c){puts("等腰三角形");}else if (a*a + b*b == c*c || a*a + c*c == b*b || b*b + c*c == a*a){puts("直角三角形");}else {puts("普通三角形");}}else{puts("不可以构成三角形");}return 0;
}
http://www.xdnf.cn/news/830323.html

相关文章:

  • 【分布式事务----LCN】LCN原理及使用方式
  • IPMSG(飞鸽传书)协议翻译
  • ipvsadm命令详解
  • Canvas学习:绘制箭头
  • 初识EMC元器件(九)——气体放电管的参数解读及选型应用
  • 【2024版】最新6款漏洞扫描工具来了!(附下载)看完这一篇就够了
  • 矩阵式管理
  • 可怕的冷读术:十二种瞬间打开陌生…
  • 10种JavaScript特效实例
  • 称呼大全,亲戚称呼,祖宗十八代的称呼!
  • 使用Citavi进行文献管理,常用宏
  • MSDE安装和配置提示
  • docker与gosu(1),Golang平台HTTPS抓包解决方案及问题分析
  • RestTemlate源码分析及工具类设计
  • 通译www.djangobook.com之第二十一章:调度Django
  • [矩阵的三角分解系列四] 乔累斯基(Cholesky)分解公式
  • DNF2020年全新脚本展示第三部分
  • SATA接口-SATA和PATA的区别(ATA 设备 )
  • 网关、安全网关?与防火墙的区别?
  • Linux常用命令大全总结及讲解(超详细版)
  • 产品体验测评:使用阿里云操作系统智能助手OS Copilot解锁操作系统运维与编程
  • IDEA常用快捷键记录
  • 【采集软件】根据关键词批量采集小红薯,含笔记正文、笔记链接、发布时间、转评赞藏等
  • HarmonyOS开发指南:鸿蒙编译工具链
  • 深入浅出理解Allan方差分析方法
  • ubuntu or kylinos软件安装错误的终极解决方案
  • HBT机制
  • 四种常见的登录方案
  • 冒泡排序算法详解之C语言版
  • spss分析方法-因子分析(转载)