C语言(一)
1.数据类型
1.1基本类型
C语言已经定义好的,可以直接用的。
-
整型--保存整数
int
--16位机:2个字节 32/64位机:4个字节long int
--16/32位机:4个字节 64位机:8个字节long long
--8个字节short
--2个字节前面加unsigned表示无符号类型
例如
int a; //定义了一个有符号整型变量,可以是负数 unsigned int a; //定义了一个无符号整型变量,保存非负整数 -
字符数据--保存字符
char/unsigned char
--一个字节字符在计算机中是以字符的ASCII码来保存的
-
浮点型--保存小数
float
--4个字节double
--8个字节long double
--16个字节
1.2构造类型
自己创建的类型
- 数组
char arr[] = {};
- 结构体
struct
- 枚举
enum
- 共同体
union
1.3指针类型
带有*标识的: char *p = NULL;
1.4空类型(void)
void main() { ***** return ; } int main() { ***** return 0; } void *p = NULL;
2.变量和常量
2.1C语言中常量的表示方式
-
整型常量
-
字符常量
通常使用单引号 '' 来引用一个字符
转义字符 '\n' 换行符 '\t' 水平制表符
普通字符:
'%'
'a' --- 97
以\开头的是八进制表示的字符
'\101' --- 65 --- 'A'
以\x开头的是十六进制表示的字符
'\x41' --- 65
-
浮点常量
浮点数可以带后缀
f/F/l/L
1.5 //默认为double 1.5f //float 1.5l //long double -
符号常量--宏定义
#define pi 3.14
2.2数据在内存中的存储
2.3C语言中变量的表示方式
变量:在程序运行期间,值可以变化的量。
变量需要定于它才可以使用。
2.3.1变量的定义
//定义变量的语法 变量类型 变量名 {=初始值}; //{}内为可选项 //变量名不能和关键字重名,必须由字母、数字、下划线组成,且不能以数字开头
//定义变量的规范 1.见名知义 2.合理缩写 3.普遍认知
2.3.2变量的含义
变量的本质:
变量的属性:一种表示空间中的值 --右值
一种代表空间 --左值
int a = 10; //a表示空间,将10这个值保存进a这个空间 int b; b = a; //a表示a这个空间中的值
3.整数之间的赋值问题
int a = 100000; short b = a; //语法上行得通
3.1长的赋值给短的
会产生溢出,并且溢出的部分会丢弃,高位舍弃,低位保留。
3.2短的赋值给长的
赋值过程中,要先短边长,如果短的是有符号数据,长的高位补符号位;如果短的是无符号数据,长的高位补0。
//练习1 short int a = -6; int b = a; printf("%d\n", b); //-6 printf("%u\n", b); //2^32 - 6 //练习2 unsigned short int a = -6; int b = a; printf("%d\n", b); //2^16 - 6 printf("%u\n", b); //2^16 - 6 //练习3 short int a = -6; printf("%d\n", a); //-6 printf("%u\n", a); //2^32 - 6 //练习4 char a = 358; printf("%c\n", a); //f printf("%d\n", a); //102
//作业 //分析如下代码的输出结果: printf("%d\n", -1); //-1 printf("%u\n", -1); //2^32 - 1 printf("%d\n", -1u); //-1 printf("%u\n", -1u); //2^32 - 1 printf("%d\n", (char)-1u); //-1 printf("%u\n", (char)-1u); //2^32 - 1 printf("%d\n", (char)-1); //-1 printf("%c\n", 359); //'g' printf("%d\n", (unsigned char)-1); //255 printf("%u\n", (unsigned char)-1); //255 printf("%d\n", 255); //255 printf("%u\n", 255); //255 printf("%d\n", (char)255); //-1 printf("%u\n", (char)255); //2^32 - 1
4.运算符与表达式
运算符:进行运算的某种符号。
操作数:参与某种运算的数据。
表达式:用运算符连接操作数的式子,每个式子都有一个值,成为表达式的值。
1 > 2 //1 2 :操作数 // > :运算符 //1 > 2:表达式 // 0 :表达式的值
4.1运算符的分类
-
按操作数的个数分:
单目运算符、双目运算符、三目运算符
-
按运算属性分:
算数运算符、关系运算符、逻辑运算符、位运算符...
4.2算数运算符
用 + - * / ++ -- 进行运算的符号
用算数运算符连接的式子叫做算术表达式。
4.3关系运算符
判断两个数的关系。
4.4逻辑运算符
&& : 逻辑与
|| : 逻辑或
! : 逻辑非
惰性运算:已经知道的结果不需要再进行运算。
//练习 int a,b,c,d,m,n,k; a = 1; b = 2; c = 3; d = 4; m = 1; n = 1; k = (m = a > b) && (n = c > d); printf("m = %d, n = %d, k = %d", m, n, k); // m = 0, n = 1, k = 0
4.5赋值运算符
赋值符号左右两边的操作数,类型要相同或兼容
int a; a = 26; //类型相同 a = 'a'; //类型不同,但兼容 a = 8.8; //类型不同,但兼容,只保留整数部分 a = "hello world"; //类型不同且不兼容
复合赋值运算符;
+= -= *= /= >>= ...
4.6位运算符
最重要的,常用的,笔试/面试考点
效率高,运算快
4.6.1按位取反
4.6.2按位与
0 & x = 0; 1 & x = x;
4.6.3按位或
0 | x = x; 1 | x = 1;
4.5.4按位左移/右移
- 按位左移规则:溢出的丢弃,低位补零
- 按位右移规则:
- 无符号数:溢出的丢弃,高位补零
- 有符号数:溢出的丢弃,高位补符号位
//练习 //设置一个数的第7位位1,其余位保持不变 x = x | (1<<7); //将一个数的第8位清0,其余位保持不变 x = x & ~(1<<8); //将一个数据的bit0-10,设置为1,其余位保持不变 x = x | ~(-1 << 11); //将一个数据的bit0-10,清除为0,其余位保持不变 x = x & -1 << 11;
4.6.5按位异或
0 ^ x = x; 1 ^ x = ~x;
//练习 //有a、b两个变量,交换他们的值,但是不要借助第三个变量 a = a ^ b; b = b ^ a; a = b ^ a;
4.7条件运算符
唯一的三目运算符。
语法:表达式1?表达式2:表达式3
运算规则:如果表达式1为真,则条件表达式的值为表达式2的值,且不会执行表达式3;
如果表达式1为假,则条件表达式的值为表达式3的值,且不会执行表达式2。
4.8逗号运算符
语法:表达式1,表达式2,……,表达式n
运算规则:先算表达式1,再算表达式2,……,整个逗号表达式的值等于表达式n的值。
4.9强制类型转换
4.10求长度运算符
语法:sizeof(type/value/variable)
返回该类型/值/变量的字节数。
4.11其他
* 指针运算符、取值运算符 & 取地址运算符 . 引用成员变量运算符 普通变量 -> 引用成员变量运算符 指针变量
//作业 //请写出相应的表达式满足1,2,3 //1.对于一个4字节的数值,判断其第n位是否为1 x & (1 << n) == (1 << n) ? 1 : 0; //2.对于一个4字节的数值,将其[n,m](n<m,m<31 m>0)区间内的全部设置为1,其余位保持不变 x = x | ((-1u << (31 - m + n)) >> (31 - m)); //3.对于一个4字节的数值,将其[n,m](n<m,m<31 m>0,n>0)区间内的全部设置为0,其余位保持不变 x = x & ~((-1u << (31 - m + n)) >> (31 - m));
4.12运算符优先级
优先级 | 名称 | 符号 | 结合性 |
---|---|---|---|
1 | 数组取下标 | [ ] | 左结合性 |
1 | 函数调用 | ( ) | 左结合性 |
1 | 取结构和联合体成员 | . -> | 左结合性 |
1 | 自增(后缀) | ++ | 左结合性 |
1 | 自建(后缀) | -- | 左结合性 |
2 | 自增(前缀) | ++ | 右结合性 |
2 | 自减(前缀) | -- | 右结合性 |
2 | 取地址 | & | 右结合性 |
2 | 间接寻址 | * | 右结合性 |
2 | 一元正号 | + | 右结合性 |
2 | 一元负号 | - | 右结合性 |
2 | 按位取反 | ~ | 右结合性 |
2 | 逻辑非 | ! | 右结合性 |
2 | 计算所需空间 | siziof | 右结合性 |
3 | 强制类型转换 | ( ) | 右结合性 |
4 | 乘法类运算符 | * / % | 左结合性 |
5 | 加法类运算符 | + - | 左结合性 |
6 | 移位 | << >> | 左结合性 |
7 | 关系 | < > <= >= | 左结合性 |
8 | 判等 | == != | 左结合性 |
9 | 按位与 | & | 左结合性 |
10 | 按位异或 | ^ | 左结合性 |
11 | 按位或 | | | 左结合性 |
12 | 逻辑与 | && | 左结合性 |
13 | 逻辑或 | || | 左结合性 |
14 | 条件运算符 | ? : | 右结合性 |
15 | 赋值 | = *= /= += -= <<= >>= &= ^= |= | 右结合性 |
16 | 逗号 | , | 右结合性 |
5.C语言的三大结构
顺序结构、选择/分支结构、循环结构
这三个结构可以解决所有的编程问题
5.1顺序结构
C程序的执行顺序都是从main函数开始,依次往下执行。
//第一个C程序:hello world #include <stdio.h> //头文件:包含了类型定义,函数、变量声明 //std:标准 io:输入输出 声明了printf函数 int main() { printf("hello world\n"); return 0; } //main 主函数,所有的c程序有且只有一个main函数 //int 返回值类型 //()内可以设置函数的参数列表 //{}表示一块区域 //printf 标准输出函数 //\n 换行符,表示这是一个行缓冲 //; C语言语句的结束符 //retrun 函数返回 //0 返回值
5.2分支/选择结构
5.2.1 if语句
语法
if(表达式) { 语句块; }
if(表达式) { 语句块1; } else { 语句块2; }
if(表达式1) { 语句块1; } else if(表达式2) { 语句块2; } ...... else if(表达式n-1) { 语句块n-1; } else { 语句块n; }
练习:
//输入两个数,输出其中的较大值 int a,b; scanf("%d\t%d\r", &a, &b); if(a > b) printf("%d\n", a); else printf("%d\n", b); //输入三个数,判断三个数是否可以组成一个三角形 int a, b, c; scanf("%d\t%d\t%d", &a, &b, &c); if (a + b > c && a + c > b && b + c > a) { printf("yes\n"); } else { printf("no\n"); } //输入一个字符,如果这个字符是小写则转换位大写字符,如果是大写字符就转换位小写字符 char ch; scanf("%c", &ch); if (ch >= 'A' && ch <= 'Z') { ch = ch + 32; printf("%c\n", ch); } else if (ch >= 'a' && ch <= 'z') { ch = ch - 32; printf("%c\n", ch); } else { printf("error\n"); } //输入一个学生的考试分数,输出他的成绩等级 /* [90,100) A [80,90) B [60,80) C [0,60) D */ int score; scanf("%d", &score); if (score >= 90 && score < 100) { printf("A\n"); } else if (score >= 80 && score < 90) { printf("B\n"); } else if (score >= 60 && score < 80) { printf("C\n"); } else if (score >= 0 && score < 60) { printf("D\n"); } else { printf("SSS\n"); }
5.2.2 switch语句
语法
switch(表达式) { case 常量表达式1: 语句块1; break; case 常量表达式2: 语句块2; break; ...... case 常量表达式n: 语句块n; break; default: 语句块n+1; break; }
练习
//输入'+''-''*''/''%'' 使用switch计算5和3的正确结果 #include <stdio.h> int main() { char ch; int a, b; scanf("%d%c%d", &a, &ch, &b); switch (ch) { case '+': printf("%d%c%d=%d\n", a, ch, b, a + b); break; case '-': printf("%d%c%d=%d\n", a, ch, b, a - b); break; case '*': printf("%d%c%d=%d\n", a, ch, b, a * b); break; case '/': printf("%d%c%d=%d\n", a, ch, b, a / b); break; case '%': printf("%d%c%d=%d\n", a, ch, b, a % b); break; default: printf("error\n"); } return 0; } //输入一个学生的考试分数,输出他的等级,使用switch语句 #include <stdio.h> int main() { int score; scanf("%d", &score); switch (score/10) { case 10: printf("SSS\n"); break; case 9: printf("A\n"); break; case 8: printf("B\n"); break; case 7: case 6: printf("C\n"); break; default: printf("D\n"); break; } return 0; }
作业
//输入年月日,输出这天是这一年的第几天 #include <stdio.h> int runyear[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int pingyear[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int main() { int year, month, day, disday = 0; printf("请输入年月日\n输入格式:xxxx.xx.xx\n"); scanf("%d.%d.%d", &year, &month, &day); if ((year % 4 == 0 && year %100 != 0) || year % 400 == 0) { printf("闰年\n"); for (int i = 0; i < month - 1; i++) { disday += runyear[i]; } disday += day; } else { printf("平年\n"); for (int i = 0; i < month - 1; i++) { disday += pingyear[i]; } disday += day; } printf("这一天是这一年的第%d天\n", disday); } //输入出生年月日和现在的年月日,计算你活了多少天 #include <stdio.h> int runyear[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int pingyear[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int PinRun(int year) { if ((year % 4 == 0 && year %100 != 0) || year % 400 == 0) { return 1; } else { return 0; } } int main() { int now_year, now_month, now_day; int birth_year, birth_month, birth_day; int dis_day = 0; printf("请输入你的出生年月日\n格式:xxxx.xx.xx\n"); scanf("%d.%d.%d", &birth_year, &birth_month, &birth_day); printf("请输入当前出生年月日\n格式:xxxx.xx.xx\n"); scanf("%d.%d.%d", &now_year, &now_month, &now_day); if (PinRun(now_year) == 1) { for (int i = 0; i < now_month - 1; i++) { dis_day += runyear[i]; } dis_day += now_day; } else { for (int i = 0; i < now_month - 1; i++) { dis_day += pingyear[i]; } dis_day += now_day; } for (int i = birth_year; i < now_year; i++) { if (PinRun(i) == 1) { dis_day += 366; } else { dis_day += 365; } } if (PinRun(birth_year) == 1) { for (int i = 0; i < birth_month - 1; i++) { dis_day -= runyear[i]; } dis_day -= birth_day; } else { for (int i = 0; i < birth_month - 1; i++) { dis_day -= pingyear[i]; } dis_day -= birth_day; } printf("你活了%d天\n", dis_day); }
5.3循环结构
5.3.1 while语句
语法:
while(表达式) { 语句块; } //当表达式的值为真时,执行语句块,直到表达式为假时,结束循环 //如果表达式的值永远为真,我们称之为死循环
练习:
//求100-200之间偶数的和 #include <stdio.h> int main() { int i = 100, even = 0; while(i <= 200) { if (i % 2 == 0) { even += i; } i ++; } printf("%d\n", even); }
5.3.2 do...while语句
语法:
do { 语句块; }while(表达式); //先执行语句块,再判断表达式的是否为真,直至表达式的值为假 //do...while语句的语句块至少会被执行一次
特殊结构
do { 语句块; }while(0); //表示强调这里是一个功能整体
5.3.3 for语句
语法:
for(表达式1; 表达式2; 表达式3) { 语句块; } //规则:先执行表达式1,在判断表达式2是否为真,为真则执行语句块,再执行表达式3,再判断表达式2是否为真,直到表达式2为假退出循环 //for中的三个表达式都可以省略 //如果表达式2没有,默认为真,则为死循环
练习:
//求一个整数的n次方 #include <stdio.h> int main() { int a, b, p = 1; printf("底数:"); scanf("%d", &a); printf("指数:"); scanf("%d", &b); for ( ; b > 0; b--) { p *= a; } printf("%d\n", p); } //输入一个正整数,逆序输出这个整数的每一位 #include <stdio.h> int main() { int a, b; printf("输入一个正整数:\n"); scanf("%d", &a); if (a == 0) { printf("%d", a); } else { while(a != 0) { b = a % 10; a = a / 10; printf("%d", b); } } printf("\n"); } //输入一个正整数,输出他的阶乘 #include <stdio.h> int main() { int a, f = 1; scanf("%d", &a); for (int i = a; i > 0; i --) { f *= i; } printf("%d\n", f); } //判断一个数是否是质数 #include <stdio.h> int main() { int a; printf("请输入一个数:"); scanf("%d", &a); for (int i = 2; i < a; i++) { if (a % i == 0) { printf("不是质数\n"); return 0; } } printf("是质数\n"); } //判断一个数是否为水仙花数 #include <stdio.h> int main() { int num, a, b, c; printf("请输入0-999的数\n"); scanf("%d", &num); a = num / 100; b = num / 10 % 10; c = num % 10; if (a * a * a + b * b * b + c * c * c == num) { printf("%d是水仙花数\n", num); } else { printf("%d不是水仙花数\n", num); } } //输入两个正整数,输出他们的最大公约数,输出他们的最小公倍数 #include <stdio.h> int max(int a, int b) { if (a > b) { return a; } else { return b; } } int main() { int a, b; printf("输入两个正整数\n请输入第一个正整数\n"); scanf("%d", &a); printf("请输入第二个正整数\n"); scanf("%d", &b); for (int i = max(a, b); i > 0 ; i--) { if (a % i == 0 && b % i == 0) { printf("最大公约数是%d\n", i); break; } } for (int i = max(a, b); ; i ++) { if (i % a == 0 && i % b == 0) { printf("最小公倍数是%d\n", i); return 0; } } }
5.4 break和continue
5.4.1 break
用来跳出当前的循环或分支。
5.4.2 continue
立即结束本次循环。
5.5 goto语句
语法:
goto 标识符; //标识符:用来标识一行代码。 //跳转至被标识符标识的那一行代码去执行。
goto是无条件跳转,一般是都是配合if使用。
作业:
1.求表达式a + aa + aaa + aaaa + ... + aaaaa....的值
输入: 2 5
输出: 2 + 22 + 222 + 2222 + 22222
#include <stdio.h> int power(int a, int b) { int p = 1; for ( ; b > 0; b--) { p *= a; } return p; } int main() { int a, n; int num, sum = 0; scanf("%d\r%d", &a, &n); for(int i = n; i >= 0; i--) { num = 0; for(int j = 0; j < i; j++) { num += a * power(10, j); } sum += num; } printf("%d\n", sum); }
2.求一个整型数中二进制表示中有多少个1
//方法一 for(i = 0; i < 32; i++) { if(x & (1 << i)) count++; } //方法2 while(x) { x = x & (x - 1) count++; }
3.打印九九乘法表
#include <stdio.h> int main() { for (int i = 1; i < 10; ++i) { for (int j = 1; j <= i; ++j) { printf("%d*%d=%d\t", j, i, i*j); } printf("\n"); } }
4.求连续的正整数之和,一个正整数,有可能表示为n个连续的正整数之和
15 = 1 + 2 + 3 + 4 + 5
15 = 4 + 5 + 6
15 = 7 + 8
#include <stdio.h> int main() { int num,sum; scanf("%d", &num); for(int i = 1; i <= num/2; i++) { sum = 0; for(int j = i; j <= num/2+1; j++) { sum += j; if(sum == num) { printf("%d=", num); for(int k = i; k <= j; k++) { if(k == i) printf("%d", k); else printf("+%d", k); } printf("\n"); break; } } } printf("not found\n"); return 0; }
5.思考第4题,除了穷举法之外的另一种方法
//not found
本文作者:乐情在水静气同山
本文链接:https://www.cnblogs.com/aalynsah/p/17522549.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)