本篇博客主要讲解C语言一些最基础和零散的知识点,为以后C语言学习打下初步基础
目录
一、main函数
二、库函数
三、数据类型
四、计算机单位
五、变量
···变量命名规范:
···变量分类
···变量作用域
···变量的生命周期
六、常量
1.字面值常量
2.const修饰的常变量
3.#define定义的标识符常量
4.枚举常量
七、字符与字符串
···字符串中的'\0'
---转义字符
八、注释
九、关键字
1.auto 自动
2.register 寄存器
3.typedef 类型重定义/重命名
4.extern 声明外部符号
5.static 静态的
一、main函数
1.main函数特点
···所有的C语言程序都必须含有main函数
①程序执行的入口 : C语言程序是从main函数的第一行开始执行的
②有且只有一个
2.main函数框架
int main()
{
return 0;
}
main是函数名, int是函数返回参数类型,而return 0在C语言中表示程序正常结束,返回0
二、库函数
·库函数是C语言标准库提供的函数,这些函数已经被设计好了,我们直接可以使用,实现相应功能
·库函数的使用必须引用相应头文件,声明程序中会使用该头文件中的函数了
第一个C语言程序:在屏幕上打印hello world
打印函数: printf --- print function 对应头文件: #include
#include
int main()
{
printf("hello world");
return 0;
}
三、数据类型
char | 字符型 |
---|---|
short | 短整型 |
int |
整形 |
long |
长整型 |
long long | 更长的整形 |
float | 单精度浮点型 |
double | 双精度浮点型 |
·不同数据类型是为了更加丰富表达生活中的值,他们大小是不一样的,sizeof是C语言的一个操作符,可以计算变量或类型大小,单位是字节
#include
int main()
{
printf("%d\n", sizeof(char)); //1
printf("%d\n", sizeof(short)); //2
printf("%d\n", sizeof(int)); //4
printf("%d\n", sizeof(long)); //4
printf("%d\n", sizeof(long long)); //8
printf("%d\n", sizeof(float)); //4
printf("%d\n", sizeof(double)); //8
}
C语言标准规定:sizeof(long) >= sizeof(int)即可
四、计算机单位
单位 | 换算 | 说明 |
bit | 比特位是计算机最小单位,一个2进制位(0/1)的大小就是1个bit位 | |
byte | 1byte = 8bit | |
kb |
1kb = 1024byte | |
mb | 1mb = 1024kb | 日常生活说的多少M |
gb | 1gb = 1024mb | 日常生活说的多少G |
tb | 1tb = 1024gb |
五、变量
变量就是可以改变的量,在编程中,经常定义变量来存储值
···定义变量方式: 类型名 变量名 = "xxx";
int main()
{
int a = 10;
char c = 'w';
//C语言中,一个小数默认是double类型,加上f认为其是float类型
double weight1 = 45.5;
float weight2 = 45.5f;
return 0;
}
···"变"字体现?
int main()
{
int a = 10; //创建变量
a = 20; //重新赋值
printf("%d\n", a);//20
return 0;
}
1.必须由数字,字母,下划线组成
2.不能以数字开头
3.区分大小写
4.变量名最好有意义
·全局变量:在{}外部定义的变量就是全局变量
·局部变量:在{}内部定义的变量就是全局变量
int num = 100; //全局变量
int main()
{
int a = 10; //局部变量
return 0;
}
注:全局变量和全局变量名字可以相同,但是在使用时局部优先
·一个变量可以在哪里起作用,哪里就是它的作用域
·局部变量的作用域是其所在的局部范围
void test()
{
printf("%d\n", a); //出了作用域,不能再使用a
}
#include
int main()
{
int a = 10;
printf("%d\n", a);
{
int b = 20;
printf("%d\n", b);
}
printf("%d\n", b); //出了作用域,不能再使用b
return 0;
}
·全局变量的作用域是整个工程(因此全局变量不是很安全)
同一文件使用全局变量
int a = 100;
void test()
{
printf("2:%d\n", a);
}
int main()
{
printf("1:%d\n", a);
test();
return 0;
}
跨文件使用
add.c
int g_val = 2023;
test.c
extern int g_val;
int main()
{
printf("%d\n", g_val);
}
·变量的生命周期是指变量从创建到销毁的整个过程
·全局变量的生命周期:程序的生命周期
·局部变量的生命周期:进作用域生命周期开始,出作用域声明周期结束
int main()
{
{
//进入作用域生命开始
int a = 10;
printf("%d\n", a);
//出作用域生命结束
}
printf("%d\n", a); //err
return 0;
}
六、常量
100, 'w', 3.14, "abcdef"
·const修饰的变量具有常属性(意味着不能被改变)
int main()
{
const int num = 10; //num已经被const修饰了,本质还是变量, 具有常属性
printf("%d\n", num);
num = 20; //err 不能再修改了
printf("%d\n", num);
}
·const修饰的变量本质还是变量
int main()
{
//证明还是变量,只是具有常属性了~
int arr[10] = {0};
int n;
int arr[n] = { 0 }; //n是变量,不能指定数组的大小
const int n;
int arr[n] = { 0 }; //n本质仍然是变量,不能用来指定数组的大小
return 0;
}
#define MAX 1000
int main()
{
printf("%d\n", MAX); //1000
//MAX = 2000; //err 常量不能再改变了~
int arr[MAX];
#define MIN 0
printf("%d\n", MIN); //0
return 0;
}
·枚举就是可以一一列举
enum Sex //枚举类型
{
//下面三个符号是Sex这个枚举类型的未来的可能取值
MALE,
FEMALE,
SECRET
};
int main()
{
//枚举常量默认值从0开始,依次递增1
printf("%d\n", MALE); //0
printf("%d\n", FEMALE); //1
printf("%d\n", SECRET); //2
enum Sex s = MALE; //定义枚举类型的变量s
return 0;
}
·枚举常量是可以赋初值的
enum Sex
{
MALE = 5, //可以给枚举常量赋初值
FEMALE,
SECRET
};
int main()
{
//printf("%d\n", MALE); //5
//printf("%d\n", FEMALE); //6
//printf("%d\n", SECRET); //7
enum Sex s = MALE;
printf("%d\n", s);
return 0;
}
七、字符与字符串
字符是由单引号引起来的,字符串是由双引号引起来的一串字符
字符串末尾默认放了'\0', 例如"abcdef"字符串其实是有 abcdef\0 这7个字符
打印结束的标志
int main()
{
char c1 = 'a';
char c2 = 'b';
//字符数组
char arr1[] = "abc";
char arr2[] = { 'a', 'b', 'c' };
printf("%s\n", arr1); //abc
printf("%s\n", arr2); //abc烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫虜悕畸
char arr3[] = { 'a', 'b', 'c', '\0' };
printf("%s\n", arr3); //abc
return 0;
}
求长度结束的标志
#include
int main()
{
//strlen是一个库函数,专门用来求字符串长度的
//统计的是\0之前出现的字符的个数,不包含\0
int len = strlen("abcdef");
printf("%d\n", len); //6
char arr1[] = "abc";
char arr2[] = { 'a', 'b', 'c'};
char arr3[] = { 'a', 'b', 'c', '\0' };
char arr4[4] ={'a', 'b', 'c'}; //4个字符,前三个指定了初始化内容,没指定的默认是'\0'
int len1 = strlen(arr1);
printf("%d\n", len1); //3
int len2 = strlen(arr2);
printf("%d\n", len2); //随机值
int len3 = strlen(arr3);
printf("%d\n", len3); //3
int len4 = strlen(arr4);
printf("%d\n", len4); //3
return 0;
}
转义字符,顾名思义,就是转变了字符原来的意思
例如:
printf("abcndef"); 会打印出 abcndef
printf("abc\ndef"); 会打印出 abc,然后换行打印def
这就是因为\n转义了n原本的意思,变成了换行
各个转义字符含义如下:
\? |
在书写连续多个问号时使用,防止他们被解析成三字母词
|
\'
|
用于表示字符常量 '
|
\“
|
用于表示一个字符串内部的双引号
|
\\
|
用于表示一个反斜杠,防止它被解释为一个转义序列符
|
\a
|
警告字符,蜂鸣
|
\b
|
退格符
|
\f
|
进纸符
|
\n
|
换行
|
\r
|
回车
|
\t
|
水平制表符
|
\v
|
垂直制表符
|
\ddd
|
ddd 表示 1~3 个八进制的数字。 如: \130 X
|
\xdd
|
dd表示 2 个十六进制数字。 如: \x30 0
|
大多数转义字符了解即可,这里重点介绍一下其中几个
① \' \'' \\
int main()
{
//想打印单引号
//printf("%c\n", '''); //错误写法
printf("%c\n", '\'');
printf("%s\n", "a");
printf("%s\n", "\"");
//打印 abc\ndef
printf("%s\n", "abc\\ndef");
// \\在文件路径经常需要用到
printf("c:\\net\\next.c\n");
return 0;
}
②\ddd \xdd
字符在内存中是有编码的,我们称之为ASCII值
int main()
{
// \ddd表示1~3个八进制的数字
// ASCII表 --- 键盘输入的字符都是有编号的---ASCII值
printf("%c\n", '\130'); //X 1*8^2+3*8^1+0*8^0 = 88 --- X
printf("%c\n", '\63'); //3
// \xdd表示1~2个十六进制数字
printf("%c\n", '\x33'); //3
printf("%c\n", '\x63'); //c
return 0;
}
无论是八进制数字,还是十进制数字,都要先根据权重转化为十进制数字之后,再去找对应的字符
八、注释
注释是为了解释较为难懂的代码,为了让别人看懂,也为了让几个月之后的自己能够看懂~
注释方式:
①// 注释内容
②/* 注释内容 */
区别: /* */ 不支持嵌套注释
快捷键:
注释:ctrl+k+c
取消注释:ctrl+k+u
九、关键字
这些是C语言常见的关键字,随着知识学习的深入,大家会逐渐了解到每个关键字,这里先重点介绍几个
int main()
{
//int a = 10;
auto int a = 10; //局部变量,自动创建,自动销毁, 因此又叫自动变量,但auto可以省略不写
return 0;
}
拓展知识:计算机存储数据体系结构:
和内存一样,寄存器也是存储数据的设备,cpu处理的数据来源就是这些存储设备,由于cpu不断发展,处理数据速度越来越快,内存这些存储设备已经跟不上cpu的速度了,因此出现了高速缓存,寄存器等设备进行更快的数据交互
有些数据我们可能会频繁大量使用,因此可以用register关键字声明变量,建议将数据存储在寄存器中,但真正是否会存储到寄存器中,取决于操作系统
int main()
{
register int num = 100; //建议把100放在寄存器中存储
return 0;
}
typedef常用于给一个较长的类型名字重新命名一下,使其变短,写起来更加方便
eg: typedef unsigned int uint;
全局变量或者是函数一般在当前文件内部使用,若想要跨文件使用,就用extern声明一下即可
·extern声明全局变量
add.c
int g_val = 2023;
test.c
extern int g_val;
int main()
{
printf("%d\n", g_val); //2023
return 0;
}
·extern声明函数
add.c
int Add(int x, int y)
{
return x + y;
}
test.c
extern int Add(int, int);
int main()
{
int a = 10;
int b = 20;
int sum = Add(a, b);
printf("%d\n", sum);
return 0;
}
拓展知识:内存区域的划分
①static修饰局部变量:
延长了局部变量的生命周期,作用域不受影响
本质:statici修饰局部变量,本质改变了局部变量在内存中的存储位置,栈区->静态区
void test()
{
int a = 1;
a++;
printf("%d ", a); //2 2 2 2 2 2 2 2 2 2
}
int main()
{
int i = 0;
while (i < 10)
{
test();
i++;
}
return 0;
}
void test()
{
//static修饰局部变量使得局部变量出了作用域不会销毁,影响了局部变量的生命周期
//一个普通的局部变量是放在栈区的,而被static修饰的局部变量,是放在内存的静态区的
static int a = 1;
a++;
printf("%d ", a); //2 3 4 5 6 7 8 9 10 11
}
int main()
{
int i = 0;
while (i < 10)
{
test();
i++;
}
return 0;
}
②static修饰全局变量:
改变了全局变量的链接属性,外部链接属性->内部链接属性,使得全局变量只能在当前文件中使用,出了当前文件,其他文件看不到,本质改变了全局变量的作用域
add.c
static int g_val = 2023;
test.c
extern int g_val;
int main()
{
printf("%d\n", g_val); //err
return 0;
}
③static修饰函数:
改变了函数的链接属性,外部链接属性->内部链接属性,使得函数只能在当前文件中使用,出了当前文件,其他文件看不到,相当于改变了函数的作用域
static修饰函数和static修饰全局变量效果基本是一样的,这里就不赘述了~