大家好,欢迎踏入C语言的世界,在这篇文章中,anduin会带你遍历C语言中的基本知识点,因为是初始C语言,我们对于知识点的讲解点到为止,只是对于C语言有一个初步的了解,方便我们以后将其一一剖析,当然我也会在一些地方做一些小补充,如果有不到位的地方,还请大家多多指正!(以下代码均在vs2022中编译)
目录
1. 什么是C语言?
计算机语言的发展
低级 -> 高级
机器语言 ->助记符,汇编语言 -> B -> C
标准ANSI C 变换过程:ISO K&R C89/C90 C98 C99
C语言和其他语言的区别
C语言编译器
2. 第一个C语言程序
#include<stdio.h>
{
printf("hello world\n");
return 0;
}
主函数的标准格式
//推荐
int main()
{
}
//古早写法
void main()
{
}
//不规范写法
main()
{
}
//不推荐但正确的写法
int main(void)//详细告诉你这个函数没有返回值
{
}
科普
返回值
printf
通用单位
计算机处理数据,处理的为二进制数据。
1 bit 存一个二进制位
1 byte = 8 bit 1 KB = 1024 byte 1 MB = 1024 KB 1 GB = 1024 MB TB ZB
数据类型
为什么写代码?是为了用程序解决问题。
数据类型符号 | 数据类型 | 单位 |
char | 字符数据类型 | 1个字节 |
short | 短整型 | 2个字节 |
int | 整型 | 4个字节 |
long | 长整型 | 4个字节 |
long long | 更长的整型 | 8个字节 |
float | 单精度浮点数 | 4个字节 |
double | 双精度浮点数 | 8个字节 |
sizeof用法
sizeof是操作符,sizeof计算单位的结果是:字节 - byte。
sizeof(long) >= sizeof(int),也就是说long长整形只要大于等于int整形就可以了,在vs2022中计算出long的大小为4个字节。
计算方法
#include<stdio.h>
int main()
{
printf("%d\n",sizeof(char));
printf("%d\n",sizeof(short));
printf("%d\n",sizeof(int));
printf("%d\n",sizeof(long));
printf("%d\n",sizeof(long long));
printf("%d\n",sizeof(float));
printf("%d\n",sizeof(double));
return 0;
}
//编译结果:
// 1 2 4 4 8 4 8
3. 变量与常量
3.1 定义变量的方法
int age = 150;
float weight = 45.5f//加f原因:编译器默认为double类型。如果想定义为float类型,就加上f
char ch = 'w';
3.2 变量的命名
3.3 变量的分类
局部变量与全局变量的定义
#include<stdio.h>
int global = 10;//全局变量
int main()
{
int local = 1;//局部变量
return 0;
}
小思考
下列代码有没有问题,若没有问题输出的值是什么:
#include<stdio.h>
int num1 = 2019;//全局变量
int main()
{
int num1 = 2020;//局部变量
printf("num1 = %d\n",num1);//打印结果是什么?
return 0;
}
在vs2022中编译结果如下:
变量的使用
#include<stdio.h>
int main()
{
int num1 = 0;
int num2 = 0;
int sum = 0;
printf("请输入两个操作数:>");
scanf("%d %d", &num1, &num2);
sum = num1 + num2;
printf("sum = %d\n",sum);
return 0;
}
3.4 变量的作用域和生命周期
作用域
1)局部变量的作用域是变量所在的局部范围。
2)全局变量的作用域是整个工程。
生命周期
1)局部变量的生命周期是:进入作用域生命周期开始,出作用于生命周期结束。
2)全局变量的生命周期是:整个程序的生命周期。
理解
对于作用域和生命周期,如果光看定义可能很难理解,接下来anduin就用一个例子来帮助我们更好地理解这个概念,生命周期可以看做从anduin从出生到死亡这个范围,但是作用域呢可以看成auduin可以坚持写代码的时间,当我的作用域结束之后,我的生命周期并没有结束。这两个是不同的两个概念。
3.5 常量
字面常量
const 修饰的常变量
#include<stdio.h>
int main()
{
const int num = 100;
num = 200;//报错
return 0;
}
当我们对num进行二次赋值是发生报错,这是因为 const 修饰的变量无法被重新写入。
那么常变量又是什么,我们怎么理解他呢?
num 本质是变量,但是因为 const 的修饰限定了他的改变, 就和常量一样。
如果想更加深入理解关键字 const 可以参考我的一篇博客http://t.csdn.cn/PtuDv
#define 定义的标识符常量
#include<stdio.h>
#define MAX 1000
int main()
{
int a = MAX;
printf("%d\n", a);
//MAX = 2000;//报错
int arr[MAX];//可以
return 0;
}
当我们对MAX进行二次赋值时,发生报错,这可以看出MAX为常量。
但是#define 定义的标识符常量可以用来定义数组元素个数如int arr[MAX];
由于#define起替换作用,这里的数组相当于int arr[1000];
枚举常量
枚举从字面意思上看就是一一列举,生活中很多东西都可以一一列举,它们都可以用枚举来表示。
代码演示:
enum Sex
{
MALE,
FEMALE,
SECRET
};
int main()
{
enum Sex s = SECRET;
printf("%d %d %d\n", MALE, FEMALE, SECRET);//0 1 2
MALE = 3;//报错 证明
}
我们编译后发现在对枚举定义MALE进行赋值时报错,所以我们可以得出结论在枚举类型enum Sex中列举出的可能取值都是枚举常量。而枚举常量中首个元素被默认初始化为0,在进行打印时,打印结果为0 1 2。枚举常量中的状态值是呈+1式递增的。
4. 字符串+转义字符
4.1 字符
字符的使用
#include<stdio.h>
int main()
{
char ch = 'a';
ch = 'x';
printf("%c", ch);
return 0;
}
字符的本质:ASCII码值
ASCII码值小科普
4.2 字符串
字符串是什么
字符串的使用
#include<stdio.h>
int main()
{
char arr[] = "abcd";
printf("%s\n",arr);
return 0;
}
隐藏的' \0 '
#include<stdio.h>
int main()
{
char arr1[] = "abcd";//此处可以结合内存来说明
char arr2[] = {'a', 'b', 'c', 'd'};
return 0;
}
接下来我们启动调试,查看arr1,arr2的内容。
在arr1的结尾处隐藏着一个'\0'作为结束字符串的标志,但是arr2中却没有' \0 '。
' \0 ' 的威力
别看上述例子只是少了一个' \0 ',在这里' \0 '并不是摆设,它也是有自己的“威力”的。
在我们用代码看它的作用之前让我们先了解一下strlen函数。
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[] = "abcd";
char arr2[] = {'a','b','c','d'};
printf("%d\n",strlen(arr1));
printf("%d\n",strlen(arr2));//可以画图详细讲解
}
这里的输出结果是什么???让我们开始运行,我们看到结果如下:
小思考
如何输出这个路径?D:\Anduin_code\anduins-code-warehouse
这样可以吗?
int main()
{
printf("D:\Anduin_code\anduins-code-warehouse");
//输出结果:D:Anduin_codenduins-code-warehouse
}
但当我们运行之后,发现我们并不能输出我们的路径,这是为什么?因为这里\和其他字符构成转义字符。
4.3 转义字符
下面我列出了一些转义字符:
转义字符 | 释义 |
\? | 在书写连续多个问号时使用,防止他们被解析成三字母词 |
\' | 用于表达字符常量 |
\" | 用于表示一个字符串内部的双引号 |
\\ | 用于表示一个反斜杠,防止他被解释为一个转义序列符 |
\a | 警告字符,蜂鸣 |
\b | 退格符 |
\f | 进纸符 |
\n | 换行 |
\r | 回车 |
\t | 水平制表符 |
\v | 垂直制表符 |
\ddd | ddd表示1 - 3个八进制数字。如:\130x |
\xdd | dd表示2个十六进制数字。如:\x30 0 |
让我们用代码了解他们都是什么作用(详情见注释):
int main()
{
printf("%s\n","(are you ok??)");//在老编译器上会打印(are you ok]
//三字母词:??) ->]
printf("%c\n",'\'');//输出结果为:'
printf("%c\n","\"");//输出结果为:"
printf("\a\a\a");//蜂鸣,电脑叫三声
char a[] = "abc";
printf("%c%c\b%c", a[0], a[1], a[2]);//输出结果为:ac(\b为退格符,b被删掉)
printf("1\t23");//输出结果为:1 23(\t是水平制表符,八个空格)
printf("anudin\n");//输出结果为:anduin且换行
printf("%c\n",'\130');//输出结果为:X (1*64+3*8+0*1 = 88 也就是字符 X)
printf("%c\n",'\x30');//输出结果为:0 (3*16+0*1 = 48 也就是字符 0)
}
小测验
看到这儿大家应该对转义字符有一定的理解了,接下来就用几道题目来测验一下自己吧:
题1:如何正确输出代码路径:D:\Anduin_code\anduins-code-warehouse?
题2:这个路径的长度是多少?
#include<stdio.h>
int main()
{
printf("D:\\Anduin_code\\anduins-code-warehouse?");
printf("%d\n",strlen("D:\Anduin_code\anduins-code-warehouse"));
return 0;
}
揭晓答案:
5. 注释
注释的作用
注释风格
#include<stdio.h>
int main()
{
//printf("hello anduin\n");C++注释风格 推荐
/* C语言风格注释 不推荐
printf("oops!\n");
*/
}
C语言注释风格由于\*总是和更近的*/进行匹配,从而导致无法嵌套注释,所以我们一般还是用C++风格的注释。
6.选择语句
代码演示:
int main()
{
int studying = 0;
printf("你会坚持每天学习吗?(1 or 0):>");
scanf("%d",&studying);
if(studying == 1)
{
printf("好offer在等着你!\n");
}
else
{
printf("竹篮打水一场空!\n");
}
对于你,你会怎么选择呢?是选择1 好offer,还是选择 0 竹篮打水一场空呢?
anduin这里还是建议大家努力起来,一起加油!
当然分支语句可不仅仅是这么点,我们今天只是了解,等之后会我会重新整理的。
7.循环语句
我们今天就重点看一下while语句,其他两种循环语句,我会在以后详细讲解:
我们可以通过一个例子来了解一下while语句是如何进行的,比如你坚持写代码,当你代码写到两万行时,你可能觉得你的水平差不多了,也可以找个offer了,那么这个循环也就随之结束。如下面代码所示:
#include<stdio.h>
int main()
{
int line = 0;
printf("insist codeing >\n");
while(line < 20000)
{
printf("写代码\n");
line++;
}
if(line == 20000)
{
printf("好offer\n");
}
return 0;
}
编译运行结果为:(因为这里代码过多就截取一小部分)。
8.函数
如何理解
函数的结构
实现Add函数
#include<stdio.h>
int Add(int x,int y)
{
return (x + y);
}
int main()
{
int num1 = 0;
int num2 = 0;
int sum = 0;
scanf("%d%d",&num1,&num2);
sum = Add(num1,num2);
printf("%d\n",sum);
}
分析:用sum来接受Add函数所返回的值的同时调用Add函数,于是num1和num2在进行Add函数计算后,返回值为num1 + num2的值。
为什么使用函数
9. 数组
9.1 数组定义
9.2 数组的下标
代码演示:
#include<stdio.h>
int main()
{
int arr[5] = { 1, 2, 3, 4, 5};
printf("%d\n",arr[3]);//访问下标为3的元素
//printf("%d\n",arr[10])//不可以这样访问!!!
}
请注意数组不能越界访问,例如:arr[10]就越界访问了!!!越界访问可能会导致程序崩溃,程序出错等严重后果。
设想一下:你在一层楼中买了两套房子,但是你自己的房子不住,偏偏要去住别人的房子,这是什么,这就是非法访问,严重的是要被抓起来了,就说明你违法了!!!所以越界访问的危险可见一斑。
9.3 数组的使用
#include<stdio.h>
int main()
{
int arr[10] = { 0 };
//0~9
//输入10个值给数组
int i =0;
while(i<10)
{
scanf("%d",&arr[i]);
i++;
}
//输出数组的10个值
i = 0;
while(i<10)
{
printf("%d ",arr[i]);
i++;
}
return 0;
}