C语言基础
初识C语言
1.🚀第一个C语言程序
#include<stdio.h>
//包含一个叫<stdio.h>的文件
//std 标准 standard input output
int main()
{
printf("hellow bit\n");
printf("he he\n");
return 0;
}
//解释:
//main函数是程序的入口
//一个工程中main函数有且只有一个
2.🚀数据类型
char //字符数据类型
short //短整型
int //整型
long //长整型
long long //更长的整型
float //单精度浮点数
double //双精度浮点数
3.🚀变量、常量
3.1定义变量的方法
int age = 7;
float weight = 45.5f;
char ch ='wxy';
3.2变量的分类
- 局部变量
- 全局变量
#include<stdio.h>
int global = 2019;//全局变量
{
int local = 2018;
int global = 2020;
printf("global = %d\n",global);
return 0;
}
总结:
上面局部变量global变量的定义其实没什么问题的
当局部变量和全局变量同名的时候,局部变量优先使用。
3.3变量的使用
#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变量的作用域和生命周期
作用域
- 局部变量的作用域是变量所在的局部范围。
- 全局变量的作用域是整个工程。
生命周期
- 局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。
- 全局变量的生命周期是:整个程序的生命周期。
3.5常量
C语言中的常量分为以下几种:
- 字面常量
const
修饰的常变量- #define定义的标识符常量
- 枚举常量
#include<stdio.h>
//举例
enum Sex
{
MALE,
FEMALE,
SECRET
};
//括号中MALE,FEMALE,SECRET是枚举常量
int main()
{
//字面常量演示
3.14;//字面常量
7;//字面常量
//const修饰的常变量
const float pai = 3.14f; //这里的pai是const修饰的常变量
pai = 5.14;//是不能直接修改的!
//#define的标识符常量演示
#define MAX 100
printf("MAX = %d",MAX);
//枚举常量演示
printf("%d\n",MALE);
printf("%d\n",FEMALE);
printf("%d\n",SECRET);
//注:枚举常量的默认是从1开始,依次向下递增1的
return 0;
}
注:
上面例子上的pai
被称为const
修饰的常变量,const
修饰的常变量咋C语言中只是在语法层面限制了变量pai
不能直接被改变,但是pai
本质上还是一个变量的,所以叫常变量。
4.🚀字符串+转义字符+注释
4.1字符串
"hello bit.\n"
这种由双引号引起来的一串字符称为字符串字面值,或者简称字符串。
注:字符串的结束标志是一个\0
的转义字符。在计算字符串长度的时候\0
是结束标志,不算做字符串内容。
#include<stdio.h>
int main()
{
char arr1[] = "bit";
char arr2[] = {'b','i','t'};
char arr3[] = {'b','i','t','\0'};
printf("%s\n",arr1);
printf("%s\n",arr2);
printf("%s\n",arr3);
return 0;
}
4.2转义字符
假如我们要在屏幕上打印一个目录c:\code\test.c\n
#include<stdio.h>
int main()
{
printf("c:\code\test.c\n");
return 0;
}
转义字符顾名思义就是转变意思。
下面是一些转义字符。
转义字符 | 释义 |
---|---|
? | 在书写连续多个问号时使用,防止他们被解析成三字母词\ |
\’ | 用于表示字符常量’ |
\‘’ | 用于表示一个字符内部的双引号 |
\a | 警告字符,蜂鸣 |
\b | 退格符 |
\f | 进纸符 |
\n | 换行 |
\r | 回车 |
\t | 水平制表符 |
\v | 垂直制表符 |
\ddd | ddd表示1~3个八进制的数字。如:\130X |
\xdd | dd表示2个十六进制数字。如:\x30 0 |
4.3注释
- 代码中又不需要的代码可以直接删除,也可以注释掉。
- 代码中有些代码比较难懂,可以加一下注释文字。
注释有两种风格:
- C语言风格的注释/*xxxxxxx*/
- 缺陷:不能嵌套注释
- C++语言注释风格://xxxxxxx
- 可以注释一行也可以注释多行
5.🚀选择语句
#include<stdio.h>
int main()
{
int coding = 0;
printf("你会去好好学习吗?(选择1 or 0):");
scanf("%d",&coding);
if(coding==1)
{
printf("坚持,你会有好offer\n");
}
else
{
printf("放弃,回家卖红薯\n");
}
}
6.🚀循环
- while语句
- for语句
- do…while语句
//while循环的实例
#include<stdio.h>
int main()
{
printf("加入比特\n");
int line = 0;
while(line<=20000)
{
line++;
printf("我要继续敲代码\n");
}
if(line>20000)
printf("好offer\n");
return 0;
}
7.🚀函数
#include<stdio.h>
int Add(int x,int y)
{
int z = x+y;
return z;
}
int main()
{
int num1 = 0;
int num2 = 0;
int sum = 0;
printf("输入两个操作数:");
scanf("%d %d",&num1,&num2);
sum = Add(num1,num2);
printf("sum = %d\n",sum);
return 0;
}
函数的特点就是简化代码,代码复用。
8.🚀数组
要存储1-10的数字,怎么存储?
C语言中给了数组的定义:一组相同类型元素的结合
8.1数组定义
int arr[10]={1,2,3,4,5,6,7,8,9,10}//定义一个整型数组,最多存放10个元素
8.2数组的下标
C语言规定:数组的每一个元素都有下标,下标是从0开始的。
数组可以通过下标来询问。
比如:
int arr[10] = {0};
//如果数组10个元素,下标的范围是0~9
int arr[10] | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
---|---|---|---|---|---|---|---|---|---|---|
下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
8.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;
}
9.🚀操作符
算术操作符
+ - * / %
位移操作符
>> <<
(2进制)位操作符
& ^ |
赋值操作符
= += -= *= /= &= ^= |= >>= <<=
单目操作符
! 赋值反逻辑
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
-- 前置、后置--
++ 前置、后置++
* 间接访问操作符(解引用操作符)
(类型) 强制类型转换
关系操作符
>
>=
<
<=
!= 用于测试“不相等”
== 用于测试“相等”
逻辑操作符
&& 逻辑与
|| 逻辑或
条件操作符
exp1 ? exp2 : exp3
逗号表达式
exp1, exp2, exp3, ...expN
下标引用、函数调用和结构成员
[] () . ->
10.🚀关键字
10.1关键字typedef
typedef顾名思义是类型定义,这里应该理解为类型重命名。
比如:
//将unsigned int 重命名为uint_32,所以unit_32也是一个类型名
typedef unsigned int unit_32;
int mian
{
//观察num1和num2,这两个变量的类型是一样的
unsigned int num1 = 0;
unit_32 num2 = 0;
return 0;
}
10.2关键字static
在C语言中:
static是用来修饰变量和函数的
- 修饰局部变量-称为静态局部变量
- 修饰全局变量-称为静态全局变量
- 修饰函数-成为静态函数
10.2.1修饰局部变量
//代码1
#include<stdio.h>
void test()
{
int i = 0;
i++;
printf("%d\n",i);
}
int main()
{
int i = 0;
for(i=0;i<10;i++)
{
test();
}
return 0;
}
//代码2
#include<stdio.h>
void test()
{
//static修饰局部变量
static int i = 0;//静态变量
i++;
printf("%d\n",i);
return 0;
}
int main()
{
int i = 0;
for(i=0;i<10;i++)
{
test();
}
return 0;
}
对比代码1和代码2的效果理解static修饰局部变量的意义。
代码1:
代码2:
结论:
static修饰局部变量改变了变量的生命周期
一个普通的局部变量是放在栈区的,而static修饰的局部变量是放在内存的静态区。存储位置发生了变化,使得局部变量出了作用域不会被销毁,影响了生命周期。
作用域不受影响
让静态局部变量出了作用域依然存在,到程序结束,生命周期才结束。
10.2.2修饰全局变量
//代码1
//add.c
int g_val = 2018;
//test.c
int main()
{
printf("%d\n",g_val);
return 0;
}
//代码2
//add.c
static int g_val = 2018;
//test.c
int main()
{
printf("%d\n",g_val);
return 0;
}
代码1正常,代码2出现连接性错误。
结论:
一个全局变量在整个工程中都可以使用的,全局变量是有外部链接属性的,在其他源文件内部只要适当的声明就可以使用
一个全局变量被static修饰,这时的外部链接属性就变成了内部链接属性,使得这个全局变量只能在本源文件内使用,不能在其他源文件内使用。
影响了变量的作用域。
10.2.3修饰函数
//代码1
//add.c
int Add(int x,int y)
{
return x+y;
}
//test.c
int main()
{
printf("%d\n",Add(2,3));
return 0;
}
//代码2
//add.c
static int Add(int x,int y)
{
return x+y;
}
//test.c
int main()
{
printf("%d\n",Add(2,3));
return 0;
}
代码1正常,代码2在编译的时候会出现连接性错误。
结论:
函数也是有外部链接属性的
一个函数被static修饰,函数的外部链接属性就变成了内部连接属性,使得这个函数只能在本源文件内使用,不能在其他源文件内使用。
11.🚀#define定义常量和宏
//define定义标识符常量
#define MAX 1000
//define定义宏
#define ADD(x,y) ((x)+(y))
#include<stdio.h>
int main()
{
int sum = ADD(2,3);
printf("sum = %d\n",sum);
sum = 10*ADD(2,3);
printf("sum = %d\n",sum);
return 0;
}
12.🚀指针
12.1内存
内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的。
所以为了有效的使用内存,就把内存划分为一个个小小的内存单元,每个内存单元的大小是1个字节。
为了能够有效访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址。
变量是创建内存中的(在内存中分配空间的),每个内存单元都有地址,所以变量也是有地址的。
取出变量地址如下:
#include<stdio.h>
int main()
{
int num = 10;
#//取出num的地址
//注:这里num的4个字节,每个字节都有地址,取出的是第一个字节的地址(较小的地址)
printf("%p\n",&num);
return 0;
}
那地址应该如何存储,需要定义指针变量。
int num = 10;
int *p;//p为一个指针变量
p = #
指针的使用实例:
#include<stdio.h>
int main()
{
int num = 10;
int *p = #
*p = 20;
printf("%d\n",num);
return 0;
}
以整型指针举例,可以推广到其他类型,如:
#include<stdio.h>
int main()
{
char ch = 'w';
char* pc = &ch;
*pc = 'q';
printf("%c\n",ch);
return 0;
}
12.2指针变量的大小
#include<stdio.h>
//指针变量的大小取决于地址的大小
//32位平台下地址是32个bit位(即4个字节)
//64位平台下地址是64个bit位(即8个字节)
int main()
{
printf("%d\n",sizeof(char *));
printf("%d\n",sizeof(short *));
printf("%d\n",sizeof(int *));
printf("%d\n",sizeof(double *));
return 0;
}
结论:指针大小在32位平台是4个字节,64位平台是8个字节。
13.🚀结构体
结构体是C语言中特别重要的知识点,结构体使得C语言有能力描述复杂类型。
比如描述学生,学生包括:名字+年龄+性别+学号
这几项信息。
这里只能使用结构体来描述了。
例如:
#include<stdio.h>
struct Stu
{
char name[20];
int age;
char sex[5];
char id[15];
};
//结构体的初始化:
int main()
{
//.为结构成员访问操作符
//利用结构体类型创造一个该类型的结构体变量
struct Stu s = {"张三",20,"男","20180101"};
printf("name = %s age = %d sex = %s id = %s\n", s.name, s.age, s.sex, s.id );
//->操作符
struct Stu *ps = &s;
printf("name = %s age = %d sex = %s id = %s\n",ps->name,ps->age,ps->sex,ps->id);
}