从无到有的C语言学习历程

哈喽,大家好,第一次写博客,为了记录我的C语言学习历程,同时过一遍自己学习的知识,这篇博客会随着我的学习持续更新,其中一些内容参考了B站鹏哥,百度,知乎和csdn的其他大佬们的知识讲解。有什么问题的话,烦请大家帮忙指出,谢谢!!

一、C语言的基本概念

1、什么是C语言?


C语言是一门面向过程的、抽象化的通用程序设计语言,广泛应用于底层开发。C语言能以简易的方式编译、处理低级存储器。C语言是仅产生少量的机器语言以及不需要任何运行环境支持便能运行的高效率程序设计语言。尽管C语言提供了许多低级处理的功能,但仍然保持着跨平台的特性,以一个标准规格写出的C语言程序可在包括类似嵌入式处理器以及超级计算机等作业平台的许多计算机平台上进行编译。

2、编译器

(1)编译器的选择

在学习c语言的的过程中,我选择的是vs2022社区版

(2) vs2022的优缺点

vs2022是一个主流的集成开发环境,其中包含了:编译器、编辑器、调试器。功能强大,基本不用额外配置环境,上手容易,对初学者很友好。
它的不足是安装包大,占用空间多。

3、C语言的基本程序结构

#include <stdio.h> //头文件(用于声明函数、变量、宏等的定义)
int main() //主函数(main() { } 被大括号{ }括起来的内容称为main函数的函数体,这部分内容就是计算机要执行的内容)
{
     printf(""); //库函数(在屏幕上进行信息打印输出)注意!不要忘记括号外的“ ;”
     return 0;//返回类型(终止函数执行的一种方式)
     }

在写代码的时候,我们要将输入法改为英文,这样写的代码才能编译执行。
其中,main函数被叫做:主函数;每个C语言程序都是从main函数开始执行的,main函数是程序的入口
注意:在一个C语言程序中,主函数有且只有一个!!
而 printf函数 可以用来打印各种类型的数据,只要把想要输出的数据放在双引号里并传递给printf函数就可以打印。
但是使用库函数时,是需要包含头文件的,printf函数包含的就是stdio.h这个头文件。
具体的表示方法如下:

#include <stdio.h>

末尾的return语句用来结束循环,或返回一个函数的值。

return 0:一般用在主函数结束时,按照程序开发的一般惯例,表示成功完成本函数。

main函数的返回值用于说明程序的退出状态。如果返回0,则代表程序正常退出。返回其它数字的含义则由系统决定。通常,返回非零代表程序异常退出

当你看到这想必应该对C语言的基本程序结构有了大概的了解,学习C语言怎么能少了”hello world“,下面让我们来用C语言输出“hello world”吧

#include <stdio.h>
int main()
{
    printf("hello world\n");//其中\n表示换行
    return 0;
    }

真棒,完整的写出来了呢!恭喜你已经掌握了C语言的基本程序结构!
接下来,让我们继续往下学习。

4、C语言的基本元素

包括标识符、关键字、字符。

(1)标识符

程序设计语言中为变量、常量、类型、函数等取的名字称为标识符。
标识符由大小写英文字母、数字、下划线组成,并且只能以大小写英文字母或者下划线作为首字母。

C语言中的标识符不能使用任何中文字符,包括汉字、中文标点。

(2)关键字

C语言中有一批保留的名字的符号,比如:int、if、return、这些符号被称为保留字或者关键字。C语言中共有32个关键字。

  • 关键字都有特殊的意义,是保留给C语言使用的
  • 程序员自己在创建标识符的时候是不能和关键字重复的
  • 关键字也是不能自己创建的
    32个关键字如下:
auto double int struct break else long switch  case enum register 
typedef char extern return union  const float short unsigned continue 
for signed void   default goto sizeof volatile do if while static

注:https://zh.cppreference.com/w/c/keyword (C语言关键字的全部介绍)

(3)字符和ASCII码

在键盘上可以敲除各种字符,如:a,q,@,#等,这些符号都被称为字符,C语言中字符都是用单引号括起来的,如:‘a’,‘b’,‘@’。

在计算机中所有数据都是以二进制的形式存储的,而这些字符中的每一个字符编一个了二进制序列,我们把它叫做编码,字符通过编码的方式在内存中存储。为了方便通信,不造成混乱,这时,ASCII编码诞生了,C语言中的字符就遵循了ASCII编码的方式。

1.ASCII码

在这里插入图片描述
ASCII码参考:link.

ASCII码中需要掌握的几组特殊的数据:

  • 字符A~Z的ASCII码值从60 ~90
  • 字符a~z的ASCII码值从97 ~122
  • 对应的大小写字符(a和A)的ASCII码值的差值是32
  • 数字字符0~9的ASCII码值从48 ~57
  • 换行 \n 的ASCII值是:10
  • 在这些字符中ASCII码值从0~31 这32个字符是不可打印字符,⽆法打印在屏幕上观察

单个字符的打印可以使用%c来指定格式:

#include <stdio.h>
int main()
{
    printf("%c\n",'Q');
    printf("%c\n",81);//这里的81是字符Q的ASCII码值,是可以正常打印的
    return 0;
 }

如图为该程序调试的结果:
在这里插入图片描述
C语言中可打印的字符可以用下面的代码打印出来:

#include <stdio.h>
int main()
{
	int i = 0;
	for (i = 32; i <= 127; i++)
	{
		printf("%c ", i);
		if (i % 16 == 15)
			printf("\n");
	}
	return 0;
}

得到的结果如下图所示:
在这里插入图片描述

2.字符串和\0

C语言中使用双括号括起来的一串字符就被称为字符串,如:"abcdef"就是一个字符串。
字符串的打印格式可以使用%s来指定,也可以直接打印:

#include <stdio.h>
int main()
{
	printf("%s\n", "hello C");
	printf("hello c\n");
	printf("你好 C");//注意此处,一个汉字是占两个字节的
	return 0;
}

在字符串的末尾隐藏放着一个\0字符,\0字符是字符串的结束标志。

在使用库函数printf()打印字符串或者strlen()计算字符串长度时,遇到**\0**时就会自动停止计算
注:strlen()是用来获取字符串的有效长度的,结尾标记’\0’不包含在内。
strlen()获取的规则非常简单:从前往后依次检测,直到遇到’\0’是就终止检测。

在C语言中,用来存放字符的数组称为字符数组。字符数组实际上是一系列字符的集合,也就是字符串
例如:char arr1[ ]=“abc”,char arr1[] = {‘a’, ‘b’, ‘c’}。
现在,,我们将用下面的代码来验证\0。

#include <stdio.h>
int main()
{
 char arr1[] = {'a', 'b', 'c'};//arr1数组中存放的是3个字符
 char arr2[] = "abc"; //arr2数组中存放的是字符串
 printf("%s\n", arr1);
 printf("%s\n", arr2);
 
 return 0;
}

在这里插入图片描述
在这里插入图片描述
如上图,arr1的输出结果除了abc还打印了一些随机值,而arr2输出结果仅为 abc。
原因是arr1包含的是单个字符,不包含\0,程序就会一直打印下去,而arr2包含的是字符串,其中包含了\0,故而打印到\0时,程序就会自动停止。

那么,如果我们主动在arr1数组中放一个’\0’字符,结果会不会变呢?

 #include <stdio.h>

int main()
{
	char arr1[] = { 'a', 'b', 'c', '\0' };
	char arr2[] = "abc";
	printf("%s\n", arr1);
	printf("%s\n", arr2);
	printf("%s\n", "abc\0def");
    return 0;
}

在这里插入图片描述
经测试,结果完全一致。三次结果都是打印到\0就停止了。
所以我们要记住:\0是个拦路虎,遇到 \0 就停止;字符串中藏 \0 ,单字符中无 \0

3.转义字符

在字符中有一组特殊的字符是转义字符,顾名思义:转变原来的意思的字符。
比如:\n、\0。
就拿\n来说,\n是一个转义字符表示换行的意思,n本来是一个普通的字符,被 \ 转义为换行的意思。
C语言中还有类似的转义字符,如下:

在这里插入图片描述
在这里插入图片描述
下面2种转义字符可以理解为:字符的8进制或者16进制表示形式

  • \ddd :d d d表示1~3个八进制的数字。如:\130 表示字符X 130的八进制等于 1x82+3x81+0x80 =88(十进制) ASCII码中 八进制130 十进制88 代表字符X。
  • \xdd :d d表示2个十六进制的数字。如:\x30 表示字符0

转义字符参考:link.

5、C语言中的2种注释形式

(1)/**/的形式

将注释放在 /* …… */ 之间,内部可以分行。

/*注释*/

/*
这是一行注释
*/

这种注释可以插在行内。

 int fopen(char* s /* file name */, int mode);

注:这个里面的注释会被执行为一个空格。

/* file name */ 用来对函数参数进行说明,跟在它后面的代码依然会有效执行。
/**/ 的这个注释也不支持嵌套注释,/*开始注释后,遇到第⼀个 */ 就认为注释结束了。

(2)//的形式

将注释放在双斜杠 //后面,从双斜杠到行尾都属于注释。这种注释只能是单行,可以
放在行首,也可以放在一行语句的结尾。

//这是一个注释

int x;//这是一个注释

不管是哪一种注释,都不能放在双引号里面。
双引号里面的注释符号,会成为字符串的一部分,解释为普通符号,失去注释作用。

printf("// hello /* world */ ");

如上所示,双引号里面的注释符号,都会被视为普通字符,没有注释作用。

6、C语言中的数据类型

(1)数据类型的介绍

C语言中使用整数类型来描述整数,使用字符类型来描述字符,使用浮点型类型来描述小数。编译器只有知道了数据类型,才知道怎么操作数据。

数据类型
内置类型
字符
char
自定义类型
数组
整型
int
浮点型
单精度float
双精度double
布尔类型
结构体-struct
枚举-enum
联合体-union

(2)signed 和 unsigned

C语言使用signed 和 unsigned 关键字修饰字符型和整型类型的。

signed 关键字,表示一个类型带有正负号,包含负值;

unsigned 关键字,表示该类型不带有正负号,只能表示零和正整数。

整数变量声明为 unsigned 的好处是,同样长度的内存能够表示的最大整数值,增大了一倍。
比如,16位的 signed short int 的取值范围是:-32768~32767,最大是32767;而unsigned short int 的取值范围是:0~65535,最大值增大到了65,535。32位的 signed int 的取值范围可以参看 limits.h 中给出的定义

(3)字符类型

有符号的类型无符号的类型
char/[signed] charunsigned char

注意,C 语⾔规定 char 类型默认是否带有正负号,由当前系统决定。
这就是说, char 不等同于 signed char ,它有可能是 signed char ,也有可能是
unsigned char 。

(4)整型类型

短整型整型长整型更长的整型
short [int]intlong [int]long long [int]
[signed] short [int][signed] int[signed] long [int][signed] long long [int]
unsigned short [int]unsigned intunsigned long [int]unsigned long long [int]

[ ]内的可以省略不写。

(5)浮点型

单精度实型双精度实型长双精度实型
floatdoublelong double​

浮点型就是指小数点是可以浮动的。
例如:3.14=31.4x10-1=0.314x101

(6)布尔类型

C 语言原来并没有为布尔值单独设置⼀个类型,而是使用整数 0 表示假,非零值表示真。
在 C99 中引入了 布尔类型 ,是专门表示真假的。

 _Bool

布尔类型的使用得包含头⽂件 <stdbool.h>
布尔类型变量只有两个取值:true或者false

#define bool _Bool
#define false 0
#define true 1

以上是用来宏定义布尔类型,不过直接输入头文件#include <stdbool.h>更为简便

代码演示:

 #include <stdio.h>
#include <stdbool.h>
int main()
{
	_Bool flag = true;
	if (flag)//此处为if()为if语句,括号后面没有分号
	printf("i like C\n");
    return 0;
}

C语言中一般设置一个变量flag,是一个来表示判断的变量,当做标志。

(7)数据类型的取值范围

每⼀种数据类型有自己的取值范围,也就是存储的数值的最大值和最小值的区间。

limits.h 文件中说明了整型类型的取值范围。
float.h 这个头文件中说明浮点型类型的取值范围。

为了代码的可移植性,需要知道某种整数类型的极限值时,应该尽量使⽤这些常量。

  • SCHAR_MIN , SCHAR_MAX :signed char 的最小值和最大值
  • SHRT_MIN , SHRT_MAX :short 的最小值和最大值。
  • INT_MIN , INT_MAX :int 的最小值和最大值。
  • LONG_MIN , LONG_MAX :long 的最小值和最大值。
  • LLONG_MIN , LLONG_MAX :long long 的最小值和最大值。
  • UCHAR_MAX :unsigned char 的最大值。
  • USHRT_MAX :unsigned short 的最大值。
  • UINT_MAX :unsigned int 的最大值。
  • ULONG_MAX :unsigned long 的最大值。
  • ULLONG_MAX :unsigned long long 的最大值。

7、c语言中的常量和变量

(1)常量

直接常量:直接拿来使用,无需说明的量。
如:

  • 整型常量:1、-1、0
    
  • 实型常量:1.2、-1.45
    
  • 字符常量:'a'、'B'
    
  • 字符串常量:"i like c"
    

符号常量:用一个标识符来表示一个常量,使用前必须要定义。

#define 标识符 常量值
#define POCKETMONEY 10   //定义常量及常量值

在程序中定义符号常量后,当代码中存在此符号常量,不能在后续代码中改变。

(2)变量

我们使用数据类型是用来创建变量的,C语言中把经常变化的值称为变量。
变量创建的语法形式是这样的:

  • data_type name;
       |        |
     数据类型 变量名
    

变量在创建的时候就给⼀个初始值,就叫初始化。
1

1.变量的分类
  • 全局变量:在⼤括号外部定义的变量就是全局变量
    全局变量的使用范围更广,整个工程程中想使用,都是有办法使用的。
  • 局部变量:在大括号内部定义的变量就是局部变量
    局部变量的使⽤范围是比较局限,只能在自己所在的局部范围内使用的。
#include <stdio.h>
int global = 2023;//全局变量
int main()
{
 int local = 2018;//局部变量
 printf("%d\n", local);
 printf("%d\n", global);
 return 0;
}

当局部变量和全局变量同名的时候,局部变量优先使用。

2.变量的储存

⼀般我们在学习C/C++语⾔的时候,我们会关注内存中的三个区域:栈区、堆区、静态区。

  • 局部变量是放在内存的栈区
  • 全局变量是放在内存的静态区
  • 堆区是⽤来动态内存管理的

7、C语言中的操作符

(1)算术操作符

分别是: + - * \ % ,都是双目操作符。
注:操作符也被叫做:运算符,是不同的翻译,意思是⼀样的。

名称运算符号举例
加法操作符+int x=5+6
减法操作符int x=15-3
乘法操作符*int x=5*6
除法操作符/int x=30/3
求模操作符(取余)%15%2=1

注意:
在除法中

  • 除号的两端如果是整数,执⾏的是整数除法,得到的结果也是整数,有小数的部分忽略。
    如:10/3=3
  • 如果希望得到浮点数的结果,两个运算数必须⾄少有⼀个浮点数。
    如: 6.0 / 4= 1.500000
    在求模运算符中
  • 只适用于整数,不能⽤于浮点数。
  • 负数求模的规则是,结果的正负号由第⼀个运算数的正负号决定。
  •  如:(-5)%3= -2         5 % (-3)=2
    

(2)赋值操作符

在变量创建的时候给⼀个初始值叫初始化,在变量创建好后,再给⼀个值,这叫赋值。

int a = 100;//初始化
a = 200;//赋值,这⾥使⽤的就是赋值操作符

赋值操作符 = 是⼀个随时可以给变量赋值的操作符。

  • 连续赋值
int a = 3;
int b = 5;
int c = 0;
c = b = a+3;//连续赋值,从右向左依次赋值的。
  • 复合赋值符
int a = 10;
a += 3;//a=a+3
a -= 2;//a=a-3

C语⾔中提供了复合赋值符,⽅便我们编写代码,这些赋值符有:

  •    +=   -=    *=  /=  %=  >>=     <<=    &=   |=    ^=
    

(3) 单目操作符

前面介绍的操作符都是双目操作符,有2个操作数的。C语言中还有⼀些操作符只有⼀个操作数,被称为单目操作符。 ++、–、+(正)、-(负) 就是单目操作符的。

  • ++是⼀种自增的操作符,- -是一种自减的操作符。
自增操作符举例计算口诀结果
前置++int a=1;b=++aa先+1,后使用a=2,b=2
后置++int a=1;b=a++先使用,后+1a=2,b=1
前置- -int a=1;b=- -a先-1,后使用a=0,b=0
后置- -int a=1; b=a- -先使用,后-1a=0,b=1
  • +和-

这⾥的+是正号,-是负号,都是单目操作符。

运算符 + 对正负值没有影响,是⼀个完全可以省略的运算符
int a = +10; 等价于 int a = 10;

运算符 - 用来改变一个值的正负号,负数的前面加上 - 就会得到正数,正数的前面加上 -会得到负数。

(4)三目操作符

?: 三目操作符,又称条件运算符,是计算机 语言 (c,c++,java等)的重要组成部分。. 它是唯一有3个操作数的运算符。
它的作用就是用来判断.
格式为:表达式1?表达式2:表达式3;

它先判断表达式1的值是否为真,如果为真,则执行表达式2,如果为假,则执行表达式3。

(5)关系操作符

符号举例运算结果
大于 >6>51
小于 <6<50
大于等于 >=5>=51
小于等于5<=51
等于 ==6==50
不等于 !=6!=51

关系表达式的值是真和假。表达式关系成立,表达式结果为真,用1表示真。 表达式关系不成立,表达式结果为假,用0表示假

多用于循环判断语句中

(6)逻辑操作符

在这里插入图片描述
逻辑运算的值也是只有 真和假,C语言中,用整型的1和0来表示。

  • 如果 &&逻辑与左侧的子表达式为 0,则不会检查右侧的表达式。因为只要有一个子表达式为 0,则整个表达式都为 0,
  • 如果 ||逻辑或 中只要其中一个子表达式为 1,则整体表达式为1,此时另外一个子表达式无论是 0 还是1都无关紧要,两个子表达式全为0的话,则整体表达式为0。

(7)操作符之间的优先级顺序

在这里插入图片描述
级别为1的优先级最高,级别为10的优先级最低。

(8)强制类型转换

在操作符中还有⼀种特殊的操作符是强制类型转换,语法形式很简单,形式如下:

  •    (类型)
    

如下:

int a = 3.14;
//a的是int类型, 3.14是double类型,两边的类型不⼀致,编译器会报警告

这时,我们可以使⽤强制类型转换消除警告

int a = (int)3.14;//意思是将3.14强制类型转换为int类型,这种强制类型转换只取整数部分

8、C语言中的占位符

最前面说的printf()输出函数可以在输出文本中指定占位符。
所谓占位符就是这个位置可以用其他值植入。
例如:

#include <stdio.h>
int main()
{
 printf("%d\n", 3);
 return 0;
}

如上所示,%d\n 是输出⽂本,里面的 %d 就是占位符,表示这个位置要用其他值来替换。占位符的第一个字符一律为百分号 % ,第二个字符表示占位符的类型, %d 表示这里代入的值必须是一个整数。
printf() 的第⼆个参数就是替换占位符的值,上面的例子是整数 3 替换 %d 。
常⽤的占位符除了 %d ,还有 %s 表⽰代⼊的是字符串。

#include <stdio.h>
int main()
{
 printf("%s will come tonight\n", "张三");//由于要输出的是%s,这里的张三为字符串,要用" "双引号括起来
 return 0;
}

上面示例中, %s 表示代入的是⼀个字符串,所以 printf() 的第⼆个参数就必须是字符串。
得到的结果如下:
在这里插入图片描述

输出⽂本⾥⾯可以使⽤多个占位符。但是需要于想输出的结果一一对应.
例如:

printf("%s说现在%d点钟\n", "李四", 21);//李四对应 %s,21 对应%d;

测试结果如下:
在这里插入图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值