@TOC
前言:
1.初学习了c语言,感觉还是很不错的,哈哈~~。下面让我来分享下我目前对c的认识
题外:后面有关于c语言风格培养的《高质量的c-c++编程》PDF版链接,有需要自拿。哈哈~~。
一.初识c语言
1.1计算机语言的发展过程:由需求促进发展,由不成熟逐渐成为流行。
1.2什么是c语言?
选择C语言的理由:==流行性,高效性,可移植性高,强大而灵活,面向程序员==。
简单的c程序
#include<stdio.h>
int main()
{
printf("helloworld!");
return 0;
}
![image-20210718085659275 image-20210718085659275](https://ucc.alicdn.com/images/user-upload-01/img_convert/18ba5c3bb0bd79cf7cafb6a3a05736ca.png?x-oss-process=image/resize,w_1400/format,webp)
三.c语言的语法规则
3.1 c中的数据类型:整形,浮点型,字符型及其所占空间大小
整型 |
名字 |
int |
(普通整形), |
short (int)可以省略(int) |
短整形 |
long |
长整形 |
long long |
更长的整形 |
unsigned int |
无符号(—)整形(只能为正) |
signed int |
有符号整型(一切整数) |
==浮点型:== |
名字 |
float |
单精度浮点数型 |
double |
双精度浮点型 |
3.1.2 每种数据类型的在内存中的大小
![image-20210718095315310 image-20210718095315310](https://ucc.alicdn.com/images/user-upload-01/img_convert/7472c28bec4b72cad1ceb53a8f85f8a9.png?x-oss-process=image/resize,w_1400/format,webp)
补充:
1.sizeof(类型) |
1.它是==运算操作符==,不是函数 |
2.它用于测定数据在内存中的字节(byte)大小,字符串结束标志‘\0’也要被计算内存。 |
2.strlen(字符数组名) |
1.它是==函数==,不是操作符。 |
2.它用于测定字符数组长度。在测定长度时以'\0'为字符串结束标志。 |
3.字节(byte)
计算机的单位:
内存单位 |
名字 |
补充 |
bit |
比特 |
计算机最小内存单元 |
byte |
字节 |
1byte=8bit |
kb |
|
1kb=1024byte |
mb |
|
1kb=1024kb |
gb |
|
1kb=1024mb |
tb |
|
1kb=1024gb |
pb |
|
1kb=1024tb |
而对于数据类型我们规定:
类型 |
内存大小 |
整型(int) |
4个字节(32bite位) |
短整形(short) |
2个字节(16个bite位) |
long long型 |
8个字节。 |
类型 |
内存大小 |
字符型 |
一个字节(8个bite位)。 |
类型 |
内存大小 |
单精度型(float) |
4个字节(32个bite位) |
双精度型(double) |
8个字节(64个bite位)。 |
3.2变量,常量
3.2.1.变量:可以随时改变的量(数据).如:年龄,身高等;
3.2.2.常量:不能改变的量(数据)。如:圆周率,血型等。
3. 2.3定义变量的方式:
数据类型+自定义数据名称+初始化+语句结束标志“;”(分号)
==初始化依据条件可以不进行初始化。==
如 年龄是==整形==数据
身高是==浮点型==数据
字母是==字符型==数据
int age=19;
float length=170f;
char a='w';
3.2.4变量的使用:
#include<stdio.h>
int main()
{
int age=19;
float length=170f;//c默认浮点型数据为double型,如果非要float,只需要在后面加f;
char name[]="***";//名字是由多个字符组合成的,因此在c中我们定义字符数组来表示字符串;
printf("年龄=%d\n",age);
printf("长度=%f\n",length);
printf("名字=%s",name);//以字符串的形式打印字符数组name中的每个元素;
return 0;
}
3.2.5变量的分类
局部变量:
全局变量:
==注意==
3.2.6变量的作用域与生命周期————==有效使用变量==
局部变量:
2.生命周期: |
局部变量自创建的==一对{}始==,到==出这对{}为止==,这段==时间为其生命周期;==** |
==right:==
![image-20210718145758136 image-20210718145758136](https://ucc.alicdn.com/images/user-upload-01/img_convert/67ba23d3950f4c45870ee8d067fa4f85.png?x-oss-process=image/resize,w_1400/format,webp)
![image-20210718150004939 image-20210718150004939](https://ucc.alicdn.com/images/user-upload-01/img_convert/c31865b9706b539f7efbb5bec869928b.png?x-oss-process=image/resize,w_1400/format,webp)
==error==
![image-20210718150314601 image-20210718150314601](https://ucc.alicdn.com/images/user-upload-01/img_convert/a7d370d1919afba93c7c41763f9fbdb4.png?x-oss-process=image/resize,w_1400/format,webp)
==思考==
#include<stdio.h>
int main()
{
{
int a=1;
printf("%d\n", a);
}
printf("%d\n", a);
return 0;
}
#include<stdio.h>
int main()
{
int a = 1;
{
int a=1;
printf("%d\n", a);
}
printf("%d\n", a);
return 0;
}
全局变量: |
1.作用域:自创建到程序结束的任何地方都可以使用。 |
2.生命周期:自创建到程序结束为其生命周期。 |
3.2.7常量:
1.字面常量:血型,名字等
2.const修饰常变量(==一旦const就不可更改==):
#include<stdio.h>
int main()
{
const int a=19;
a=22;//变量一旦const就不可更改,重新赋值。
printf("%d",a);
return 0;
}
3.#define定义的标识符常量
![](https://ucc.alicdn.com/images/user-upload-01/img_convert/a980ccde0e9af962fa84500203cabf9b.png?x-oss-process=image/resize,w_1400/format,webp)
==注意==
![image-20210718154601516 image-20210718154601516](https://ucc.alicdn.com/images/user-upload-01/img_convert/024d1dba53f83e5a7952e1041b99c3ba.png?x-oss-process=image/resize,w_1400/format,webp)
==分析==:
4.枚举常量
![image-20210718155806841 image-20210718155806841](https://ucc.alicdn.com/images/user-upload-01/img_convert/5cc7e9b26889de8bbebef4536ad5a1da.png?x-oss-process=image/resize,w_1400/format,webp)
![image-20210718160620143 image-20210718160620143](https://ucc.alicdn.com/images/user-upload-01/img_convert/8a59746758eebb777bd9eb0de671f0ee.png?x-oss-process=image/resize,w_1400/format,webp)
3.3字符与字符串+转义字符+注释;
3.3.1.字符与字符串:
字符:像‘w’这种由一对‘ ’所引用的字符。
字符串:”name“像这种用一对” “所引用的连续字符,称为字符串。
因为c语言中没有字符串型数据,因此我们用字符数组定义字符串;![image-20210718161734039 image-20210718161734039](https://ucc.alicdn.com/images/user-upload-01/img_convert/abcff8fc8ac2e9ac7db3601cc1ed80d4.png?x-oss-process=image/resize,w_1400/format,webp)
3.3.2.转义字符:
补充:
![](https://ucc.alicdn.com/images/user-upload-01/6a0e4ab6ca594fcaa2a8666016845d21.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzU1NDM5NDI2,size_16,color_FFFFFF,t_70#pic_center&x-oss-process=image/resize,w_1400/format,webp)
==注意==
![image-20210718162612966 image-20210718162612966](https://ucc.alicdn.com/images/user-upload-01/img_convert/eff3ac4fcdaea0c35b3f9ae952d10b7a.png?x-oss-process=image/resize,w_1400/format,webp)
==注意==
![image-20210718165013546 image-20210718165013546](https://ucc.alicdn.com/images/user-upload-01/img_convert/2ca716236d6e1c2f79dd05effe123778.png?x-oss-process=image/resize,w_1400/format,webp)
![image-20210718164745807 image-20210718164745807](https://ucc.alicdn.com/images/user-upload-01/img_convert/04caf60b60c8079224d354b8d0692ecb.png?x-oss-process=image/resize,w_1400/format,webp)
3.3.3.注释
1.在c程序中我们想解释自己的程序时,我们常使用“//”; |
2.在c程序中我们想保留部分程序,不让其起作用时, |
==注意==
![image-20210718172413204 image-20210718172413204](https://ucc.alicdn.com/images/user-upload-01/img_convert/3ab76dd92cd00e3621312a0a7f048650.png?x-oss-process=image/resize,w_1400/format,webp)
3.4 c语言的3种结构:顺序,选择,循环。
3.4.1顺序:一步一步执行代码。
3.4.2选择结构(分支语句):
==注意==
3.4.2.1 if语句
1.if语句的==2种==形式
第一种
if(表达式){语句体}
else 语句体
第二种
if(表达式){语句体}
else if(表达式) {语句体}
....
else 语句体
==注意==
1.我们规定==else==与==最近的====if==匹配. |
2.注意if语句体中的==关键字==break,continue; |
==看题==
#include <stdio.h>
int main()
{
int a = 0;
int b = 2;
if(a == 1)
if(b == 2)
printf("hehe\n");
else
printf("haha\n");
return 0;
}
思考这题的输出结果
答案:
什么都不输出思考注意中的第一点
2 .switch语句:
1.switch语句的形式
switch(整形表达式)
{
case 整形常量表达式:语句;
....
}
==注意==
1.switch中的整形表达式==不可以==为==浮点型数据==,但可以为,枚举类型(可以当作是整形常量),==字符型数据==(计算机在碰到字符新数据时会将它==自动转化为整形==进行运算)(==图一==) |
2.case 中的必须为==整形常量==,或者是枚举类型(枚举也看以看作是一种特殊常量) |
3.switch中的==关键字====break==是用于==分开语句块==的。且==不能使用==关键字==continue==;(==图二==) |
4.当执行的case没有break作为跳出switch时,其会==,默认==继续执行下面的case,直到再次遇到break;(图三) |
5.虽然switch中的==default==是==默认选项==的意思,但使用时多留意其前面==是否有====break==;再次体现==第三点==的==重要性==(图四) |
6.default 可以放在switch语句体内的==任意位置== |
==看图==
图一
![image-20210719232840650 image-20210719232840650](https://ucc.alicdn.com/images/user-upload-01/img_convert/f2cbf4e4393aa699dfa6834ad3a87a73.png?x-oss-process=image/resize,w_1400/format,webp)
![](https://ucc.alicdn.com/images/user-upload-01/img_convert/e5414a6abd290e8dec9ccf6a1e27376e.png?x-oss-process=image/resize,w_1400/format,webp)
图二
![image-20210719233713420 image-20210719233713420](https://ucc.alicdn.com/images/user-upload-01/img_convert/a2e305353285002a10e7e0ee101f51e0.png?x-oss-process=image/resize,w_1400/format,webp)
图三
![image-20210721091522206 image-20210721091522206](https://ucc.alicdn.com/images/user-upload-01/img_convert/2da206d74150f760d08251fe2b756d28.png?x-oss-process=image/resize,w_1400/format,webp)
图四
![image-20210719234517389 image-20210719234517389](https://ucc.alicdn.com/images/user-upload-01/img_convert/ce7c4ffb5f5c12097d962ac2770d4638.png?x-oss-process=image/resize,w_1400/format,webp)
==问题==
#include<stdio.h>
int main()
{
int n = 1;
int m = 2;
switch (n)
{
case 1:
m++;
case 2:
n++;
case 3:
switch (n)
{//switch允许嵌套使用
case 1:
n++;
case 2:
m++;
n++;
break;
}
case 4:
m++;
break;
default:
break;
}
printf("m = %d, n = %d\n", m, n);
return 0;
}
答案:
![image-20210721092529211 image-20210721092529211](https://ucc.alicdn.com/images/user-upload-01/img_convert/6cdfba9604f506ebf75cc1ea52e971c0.png?x-oss-process=image/resize,w_1400/format,webp)
分析:(1)-》(2)-》(3)-》(4)-》(5)
(1)先执行外面的swtich,n为1,执行case 1,后m=3.因为其后无break,进行执行case。 |
(2)执行case 2-》m=3,n=2. |
(3)执行case 3->,执行内嵌的switch中的case 2-》m=4,n=3,遇到break,跳出内部switch |
(4)执行case 4-》m=5.遇到break,跳出外部switch; |
(5)m=5,n=3; |
3.4.3循环结构:while,do while,for循环;
1.while语句形式
==while(表达式){语句体}==
当==表达式====为真==是,执行语句体.
2.do ..while语句形式
do{语句体}while(表达式)==;==
==先==执行==语句体==,后判断==表达式==
3.for语句形式
==for(表达式1,表达式2,表达式3)==
表达式1:
表达式1为==初始化部分==,用于初始化循环==变量==的。
表达式2:
表达式2为条件==判断部分==,用于判断循环时候==终止==。
表达式3:
表达式3为==调整部分==,用于循环条件的==调整==。
==注意==
1.while的==执行条件==始终比==循环体====多一次==。 |
2.do while语句注意语句==结束==要有==分号"";“==,且其==循环体==始终与==表达式==执行次数一致。 |
3.brake只能跳出==一层==循环(当内循环结构时,只能跳出内部一层循环结构) |
4.continue只能跳出==本次==循环。 |
==练一练==
打印9*9乘法表
for()形式
int main()
{
int i = 0;
int j = 0;
for (i = 0; i < 10; i++)
for (j = 1; j <= i; j++)
{
printf("%d*%d=%-2d", i, j, i * j);
if (j == i)printf("\n");
}
return 0;
}
分析:通过i控制行,j控制列.
while形式
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
int main()
{
int i = 1;
int j = 0;
while (i < 10)
{
j = 1;
while (j <= i)
{
printf("%d*%d=%-3d", i, j, i * j);
j++;
}
printf("\n");
i++;
}
return 0;
}
分析:外层循环控制行,层控制列
do while形式
int main()
{
int i = 1;
int j = 0;
do
{
j = 1;
do
{
printf("%d*%d=%-3d", i, j, i * j);
j++;
} while (j <= i);
printf("\n");
i++;
} while (i<10);
return 0;
}
分析:外层循环控制行,层控制列
3.5函数
函数形式:
返回值类型+函数名+(形参1,形参2,..)
#include<stdio.h>
int add(int x,int y)
{
return x+y;
}
int main()
{
int a = 0;
int b = 0;
int c = 0;
scanf("%d%d",&a,&b);
c=add(a,b);
printf("%d\n",c);
return 0;
}
函数声明形式:
返回值类型+函数名+形式类型+”;“
#include<stdio.h>
int main()
{
int add(int x,int y);//函数声明
int a = 0;
int b = 0;
int c = 0;
scanf("%d%d",&a,&b);
c=add(a,b);
printf("%d\n",c);
return 0;
}
int add(int x,int y)
{
return x+y;
}
==注意==
1.自定义的函数要有返回值. |
2.自定义的函数可以放在main函数的前面,或者后面(在后面的时候,要在main函数中提前声明)。 |
3.实参传递数据到形参时,参数类型要相同,不然会丢失部分数据。 |
3.7数组
3.7.1数组的定义:
数组元素类型+数组名+【数据数量】;
int arr[10]={1,2,3,4,5,6,7,8,9,10};
3.7.2数组下标:
int arr[10]={1,2,3,4,5,6,7,8,9,10};
数组长度是10,下标从==0~9==;
3.7.3数组的使用
#include <stdio.h>
int main()
{
int i = 0;
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
for(i=0; i<10; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
==注意==
1.数组下标小于数组长度,且其最大值为数组长度-1; |
2.数组名是数组的首地址; |
==看题==
下面程序有问题吗?
#include<stdio.h>
int main()
{
int i = 0;
int arr1[10]={0};
char arr2{10}={0};
char arr3[10]={'0'};
printf("%d\n",arr1[0]);
printf("%c\n",arr2[0]);
printf("%c\n",arr3[0]);
return 0;
}
![image-20210721172234931 image-20210721172234931](https://ucc.alicdn.com/images/user-upload-01/img_convert/1500883d28ee862a7fde37a3c10cb8f8.png?x-oss-process=image/resize,w_1400/format,webp)
==分析:==
arr1[0]被初始化为0;arr2[0]被初始化为0;arr3[0]被初始化为字符'0'; |
0 对于int 型 就是数字0,但对char ,在ASII表中是 空 的意思,即没有任何意义(NULL)。 |
字符'0'对于char 型是字符串结束标志。 |
|
3.8操作符
3.8.1算术操作符:
+,-,*, /,%
==注意==
除法的2种情况: |
/的前后==都是====整形数据==时,对结果==取整==。 |
/的前后==存在====浮点数==时,结果就是==浮点数==。(图一) |
#include<stdio.h>
int main()
{
int a =0;
int b =0;
int c2 =0;
float c2 =0;
scanf("%d%d",&a,&b);
c1=a/b;
c2=a/b;
printf("%d\n",c1);
printf("%f\n",c2);
return 0;
}
![image-20210721181102475 image-20210721181102475](https://ucc.alicdn.com/images/user-upload-01/img_convert/aaa28458bbaefc8459efc859d66c5204.png?x-oss-process=image/resize,w_1400/format,webp)
3.8.2位移操作符:
<<,左位移操作符
>>右位移操作符
它们移动的是补码
==补码补充==
1.计算机在内存中处理数据,都是按数据的==补码==形式进行运算的,最后以==原码==的形式表现数据。 |
2.正数与0的,原码,反码,补码是一样的。 |
3.负数的==原码==是==按正数==编时的==二进制原码==;==反码==是原码==除符号位==,其它位==取反==;==补码==是==反码+1==。 |
==题目==
#include<stdio.h>
int main()
{
int a=-1;
int b=-1;
printf("%d\n",a<<2);
printf("%d\n",b>>2);
return 0;
}
![image-20210721184143358 image-20210721184143358](https://ucc.alicdn.com/images/user-upload-01/img_convert/70dc918107f0bd12545a69115ee01acd.png?x-oss-process=image/resize,w_1400/format,webp)
![image-20210721191836386 image-20210721191836386](https://ucc.alicdn.com/images/user-upload-01/img_convert/5894706d3abf8d9ace889da9a9554857.png?x-oss-process=image/resize,w_1400/format,webp)
3.8.3位操作符:&,|,^
==注意==
运算符 |
功能 |
运算规则 |
& |
按位与 |
对应位均为1时,才位1,否则为0 |
\ |
|
按位或 |
对应位存在1时就为1 |
^ |
按位与或 |
对应位相同为0,相异为1 |
<< |
左移 |
补码左移若干位,超出丢弃(不包括1),剩下补0,每左移一位,相当于多乘2; |
>> |
右移 |
补码右移若干位,正数左补0,负数左补1,右边溢出丢。 |
3.8.4赋值操作符:=,+=,-=,*=,/=,&=,|=,<<=,>>=
3.8.5单目操作符:
==单目操作符表==
单目操作福 |
功能 |
! |
逻辑反操作 |
- |
负值 |
+ |
正值 |
& |
取地址 |
sizeof |
就类型长度(以字节为单位) |
~ |
对一个数的补码按位取反 |
-- |
前置:先自减,后应用;后置:先应用,后自键 |
++ |
前置:先自增,后应用;后置:先应用,后自增 |
* |
间接访问操作符(解应用操作符) |
(类型) |
强制类型转换 |
3.8.6关系操作符:
>,,>=,<,<=,==,!=;
3.8.7逻辑操作符(==双目运算符==):
逻辑操作符 |
功能 |
&& |
且,只有当2边逻辑都为真是才为真 |
\ |
\ |
|
或,一边为真即为真 |
3.8.8条件操作符
3.8.9逗号表达式:
exp1,exp2,exp3....
==注意==
逗号表达式的==运算结果==以最后一项为准。
==看图==
![image-20210721195412928 image-20210721195412928](https://ucc.alicdn.com/images/user-upload-01/img_convert/8ddd32eecbe09c425d137b3f9d97fca5.png?x-oss-process=image/resize,w_1400/format,webp)
3.8.10下标引用[],函数调用(),结构体成员->.
3.9关键字
关键字 |
功能 |
auto |
存储类别说明关键字(局部变量) |
break |
终止一层循环 |
case |
swtich语句中的case |
char |
字符数据类型说明关键字 |
const |
将变量定义为长量 |
continue |
结束本次循环,直接执行下次循环 |
default |
switch语句中,当没有满足case的情况,默认执行default语句 |
do |
do {}while();语句中的关键字 |
double |
双精度数据类型说明关键字 |
else |
与最近if匹配的else分支语句 |
enum |
枚举变量的说明关键字 |
extern |
提前告知变量,函数等出现在别的文件中 |
float |
单精度数据类型说明关键字 |
for |
for的说明关键字 |
goto |
C语言中提供了可以随意滥用的 goto语句和标记跳转的标号。 |
if |
分支语句说明关键字 |
int |
整形数据说明关键字 |
long |
更大整形说明关键字 |
return |
返回某种类型的值,结束函数 |
short |
短整形说明关键字 |
signed |
有符号型说明关键字 |
sizeof |
测定数据占内存空间的大小,单位字节 |
static |
静态成员说明关键字(具体说明看下面) |
struct |
结构体说明关键字 |
switch |
swtich分支语句关键字 |
typedef |
重新定义数据类型==别名==:typedef unint unsigned int |
union |
联合说明关键字 |
unsigned |
无符号整形说明关键字 |
void |
空类型说明关键字 |
while |
while语句说明关键字 |
register |
|
volatile |
|
==注意==
在定义变量,函数名时不能使用关键字
3.9.1static:
1.修饰局部变量:==延长==局部变量==生命周期==,==不改变==其==作用域==(图一) |
2.修饰全局变量:改变全局变量的外联性(可被其它文件使用。extern),使全局变量只能被本模块使用。 |
3.修饰函数:改变函数的外联性(可被其它文件使用。extern),使函数只能被本模块使用。 |
图一
![image-20210721202905771 image-20210721202905771](https://ucc.alicdn.com/images/user-upload-01/img_convert/ead4dff9b2925fb71e181adfb6223d59.png?x-oss-process=image/resize,w_1400/format,webp)
图二
图三
3.10#define定义宏常量和宏
#define+“空格”+宏常量名+常量 |
#define+“空格”+宏名+表达式 |
3.11指针
3.11.1内存:
3.11.2内存是怎么被编号的?
3.11.3地址的存储
3.11.4指针变量:
3.11.5指针的大小:
3.11.6==补充==
3.12结构体
前言
3.12.1结构体定义:
struct+结构体名
{
属性1;
属性2;
.....
};
==注意==
1.定义结构体不可丢==关键字struct== |
2.结构结尾的分号不能丢 |
3.12.2结构体数组:
![在这里插入图片描述 在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/24626e1ae9d34ccfafd6b39681533d52.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzU1NDM5NDI2,size_16,color_FFFFFF,t_70&x-oss-process=image/resize,w_1400/format,webp)
感言:
1.对目前c语言的有些地方学的不深,不敢过多描述。哈哈。
2.在这段学习中,我会了一些小游戏,由其是关机程序,贼有意思!哈哈。后面会补上的。
提取码:2021