0.学习建议和心得
学习是自己积累的过程,问题自己先去解决,锻炼自己的主动能力。对于听课,一定是先听懂,在反复实践。提高编程唯一的途径就是不停的写代码,实践,实践,再实践。
1.编辑器
根据编辑器的不同,程序的输入和输出会有略微的差别,本系列的C语言采用的编辑器为vs2019。注意一点,.c和.cpp都可以保存和运行C语言的程序,但是在部分的语法上会有一些区别,在学习C语言时采用.c作为文件的后缀名。
1.1 创建文件
首先打开vs2019--->创建新项目---->选择控制台应用,下一步--->输入项目名称--->创建。在左侧的解决方案的窗口中(如果没有或者被误删除,选择顶部的视图查找选中),可以看到源文件中出现了.c文件,所有的编辑代码都是在.c文件中书写。
1.2 配置
关于出现的错误,在这先填一个坑,遇到会在这进行总结。
- scanf,strcpy,strcat等关键字 运行出现不安全的问题,解决的方案有两种,第一种在第一行输入
#define _CRT_SECURE_NO_WARNINGS 1
第二种解决方式是: 在第一行输入
#pragma warning(disable:4996)
- 如果输出的程序一闪而过,记得在main函数中加入
system("pause")
-
出现使用scanf printf未定义的错误,一般是没有引入对应的头文件,如果是使用的自定义的变量,则可能没有进行声明,例如a=5;
1.3vs中工具的使用
使用F9设置断点(程序的停留位置,此行不执行) F10 (一行行的开始执行,遇到函数跳过)F11(一行行的开始执行,遇到函数进入)
在调式状态下,选择菜单栏中的调试,在下拉的选项中找到窗口--->监视--->监视1,既可以查看程序运行中各个变量的值。或者按Shift+F9
2. C 语言简介
类似我们交流使用的汉语,C 语言是一种人与计算机交互的高级语言,计算机语言的发展大致经历了三个阶段,机器语言--》汇编语言--》高级语言。由于计算机只能识别二进制的01序列,所以最早的使用的是机器语言进行输入,例如00000001代表某一种操作,但是对于人类编程,每次都需要查阅大量的对应信息,变成不便。所以发展出汇编语言,类似使用助记符的方式进行编程,例如add 代表的就是加法,在此基础之上发展出了高级语言,即使用完全类似人类交流的语言进行编程,大大降低了学习的门槛。
2.1变量和常量
变量:存储数据的“盒子”,其值可以改变。需要使用变量时,随时创建。定义变量的方法是
数据类型 变量名 = 变量的数值
int a=12;
double b=2.8;
char c='a';
根据作用域范围和生命周期的不同,变量可以分为局部变量和全局变量,
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int a = 100; //全局变量 放在{}外面
int main()
{
int a = 10; //局部变量放在{}里面
printf("%d\n", a); //当局部变量和全局变量重名的时候,起作用的是局部变量,即输出的值是10;
return 0;
}
常量:其值不变的量,
- 字面常量 例如3,“123”等
- const 修饰的常变量,之所以称之为常变量因为其值不可以改变,但其实质是变量,例如创建数组的时候,[ ]里面必须是常量,使用const 创建的常变量就不可以定义。
int num=10; num=5; //可以进行修改 const int num=10; num=5; //不可以运行,因为const关键字创建变量具有常量属性(不可修改)。 int arr[num]; //不可以创建数组,因为const创建的是具有常量属性的变量。
-
使用define定义的常量
#define num 10 int main() { int a; a=num; printf("%d\n",a); }
- 枚举常量:列出所有可能的取值,使用enum定义类型
enum Color { Red, Blue, Green }; int main() { enum Color color = Red; enum Color color1 = Blue; enum Color color2 = Green; }
2.2字符和字符串,转义字符
字符:''单引号引起来的是一个字符,
字符串:""引起来的是多个字符,使用字符数组存储。""是空字符串," "是空格字符串。
char c='a' //存储一个字符
char c[10]="abc" //使用字符数组存储多个字符
使用双引号的字符串会在最后加上一个结束标识符'\0'
在下面的赋值方式中,字符和字符串是等价的
char arr1[]="abc";
char arr2[]={'a','b','c','\0'};
为了求出字符串的长度,一般使用string.h头文件下的strlen,计算的方式是计算遇到'\0'之前的所有字符,例如上面的结果就是3,但是使用sizeof进行求解上面的结果就是4,sizeof计算的是所定义变量占用的内存空间的大小。如果使用' '定义的时候没有输入'\0',则strlen的输出结果不正确,根据strlen的计算方式,直到后面偶然遇到一个'\0',把得到的结果返回。
int main()
{
char a[] = "abc";
char a1[] = {'a','b','c','\0'};
printf("%d\n", sizeof(a)); //4
printf("%d\n", sizeof(a1)); //4
printf("%d\n", strlen(a)); //3
printf("%d\n", strlen(a1)); //3
char a2[] = { 'a','b','c' };
printf("%d\n", sizeof(a2)); //3
printf("%d\n", strlen(a2)); //随机值
}
转义字符,它是一个字符,使用‘ ’
使用场景写路径printf("c:\\test\\test01");
常用的有:
'\n'表示换行
’\\'表示一个\
‘\t'水平制表,用作对齐
’\ddd' 1-3个数字,表示8进制数所对应的字符,由于计算机只能识别01序列,字符实际的存储方式是使用ASCII码表对应的关系使用整数进行存储。
‘\xdd' 1-2个数字,表示16进制数所对应的字符。
printf("%d\n", strlen("c:\test\327\test.c")); //结果是13
printf("%d\n", strlen("c:\test\328\test.c"));//结果是14,因为8进制数字的取值范围是0-7
2.3注释
注释即解释代码,方便他人阅读,程序不执行这些内容。有两种注释方式
// 注释一行
/* */ 注释多行
快捷键
ctrl+k+c ctrl+k+u
2.4 if语句
int main()
{
int input = 0;
printf("加入比特\n");
scanf("%d", &input);
if (1 == input) //书写代码的方式,赋值是从左向右的,这种方式可以避免少写一个=
{
printf("好offer\n");
}
else
{
printf("卖红薯\n");
}
return 0;
}
2.5while
int main()
{
int line = 0;
printf("加入比特\n");
while (line < 20000)
{
printf("我敲代码:%d\n", line);
line++;
}
if (line >= 20000)
{
printf("好offer\n");
}
}
2.6函数
把重复的工作写成函数,方便调用,减少重复的代码量
int sum(int a,int b)
{
int z=a+b;
retun z;
}
2.7数组
定义一组相同类型的变量,
int arr[5]={1,2,3,4,5};
int arr1[5]={1,2};
2.8操作符
1.算术运算符
int main()
{
printf("%d\n",7/2);
printf("%d\n",7%2);
printf("%d\n",7+2);
printf("%d\n",7-2);
printf("%d\n",7*2);
}
2.移位运算符 >> << 位操作符 & ^ |
int main()
{
int a=10;
int c=a<<2; //转化为二进制,向左移动两位
printf("%d\n",c);
int d=a>>2; //转化为二进制,向右移动两位
printf("%d\n",d);
}
int main()
{
int a = 14;
int b = 15;
int c = a ^ b; //按(二进制)位异或 相同为0,不同为1
//a 00000000000000000000000000001111
//b 00000000000000000000000000001110
//c 00000000000000000000000000000001
printf("%d\n", c);//1
c = a | b; //按(二进制)位或 有1为1,全0为0
//a 00000000000000000000000000001111
//b 00000000000000000000000000001110
//c 00000000000000000000000000001111
printf("%d\n", c);//15
c = a & b; //按(二进制)位与 有0为0,全1为1
//a 00000000000000000000000000001111
//b 00000000000000000000000000001110
//c 00000000000000000000000000001110
printf("%d\n", c); //14
}
2.9单目运算符
!逻辑反操作
+ 正值
- 负值
& 取地址
sizeof 操作数的类型长度,变量所占内存空间的大小
~ 对一个数的二进制按位取反
-- 前置,后置--
++ 前置,后置++
* 间接访问操作符(解引用操作符)
(类型) 强制类型转化
整数在内存种存储的是二进制表示的补码
负数:
反码符号位不变,其余取反
补码是反码加1
正数的原码,反码,补码相同
int main()
{
int a=-1;
//把十进制的数字可以转换为二进制
//二进制有三种表示方式:原码、反码、补码
//二进制位种最高位是符号位
//最高位是1,表示负数
//最高位是0,表示正数
//10000000000000000000000000000001 --原码
//11111111111111111111111111111110 --反码
//11111111111111111111111111111111 --补码
//00000000000000000000000000000000 --取反操作
//整数在内存种存储的是二进制表示的补码
return 0;
}
自增和自减运算符
int main()
{
int a = 10;
int b = a--;
printf("a=%d b=%d\n", a, b);
a = 10;
b = --a;
printf("a=%d b=%d\n", a, b);
a = 10;
b = ++a;
printf("a=%d b=%d\n", a, b);
a = 10;
b = a++;
printf("a=%d b=%d\n", a, b);
}
2.10 关系操作符 > >= < <= != ==
int main()
{
int a=4;
if(a=3) //赋值运算符,少了一个=,相当于 把3赋给变量a 表达式的值为真
{
printf("hehe\n");
}
}
逻辑操作符 && || ,注意短路运算(已经得到结果即停止)
int main()
{
int a=0;
int b=0;
int c=a&&b; //逻辑与 同真为真
c=a||b; //逻辑或 有真为真
}
条件运算符 exp1?exp2:exp3
int main()
{
int a,b;
scanf("%d %d",&a,&b);
int max;
if(a>b) //4行代码等价于 max=(a>b)?a:b;
max=a;
else
max=b;
}
逗号表达式 exp1,exp2,exp3, ...expN,表达式会从左到右依次计算,但是最后表达式的值,等于最后一个表达式的结果。
int main()
{
int a=(3+1,5+2,8+1,2-4);
printf("%d\n",a);
int x,a;
x=(a=3,6*3); //a=3,x=18
x=a=3,6*a; //a=3,x=3,表达式的结果为18
}
2.11关键字
auto (一般省略)局部变量都是自动创建,自动销毁的,在C语言中的局部变量就是自动变量,全局变量不可以使用auto定义
typedef 类型重命名
int main()
{
typedef unsigned int uint;
uint num=10;
}
在本.c源文件中定义的变量,如果想在其他的.c文件中使用,需要加上extern关键字例如如下两个源文件(在一个项目里,源文件右键添加新建项)
//a.c
int g_val=2022;
//b.c
extern int g_val; //声明外部变量
int main()
{
printf("g_val=%d\n",g_val);
}
register 定义的是寄存器变量,仅仅是推荐定义为寄存器类型变量,具体的结果有编辑器决定。寄存器的存储速度非常快,如果每个人都觉得自己的代码重要则没有衡量的标准。
register int a=10;
static 修饰变量和函数
1.修饰局部变量--静态局部变量 局部变量进入范围创建,出了范围销毁。static改变的是局部变量的生命周期,和程序的生命周期一样
void test()
{
int a=1;
a++;
printf("%d ",a);
}
int main()
{
int i=0;
while(i<10)
{
test();
i++;
}
return 0;
}
加入了static,第一必须要赋初值,第二赋值的语句只在第一次进入函数的时候,访问一次。
void test()
{
static int a=1; //只在第一次进入函数的时候执行一次
a++;
printf("%d ",a);
}
int main()
{
int i=0;
while(i<10)
{
test();
i++;
}
return 0;
}
2.修饰全局变量--静态全局变量 改变了这个全局变量的作用域,这个变量只能在此源文件中使用
//a.c
static int g_val=2022; //加上static 其他的源文件不能使用
//b.c
extern int g_val; //声明外部变量
int main()
{
printf("g_val=%d\n",g_val);
}
3.修饰函数--静态函数
改变了函数的使用范围,函数只能在自己所在的源文件内部使用
//a.c
static int Add(int x,int y) //加上static 其他的源文件不能使用
{
int z=0;
z=x+y;
return z;
}
//b.c
extern int Add(int x,int y); //声明外部函数
int main()
{
int a=10;
int b=20;
int sum=Add(a,b);
printf("sum=%d\n",sum);
}