C语言全面学习基础阶段01—C生万物

发布时间:2024年01月05日
如何学好 C 语言
1. 鼓励你,为你叫好。
C 生万物 编程之本 长远 IT 职业发展的首选 C 语言是母体语言,是人机交互接近底层的桥梁 学会 C/C++ ,相当于掌握技术核心 知识点一竿子打通。 IT 行业,一般每 10 年就有一次变革 40 年间,在 TIOBE 排行榜中, C/C++ 位置长期霸占前三名,没有丝毫撼动,可谓经典永不过时!
2. 学习不能叫苦叫累,抱怨没时间
欲戴王冠,必承其重。
如果你总是和别人走一样的路怎么才能保证超越别人,那就得付出不一样的努力。
时间就像乳沟,只要你肯挤,就一定会有
3. 拒绝做伸手党
遇到问题,先尝试自己解决
4. 学好编程,不仅仅是学好 C 语言
必须要学好:
语言、算法和数据结构、系统调用(操作系统)和计算机网络。
学习语言:
选择一门好的语言,深入学习,完成所有的课后作业。
学习算法、数据结构:
课堂上一定注意听讲,下课注重实践。
什么是 C 语言?
C 语言是一门通用 计算机编程语言 ,广泛应用于底层开发。 C 语言的设计目标是提供一种能以简易
的方式 编译 、处理低级 存储器 、产生少量的 机器码 以及不需要任何运行环境支持便能运行的编程
语言。
尽管 C 语言提供了许多低级处理的功能,但仍然保持着良好跨平台的特性,以一个标准规格写出的
C 语言程序可在许多电脑平台上进行编译,甚至包含一些嵌入式 处理器 (单片机或称 MCU )以及
超级电脑等作业平台。
二十世纪八十年代,为了避免各开发厂商用的 C 语言语法产生差异,由 美国国家标准局 C 语言制
定了一套完整的美国国家标准语法,称为 ANSI C ,作为 C 语言最初的标准。 [1] 目前 2011 12 8
日,国际标准化组织( ISO )和国际电工委员会( IEC )发布的 C11 标准 C 语言的第三个官方标
准,也是 C 语言的最新标准,该标准更好的支持了汉字函数名和汉字标识符,一定程度上实现了汉
字编程。
C 语言是一门面向过程的计算机编程语言,与 C++ Java 等面向对象的编程语言有所不同。
其编译器主要有 Clang GCC WIN-TC SUBLIME MSVC Turbo C 等。
第一个 C 语言程序
#include <stdio.h>
int main ()
{
? ? printf ( "hello bit\n" );
? ? printf ( "he he\n" );
? ? return 0 ;
}
// 解释:
//main 函数是程序的入口
// 一个工程中 main 函数有且仅有一个
数据类型
char ? ? ? ? // 字符数据类型
short ? ? ? // 短整型
int ? ? ? ? // 整形
long ? ? ? ? // 长整型
long long ? // 更长的整形
float ? ? ? // 单精度浮点数
double ? ? ? // 双精度浮点数
//C 语言有没有字符串类型?
为什么出现这么的类型?
每种类型的大小是多少?
#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 ));
? ? printf ( "%d\n" , sizeof ( long double ));
? ? return 0 ;
}

运行结果:

?

注意:存在这么多的类型,其实是为了更加丰富的表达生活中的各种值。
类型的使用:
char ch = 'w' ;
int weight = 120 ;
int salary = 20000 ;
变量、常量
生活中的有些值是不变的(比如:圆周率,性别(?),身份证号码,血型等等)
有些值是可变的(比如:年龄,体重,薪资)。
不变的值, C 语言中用 常量 的概念来表示,变得值 C 语言中用 变量 来表示。
定义变量的方法
int age = 150 ;
float weight = 45.5f ;
char ch = 'w' ;

变量的分类

局部变量
全局变量
#include <stdio.h>
int global = 2019 ; // 全局变量
int main ()
{
? ? int local = 2018 ; // 局部变量
? ? // 下面定义的 global 会不会有问题?
? ? int global = 2020 ; // 局部变量
? ? printf ( "global = %d\n" , global );
? ? return 0 ;
}

打印结果是什么呢?

运行结果:

?为什么??

总结:
上面的局部变量 global 变量的定义其实没有什么问题的!
当局部变量和全局变量同名的时候,局部变量优先使用

变量的使用

#include <stdio.h>
int main ()
{
? ? int num1 = 0 ;
? int num2 = 0 ;
? ? int sum = 0 ;
? ? printf ( " 输入两个操作数 :>" );
? ? scanf ( "%d %d" , & a , & b );
? ? sum = num1 + num2 ;
? ? printf ( "sum = %d\n" , sum );
? ? return 0 ;
}
// 这里介绍一下输入,输出语句
//scanf
//printf
变量的作用域和生命周期
作用域 作用域(scope ),程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效 / 可用的。而限定这个名字的可用性的代码范围就是这个名字的作用域。
1. 局部变量的作用域是变量所在的局部范围。
2. 全局变量的作用域是整个工程。
生命周期 变量的生命周期指的是变量的创建到变量的销毁之间的一个时间段
1. 局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。
2. 全局变量的生命周期是:整个程序的生命周期。
常量
C 语言中的常量和变量的定义的形式有所差异。 C语言中的常量分为以下以下几种:
字面常量(普通的常量)
const 修饰的常变量
#defifine 定义的标识符常量
枚举常量
#include <stdio.h>
// 举例
enum Sex
{
MALE ,
FEMALE ,
SECRET
};
// 括号中的 MALE,FEMALE,SECRET 是枚举常量
int main ()
{
? ? 3.14 ; // 字面常量
? ? 1000 ; // 字面常量
? ? const float pai = 3.14f ; ? //const 修饰的常量
? ? pai = 5.14 ; //ok?,编译出错
#define MAX 100 ? ? ? ? ? ? //#define 的标识符常量 ? ?
? ? return 0 ;
}

?这里补充一下枚举常量的用法:

#include <stdio.h>
//举例
enum Sex
{
?? ?MALE,
?? ?FEMALE,
?? ?SECRET
};
//括号中的MALE,FEMALE,SECRET是枚举常量
int main()
{
?? ?printf("%d\n", MALE);
?? ?printf("%d\n", FEMALE);
?? ?printf("%d\n", SECRET);
?? ?return 0;
}

运行结果:

发现枚举常量本身就是一个自然数递增的序列。?

枚举常量的定义是以逗号为分隔符,最后一个成员是没有标点符号的。使用时,直接打印成员变量名即可。和后面学的结构体要区别

?字符串+转义字符+注释

?字符串

"hello bir.\n"

这种由双引号( Double Quote )引起来的一串字符称为字符串字面值( String Literal ),或者简称字符串。
注:字符串的结束标志是一个 '\0'? 的转义字符。在计算字符串长度的时候 '\0'? 是结束标志,不算作字符串内容。 '\0'不计入字符串长度,但是要占据一个字节的空间!!
#include <stdio.h>
// 下面代码,打印结果是什么?为什么?(突出 '\0' 的重要性)
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 ;
}

?运行结果:

分析,打印字符串是遇到结束符'\0'才结束,而字符数组arr2长度为3,但是没有结束符,所以为一直打印,知道遇到'\0'才结束。?

转义字符
加入我们要在屏幕上打印一个目录: c:\code\test.c
我们该如何写代码?
#include <stdio.h>
int main ()
{
printf ( "c:\code\test.c\n" );
? ? return 0 ;
}

运行结果:

?为什么??这里就不得不提一下转义字符了。转义字符顾名思义就是转变意思。

下面看一些转义字符:

?因此在打印字符‘\’时,得写‘\\’,前一个'\'将后面的'\'转义。

因此正确做法:

#include<stdio.h>

int main() {
?? ?printf("c:\\code\\test.c\n");
}

运行结果:

?

#include <stdio.h>
int main ()
{
? ? // 问题 1 :在屏幕上打印一个单引号 ' ,怎么做?
? ? // 问题 2 :在屏幕上打印一个字符串,字符串的内容是一个双引号 ,怎么做?
? ? printf("%c\n",'\'');
?? ?printf("%c\n",'\"');
? ? return 0 ;
}

笔试题:?

// 程序输出什么?
#include <stdio.h>
int main ()
{
? ? printf ( "%d\n" , strlen ( "abcdef" ));
? ? // \32 被解析成一个转义字符
? ? printf ( "%d\n" , strlen ( "c:\test\328\test.c" ));
? ? return 0 ;
}

为什么?因为'\t'是转义字符,当成一个字符计算,其次是'\328',注意,?\ddd是转义字符,当且晋档仅当ddd是八进制数,因此d不可能大于8,也就是说只有'\32'是转义字符,而8不是,因此这里它们是两个字符。

拓展:怎么打印字符'%'?(重点)

?但是如果要在格式串里打印%怎么做?

下面这种做法可以吗??

用转义字符??如下:?

?发现格式中打印%是没有转移字符这种做法的,正确做法如下:

?结论:原来打印格式串中打印%要用%来转义。

注释
1. 代码中有不需要的代码可以直接删除,也可以注释掉
2. 代码中有些代码比较难懂,可以加一下注释文字
比如:
#include <stdio.h>
int Add ( int x , int y )
{
? ? return x + y ;
}
/*C 语言风格注释
int Sub(int x, int y)
{
? ? return x-y;
}
*/
int main ()
{
? ? //C++ 注释风格
? ? //int a = 10;
? ? // 调用 Add 函数,完成加法
? ? printf ( "%d\n" , Add ( 1 , 2 ));
? ? return 0 ;
}
注释有两种风格:
C 语言风格的注释 /*xxxxxx*/
? ? 缺陷:不能嵌套注释
C++ 风格的注释 //xxxxxxxx
可以注释一行也可以注释多行
选择语句
如果你好好学习,校招时拿一个好 offffer ,走上人生巅峰。
如果你不学习,毕业等于失业,回家卖红薯。
这就是选择
#include <stdio.h>
int main ()
{
? ? int coding = 0 ;
? ? printf ( " 你会去敲代码吗?(选择 1 or 0 :>" );
? ? scanf ( "%d" , & coding );
? ? if ( coding == 1 )
? {
? ? ? prinf ( " 坚持,你会有好 offer\n" );
? }
? ? else
? {
? ? ? printf ( " 放弃,回家卖红薯 \n" );
? }
? ? return 0 ;
}
循环语句:
有些事必须一直做,比如我日复一日的讲课,比如大家,日复一日的学习。
还比如:
C 语言中如何实现循环呢?
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 ( " 赢取白富美 \n" );
? ? return 0 ;
}
函数
#include <stdio.h>
int main ()
{
? ? int num1 = 0 ;
? int num2 = 0 ;
? ? int sum = 0 ;
? ? printf ( " 输入两个操作数 :>" );
? ? scanf ( "%d %d" , & a , & b );
? ? sum = num1 + num2 ;
? ? printf ( "sum = %d\n" , sum );
? ? return 0 ;
}
上述代码,写成函数如下:
#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 ;
}
函数的特点就是简化代码,代码复用。
数组: 要存储 1-10的数字,怎么存储?C 语言中给了数组的定义:一组相同类型元素的集合
数组定义
int arr [ 10 ] = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 }; // 定义一个整形数组,最多放 10 个元素
数组的使用
#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 ;
}

操作符

?简单介绍为主,后面课件重点讲。

算术操作符
+ - * / %

?移位操作符

>>? ? <<

?位操作符

& ^ |

?赋值操作符

= += -= *= /= &= ^= ?|= ? ?>>= ? <<=

单目操作符

!? ? ? ? ??逻辑反操作
- ? ? ? ? ? 负值
+ ? ? ? ? ? 正值
& ? ? ? ? ? 取地址
sizeof ? ? ? 操作数的类型长度(以字节为单位)
~ ? ? ? ? ? 对一个数的二进制按位取反
-- ? ? ? ? ? 前置、后置 --
++ ? ? ? ? ? 前置、后置 ++
* ? ? ? ? ? 间接访问操作符 ( 解引用操作符 )
( 类型 ) ? ? ? 强制类型转换
注意: 逻辑反和按位取反是不同的,逻辑反就是真变假,假变真,而按位取反是对这个数在计算机中存储的的每一位取反(1变0,0变1),整数在计算机中以补码形式存储,因此按位取反是对它的补码取反
关系操作符
>
>=
<
<=
!= ? 用于测试 不相等
== ? ? ? 用于测试 相等

?逻辑操作符

&& ? ? 逻辑与
|| ? ? ? ? ? 逻辑或

?条件操作符

exp1 ? exp2 : exp3

?逗号表达式(重点,笔试题中很喜欢出)

?exp1, exp2, exp3, …expN

下标引用、函数调用和结构成员?

[ ]? ?( )? ?.? ? ?->

?常见关键字

auto ? break ? case ? char ? const ? continue ? default ? do ? double else ? enum ?
extern float ? for ? goto ? if ? int ? long ? register ? ? return ? short ? signed
sizeof ? static struct ? switch ? typedef union ? unsigned ? void ? volatile ? while

?注:关键字,先介绍下面几个,后期遇到讲解:

关键字 typedef
typedef 顾名思义是类型定义,这里应该理解为类型重命名。
比如:
// unsigned int 重命名为 uint_32, 所以 uint_32 也是一个类型名
typedef unsigned int uint_32 ;
int main ()
{
? ? // 观察 num1 num2, 这两个变量的类型是一样的
? ? unsigned int num1 = 0 ;
? ? uint_32 num2 = 0 ;
? ? return 0 ;
}
关键字 static
C 语言中:
static 是用来修饰变量和函数的

1. 修饰局部变量 - 静态局部变量
2. 修饰全局变量 - 静态全局变量
3. 修饰函数 - 静态函数

修饰局部变量

// 代码 1
#include <stdio.h>
void test ()
{
? ? int i = 0 ;
? ? i ++ ;
? ? printf ( "%d " , 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 " , i );
}
int main ()
{
int i = 0 ;
? ? for ( i = 0 ; i < 10 ; i ++ )
? {
? ? ? ? test ();
? }
? ? return 0 ;
}

?运行结果:

?对比代码1和代码2的效果理解static修饰局部变量的意义。

结论:

static修饰局部变量改变了变量的生命周期,让静态局部变量出了作用域依然存在,到程序结束,生命周期才结束,在子函数中,static修饰的局部变量不管调用多少次,只赋值一次,即第一次调用赋值的结果,也就是说它只赋值一次,其余次的调用都是保存上一次调用的值。
修饰全局变量
// 代码 1
//add.c
int g_val = 2018 ;
//test.c
int main ()

{

? printf ( "%d\n" , g_val );
? ? return 0 ;
}
?在vs编译器这里会出错,如下:
这是add.c的内容:

这是test.c的内容:

已经报错了,为什么?是没有引用头文件吗?

改成如下:

?

?编译没警告,但是出现不能运行,这是为什么?这种解决方法不是说它是错的,只是它在VS编译器上不行,VS编译器整个环境是一个工程,这种引用头文件是会出错的,正确做法如下:

得用extern关键字声明,既然都说到这里,那就说一下extern的作用参考:

extern关键字_四川精神小伙的博客-CSDN博客

// 代码 2
//add.c
static int g_val = 2018 ;
//test.c
int main ()
{
? ? printf ( "%d\n" , g_val );
? ? return 0 ;
}

?add.c的内容:

test.c的内容:

?不能运行:但是如果顶部添加#include"add.c"头文件,这个代码就能正常运行,这里大家不用太纠结,因为编译器不同。处理方式也不一样。

代码 1 正常,代码 2 在编译的时候会出现连接性错误。
结论:
一个全局变量被static修饰,使得这个全局变量只能在本源文件内使用,
不能在其他源文件内使用。

文章来源:https://blog.csdn.net/qq_51956388/article/details/130761920
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。