·用小乌龟上传文件到gitee时,如果add以后又更改了文件,那文件的图标会变红色,此时 就不用add了 直接commit就可以
常量
常量是不变的量。
- 字面常量
- 20;
- 3.14;
- ‘a’;字符常量
- “abcdefh”;字符串常量
- const修饰的常变量
- const是c语言的一个关键字,用const修饰后的变量则不能被修改了。如下是不能修改成20的。语法不允许修改。
- const修饰后,本质上还是变量。所以不能使用中数组定义时,指定大小。
const int num=10;
num=20;
- #define定义的标识符常量
- #define m 100
- 枚举常量
- enum是关键字
enum Sex
{ MALE, //默认是0
FEMALE //默认是1 这俩就是枚举常量
};
int main(){
enum Sex s=MALE;
return 0;
}
字符串+转义字符+注释
字符串:
"hello\n"
这种由双引号引起的一串字符成为字符串字面值String Literal 或者简称字符串
·注:字符串的结束标志是一个\0的转义字符。在计算字符串长度的时候\0是结束标志,不算字符串的内容。例:
char arr1[]="abc";
char arr2[]={ 'a','b','c'};
printf("%s\n",arr1);
printf("%s\n",arr2);
此时显示的arr1是abc 而arr2则是abc后面跟着随机的内容。
因为arr1是有""的字符串,所以中"abc"实际是"abc\0" 但‘a’这些后面没有\0,会顺着内存里面的往后随机读取,直到读到\0才停止。
·strlen-库函数,用来求字符串的长度。需要#include<string.h>
求的是\0之前出现的字符的个数。
转义字符:如\n \0 转变原来的意思。 是一个字符。
- \? 以前有三字母词,如??)等于]
- 所以以前如果有 printf("(are you ok??)")就会把??)变成一个小方块
- 所以这时候加上\就不会被识别为三字母词了。printf("(are you ok\?\?)")
- \'
- printf("%c",'a')是打印一个字符a
- printf("%c",''')如果想打印一个' 那程序这里会把前面两个''理解为' '空的字符,然后后面又有一个' 就无法识别了。
- printf("%c",'\'')这样就会打印出来一个'
- \"" 同上
- \\
- printf("c:\text\text.c");
- 这里的两个\t \t都会被识别为\t的转义字符
- 所以c:\\test\\test.c就正常了
- 一般写路径都要加上\\
- \ddd -ddd表示1-3个八进制的数字
- printf("%c",'\130')显示的是X
- a--97
- A--65
- @--...
- 把这些字符都编号,即ascii编码。上面,左边是字符,右边是ASCII码的值。(有一个ASCII表可以查询)
- 8进制的130转化成十进制是88
- *8进制是0 1 2 3 4 5 6 7,没有8 9
- \t代表一个字符
- 1*8^2+3*8^1+0*8^0=1*64+3*8+0=88
- 88对应的字符就是X
- \xdd-dd表示两个十六进制数字
- printf("%c",'\x31');
- 31这个16进制转化成10进制:
- 3*16^1+1*16^0=3*16+1*1=48+1=49
- 49作为ASCII码代表的值,即 1
注释:
快捷键: ctrl k c
ctrl k u
1、注释是用来解释代码的 非常重要
2、注释可以注释掉一些不需要的代码
①c语言的注释方法:
/*
*/
缺陷:不支持嵌套
②c++的注释方法: //
选择语句 if switch
if(a==1)
{
printf("yes");
}
if(a==2)
{
printf("no");
}
循环语句 while for do while
while(line<=20000)
{
line++;
}
函数
int Add(int x,int y){
int z=0;
z=x+y;
return z;
}
数组
能够存放一组相同类型的元素,每个数组的元素都有一个下标。下标从0开始。
arr[8]即第9个元素
注意,int arr[ n]其中的n最好不要是变量,在某些编译器里可以,但某些是不行的。
int arr[10]={1,2,3,4,5,6,7,8,9,10};
操作符
- 算术操作符
- + - * / %
- /的两端如果是整数,那结果也是整数 如7/3
- 7.0/3
- 7/3.0 这样有一段是小数,那就是小数除法,结果是2.33333
- %是取余数 7除以3是商2余1,那结果就是1
- + - * / %
- 移位操作符(移动的是二进制位)
- >> <<
- 位操作符(二进制的)
- & ^ |
- 赋值操作符
- = += -= *= ^= |= >>= <<=
- a=a+10 也就是 a+=10
- 单目操作符(a+3 这里的a是双目操作符)
- c语言中,0表示假,非0表示真
- (类型)强制类型转换
- int a=(int)3.14
- * 间接访问操作符(解引用操作符)
- ++ 前置、后置++
- int a=10
- b=++a;先加加后使用 ++a的结果是11 所以b也是11
- a=a+1,b=a;
- b=a++;先使用后加加 a++的结果是11 但b还是10(a都会改变,b不一样)
- b=a++ 拆封即 int b=a ,a=a+1;
- -- 前置、后置--
- ~对一个数的二进制按位取反
- sizeof 不是函数,是操作符。和+—*/一样操作数的类型长度(以字节为单位)(变量也可以算)
- int a=10,sizeof(a)和sizeof(int)结果一样,都是4,算的是int 这个类型的长度
- &取地址
- +正值
- -负值
- ! 逻辑反操作
- (类型)强制类型转换
- 关系操作符
- > >= < <= != ==
- 条件操作符(三目操作符)
- exp1 ? exp2:exp3
-
int a=3; int b=5; int m=0; m=(a>b)?(a):(b);
- 逻辑操作符
- && 逻辑与
- || 逻辑或
- 只关注真和假
-
int a=3; int b=5; if((a==3)&&(b==5)) { printf("hehe"); }
- 逗号表达式
- exp1,exp2,exp3,。。。expN
-
int a=3; int b=4; int c=5; int d=(a -=3,b +=a, c =a-b, b=a-4);
逗号表达式,表达式会从左向右,依次计算
-
整个表达式的结果是最后一个表达式的结果。
- 下标引用操作符、函数调用操作符
- [ ]数组名,下标;是个操作符,和+-*/一样的操作符
- ( ) 函数调用操作符
- .
- ->
常见关键字
是c语言本身提供给我们的;用户自己不能创造关键字。
创建变量的名字不能用关键字。
- auto 自动; --所有的局部变量前 本质上都有auto的,代表到这里自动创建一个变量,结束后自动取消这个变量。只是平时省略了而已;如 auto int a =5;
- register 寄存器
- 电脑的存储区:(从上到下,速度越来越快,空间越来越大)
- 寄存器(集成到cpu上的,速度快->造价高->空间小)
- 高级缓存
- 内存
- 硬盘
- 网盘
- 平时cpu直接从内存中读取数据,但随着发展cpu更牛了,光用内存太大材小用,就开始向高级缓存和寄存器中拿数据,这样效率就上升了。注意这里只是建议,具体放不放看编译器。
-
int num=10; //4个字节 register int num2=20; //建议将20放在寄存器中
- 电脑的存储区:(从上到下,速度越来越快,空间越来越大)
- break用在Switch 和循环中(for while do,while)
- case用在switch里
- char
- short
- int
- long
- float
- double
- const
- continue用在循环中,继续
- enum 枚举关键字
- extern声明外部符号
- 一个工程里创建了两个源文件test.c 此时第二个。c文件想用第一个文件里面的某个变量,第二个要在前面先声明,如:
- extern int gg;
- extern int add(int x,int y);//声明来自外部的函数
- signed有符号的
- unsigned无符号的
- static静态的
- 是用来修饰变量和函数的
- 1 修饰局部变量 成为静态局部变量
- 内存 划分为栈区 堆区 静态区,局部变量一般放在栈区,当用static修饰时,放到静态区了;实际改变的是变量的存储位置。
- 静态区还有全局变量。生命周期比较长。(作用域没有变化,还是原来的作用域)
- 静态区的生命周期和程序的生命周期一致。
- 程序结束,静态数据也就结束。
- 2 修饰全局变量 称为静态全局变量
- 全局变量本来是有外部链接属性的,但是被static修饰后,外部链接属性就变成了内部链接属性
- 只能在自己所在的源文件内部使用,不能在其他文件内使用了。用extern声明也不行。
- 使用上感觉作用域变小了。(有啥用呢?能让别人看不到你的代码)
- 3 修饰函数 称为静态函数
- 函数本身有外部链接属性,如果创建函数时候加上了static就没有外部属性了,只能在自己所在的源文件内部使用,无法被其他源文件使用(和全局变量的情况差不多)
-
局部变量: void test() { int a=5; a++; printf("%d",a); } int main() { int I=0; while(I<10) {test(); I++;} return 0; } // 此时结果是 6 6 6 6 6 6 6 6 6 6 如果 int a=5变成 static int a=5 那结果就变成 6 7 8 9 10 11 12 13 14 15 即a在出其局部范围时,不会被销毁;下一次进入此函数时依然存在。(存在静态区)
- 1 修饰局部变量 成为静态局部变量
- 是用来修饰变量和函数的
- struct-结构体
- typedef类型重命名
-
unsigned int num=10; typedef unsigned int uint; uint num2=10; //和第一行效果一样
-
- union联合体(共用体)
- void 无/空
- volatile 体现c语言段位;c++的linux学
#define定义常量
test.c 源文件 经过【预编译 编译 汇编 链接 运行】,才形成一个test.exe开始运行
#define MAX=1000
int main()
{
int m=MAX;
printf("%d",MAX);
return 0;
}
这里在预编译的时候,会把MAX统统变成1000;即define定义的常量都会在预编译的时候进行替换。
define定义宏
宏的名字一般都是全大写的,习惯;
宏内的变量尽量都用()括起来,因为你不知道这个传过来的x会不会是一长串,那就容易乱
#define MAX(x,y) (x>y?x:y)
宏不用返回,不用输入变量类型;也是在预处理阶段进行处理的
ve
多组输入:
·scanf函数调用成功会返回一个1,调用失败会返回EOF(end of file 文件结束的标志,本质的定义是-1)
int iq=0;
while(scanf("%d",&iq)!=EOF)
{
if(iq>=140)
{ printf("Genius!!!")}
}
·水平制表符 =按键Tab
杂七杂八
计算机要不要考证?
--考试得到的证书无法证明自己的能力。会做题才有意义。
--talk is cheap,show me the code
蓝桥杯和acm?
--蓝桥杯适合普通大众,获奖率比较高,简单些。
--acm比较难,都是校队,大家都是炮灰。这俩都是算法竞赛。有实力可以两个都参加,技术弱参加蓝桥杯就好了。不要把所有时间放上去,企业的招聘要求:1计算机语言,c C++ java 2算法和数据结构 3操作系统和系统编程 4计算机网络+网络编程 5数据库 6实战项目
英语重要吗?
非常重要,但年薪40w前不会成为门槛,长远来看非常重要。
不能证明自己能力的考证基本上都没啥用。
初识指针
要讲清指针必须讲内存。
内存
把内存理解成一个个的小格子,每个格子都有一个自己的编号,相当于我们的地址;
因为地址-->房间
所以有编号(地址)就可以找到这个内存单元(房间);
- 那一个内存单元有多大?
- 一个内存单元=一个字节byte(如果是bit就太小了,比如送快递送到你家就行,不用到你家厕所)
- 内存单元的编号怎么产生?
- 我们有32 、64位的机器
- 32位就代表有32根地址线/数据线
- 地址线--就是物理上的电线--通电--电信号---转化成数字信号,即1/0
- 每根都通电,那就是从0000000000000到111111111111的序列
- (都是32个,一根可以是0可以是1)
- 一共有[2的32次方] 种排列组合;即有[2^32]个序列
- 序列就可以用来当地址;
- 内存单元是有编号的,编号就是内存单元的地址;理论上地址数不超过2的32次方
- 总共可以管理2^32个byte 字节。2^32byte=4294967296byte/1024=4194304kb/1024=4096mb/1024=4gb
- 所以32位实际能管理4gb的内存
- 当我们写int a=10,int是四个字节,所以a就向内存申请了4个字节的地方;
- 我们有32 、64位的机器
- %p 地址的打印
- &取地址操作符
- printf("%p",&a)这里拿到的地址是a的第一个字节的地址
- 内存单元都有编号,这个编号就是地址(一个数字),地址也叫指针
- int a=10 int* pa=&a
- pa是用来存放地址的,所以我们把pa叫指针变量。
- 这个*的意义就是告诉我们,这是个指针
- int告诉我们,pa指向的对象的类型是int类型
- 用的时候:*pa //这个*是解引用操作符 意思是,通过pa中存放的地址,找到pa指向的内容
- *pa=q;就是a=q
指针变量的大小,取决于地址的大小
地址的具体值不一样,但不管是谁的地址,都是一串数字,32个比特位,也就是四个字节;
所以这里的 指针变量 的大小:
32平台上,不管什么类型都是4字节;
64平台上,不管什么类型都是8字节;
结构体
当c语言描述复杂对象时候,比如学生,名字 年龄 性别 学号几项信息
这里只能用结构体来描述了。
//结构体
struct Stu //创建结构体
{
char name[20];
int age;
char sex[5];
char id[20];
}
//地址应该放到结构体的指针里面去,如int* pa=&a;
//前面的变量&s2就是取地址,而s2的类型不是int,是 struct Stu;所以这里就变成
//struct Stu* 然后要放到指针里面,再加上个ps;这里即ps这个指针里面,存的是s2的地址。
//即现在拿不到s2,因为s2作为结构体有很多数据,没法像int a=2这样直接拿过来用,所以用地址代表s2
//而main函数想用s2这个变量,那作为输入时候,给的就是s2的地址
//print函数里,接收到的输入就是s2的地址,但没法直接 int a=s2的地址,因为地址需要用指针存放,所以必须用一个指针 ()*ps =s2 而()里的类型要和s2一致,所以就是struct Stu* ps
//注意,这个ps只是自己命名了一下,和int a=b 这里的a一样,叫啥都行的
void print(struct Stu* ps){
printf("%s %d %s %s",(*ps).name,(*ps).age,(*ps).sex,(*ps).id);
printf("%s %d %s %s",ps->name, ps->age, ps->sex, ps->id);
}
//上面两个printf是一样的效果
//->: 结构体成员访问操作符,结构体指针->结构体成员
int main()
{
struct Stu s1={"张三",18,"男","202011000"};
struct Stu s2={"如花",444,"女","202011000"};
printf("%s %d %s %s\n",s1.name, s1.age, s1.sex, s1.id);
print(&s2);
return 0;
}
//. :结构体成员访问操作符,结构体变量.结构体成员
void不需要return
当scanf的时候,数组本身就是地址,所以不需要取地址;其他需要
如上面的例子中,scanf("%s %d %s %s",s1.name, &(s1.age), s1.sex, s1.id );