初学C语言基础知识

PS:个人使用的编译器是VS2019

1.学习C语言认识的第一串代码

#include<stdio.h>//引用库函数的头文件

int main()//主函数,每个C语言obj有且仅有一个主函数

{

printf("hello,world")//输出,引用C语言拥有的库函数,需要用预处理指令向编译器告知要调用这个函数

return 0;//函数返回值为0

}


2.数据类型总结

我们知道,C语言有不少数据类型,如:

char //字符型数据类型,可以类比英文字母

short //短整型数据类型,与int相比,储存变量的字节数小于等于int的字节

int //整形,可以类比数学中的数字

long //长整形,与int相比,储存变量的字节数大于等于int的字节数

long long//更长的整形

float//单精度浮点型,可以类比数学中的小数

double//双精度浮点型,于float相比,其储存变量后的小数点位比float更精确

简单介绍C语言的数据类型后,相比你挺想知道这几个类型占用内存的字节数吧,当我们想知道他们占用内存的字节数时,我们可以使用sizeof的关键字,其使用方法如下:

#include<stdio.h>

int main()

{

printf("%d\n",sizeof(char));//%d在输出函数的使用中表示打印整形在显示屏上,逗号后为打印的对象

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;

}

综上所述,我们知道了sizeof的基础用法,即sizeof(数据类型)


3.常量 变量

我们知道,生活中有很多不变的量和很多会变化的量,如圆周率,一个人的性别等;我们还知道,生活中还有很多变化的量,如一个人的身高和体重等。C语言中也有常量和变量,C语言中使用变量可以是一个字母或者一串字母串,但不能是数字或中文。而常量最常见的还是数字。

3.1定义变量的方法

int age=1;

double i=3.14;

char ch=‘a’;

3.2变量的分类

变量总共可以分为局部变量和全局变量两种

我们看看一下代码:

#include<stdio.h>

int i=10;//全局变量,在主函数之外的变量称为全局变量

int main()

{

int i=100;//局部变量,在靠近{}里定义的变量称为在这个{}局域范围内的局部变量

printf("%d\n",i);

return 0;

}

让我们猜一猜如果打印出i的值,最后会是多少呢?

如果我们让这个代码跑起来时:

发现打印出来的值是局部变量里存放的值,这也是在告诉我们:如果局部变量和全局变量变量相同时,局部变量的值优先被打印出来,而全局变量不被打印。

 3.3 变量的作用域和生命周期

怎么理解变量的作用域?每次碰到这个术语我有时会忘记其含义是什么。但我发现其实变量的作用域可以和变量的生命周期一起来记忆,其中这两个术语存在密不可分的关系。

在一个主函数或函数的变量中,若创建一个临变量,则这个临时变量的作用域就在离它最近的花括号内起作用,而这个花括号内的代码范围叫做这个临时变量的作用域;而离开这个花括号后该临时变量就失去了它在这个花括号范围的使用权限,这叫做该临时变量失去了它的生命周期,因此我们可知道该临时变量的生命周期是在花括号运行过程的这段时间。

PS:

1.  全局变量的生命周期是:整个工程的生命周期。

2:全局变量的作用域是:整个工程。

3.4 常量

顾名思义,常量即不变的量,如圆周率等等。在工程内创建常量可用变量作为载体进行赋值。


4.字符串 + 转义字符 + 注释

4.1 字符串

“hello”

这种双引号引起来的一串字符称为字符串字面值,或者简称字符串。

但我们在工程中常常这样定义字符串的:

1. 
char arr[] = "hello";
2.
2.1
char arr[] = {'h','e','l','l','o'};
2.2
char arr[] = {'h','e','l','l','o','\0'};

我个人比较多使用第一种定义方式,因为采用第二种定义方式就常常会出现错误,其实2.1是错误的定义的方式,这里我们就要引进字符0的作用了:

\0与\n都是转义字符,而\0的作用是控制字符的长度,而如果没有加上转义\0的话,编译器就不知道你定义的字符串长度会多少,编译器就会自己寻找\0,直到找到\0为止才确认该字符串的长度,但编译器找不到\0到定义字符串的有效代码这个过程中,你如果去打印的话,会出现一段乱码

在编译器下输入2.1代码并打印字符串时时,就会出现一下情况:

即编译器除了打印目标字符串还打印出一串乱码 .

4.2 转义字符

C语言存在一种特殊的字符,即转义字符,转义字符有很多,每一种转义字符都有各自的作用,以下为大家列举一些C语言常用的转义字符:

1.  ‘\?’ :在书写连续多个问号时使用,防止他们被解析为三字母词

那么很多人便会产生疑惑,什么是三字母词呢?

三字母词在某些编译器上是存在的,如:??)。

??)在某些编译器内是一种三字母词,而它在某些编译器上会被解析成  ] 。

所以如果你在打印中输入:(are you ok??)

时,就会被解析成:(are you ok]。

 所以,在某些编译器中存在的三字母词会使打印效果变差,因此也引进了解决该种问题的转义字符。

2. ‘ \' ’ :用于表示字符常量 ‘ 。

3. ‘ \" ’:用于表示一个字符串内部的双引号。

4. ‘ \\ ’:用于表示一个反斜杠。

5. ‘ \a ’:警告字符,蜂鸣。

6. ‘ \b ’:退格符。

7.' \f ':进纸符。

8. ' \n ':换行。

9. ‘ \r ’:回车。

10. ' \t ':水平制表符。

11. ' \v ':垂直制表符。

12. ' \ddd ':ddd表示1~3个八进制的数字,如:\130。

13. ' \xdd ':dd表示2个十六进制数字,如:\x30。

5. 注释

C语言引进注释,一方面是在比较难懂的代码语句后添加中文加以解释,另一方面,有效的代码语句也能被注释掉成为无法执行的代码语句。下面介绍两种注释风格:

1. C语言风格的注释:/*xxxxxxxxx*/

ps:C语言注释存在的一大缺陷就是无法嵌套注释,导致注释效率低。

2. C++风格的注释://xxxxxxxxxxx//

C++风格注释即使用于C++,也使用于C语言。不仅如此,也规避了第一种注释风格的缺陷,即该种注释风格可以采用嵌套注释,所以,我们采用注释的时候还是有限推荐C++风格的注释。

综上,我们介绍了两种注释风格,但是,有些编译器是有注释命令选项的,可以方便选定代码行进行注释。

6.选择语句

每个人的人生在不同的阶段都存在选择,下面给大家介绍两种常用的选择语句。

分别是:1. if语句      2.switch语句

一 、if语句的基本格式是:if(condition)

一般情况下,if(condition)后面节{内容},{}内是判断if语句内condition成立而所完成的内容。

 如果括号内condition成立,即执行if以下的语句,若成立,则不执行if的所属句。

不仅如此,如果if语句不成立,还可以添加与if语句配套的else{内容},如果if不成立,则执行else{内容},可以理解为if和else是互斥的,但他们也是常常配套一起使用的。除此之外,还可以使用else if(condition),与if一样,相当于是if的衍生情况,如果if不成立,还可以继续else if(condition)进行判断。

二 、 switch语句

switch语句的一般结构为:

switch(变量或value)

{

case 常量:

{内容};

case 常量:

{内容};

case 常量:

{内容};

……

}

通过(变量或value)所赋予的值来匹配以下的case语句。

综上,我们可以得知,if语句多用于双分支语句,而switch多用于多分支语句,我们要视情况使用语句。

7. 循环语句

在C语言中,存在一种循环语句来达成某种循环效果,最常见的循环语句莫过于while、for、do{执行语句}while(表达式)   循环语句。下面我们来初步认识一下这两个循环语句的循环效果。

(1).while语句

以下是while语句的基础用法:

while(表达式)

{

执行语句;

}

首先,如果()内的表达式成立,则进入while语句内部,执行语句生效,若表达式不成立,则循环失效,while循环语句无法进入。我们以达到某一目的来使用while语句。

(2)  for语句

C语言中最常使用的循环语句就是for语句了,因为该语句表达内容简单明了,没有过于复杂的操作过程,使得代码的可读性增大,for语句的基本形式是:

for (variable = value; condition; adjustment)

{

执行语句;

)

之所以说for循环语句好用,是因为这个语句很巧妙地将赋值、判断条件、变量调整统一表达在括号中,可以很清晰地判断循环语句的执行逻辑。我们知道,每个循环语句都有其缺点和优点,而for语句也存在其相应的缺点,for语句赋值过程的执行只能进行一次,而判断条件是根据语句真假关系进行判断的,而调整是在判断语句为真的条件下才执行的,所以有些题目考察到for循环语句的时候·,总会在赋值和判断语句挖坑让同学们去跳。

当我们明白for语句的执行流程后,这个语句的判断条件和调整变量这两个过程还时常和指针和数组等等的知识点一起结合,所以有时要判断for循环语句的执行原理也会较为困难。

(3)  do{……}while(condition)语句

do{}while()语句真的可以说是循环语句里面最不常用的语句了,首先这个语句会先执行do,即先执行{}内部的内容,再来判断while()内部()的真假,才来决定循环是否能继续执行。综上所述,就可以知道其实do{}while()语句至少会执行一次。当然,之所以说它不常用,与其至少能执行一次语句分不开瓜葛,确实,至少执行一次循环语句还不如使用while循环和for循环语句,这两种语句怎么说都比其更好用,辨识度也跟高。当然,它也有其好处,对于需要制作某些小游戏时,使用do{}while()语句可能要比前两种语句效果要更好,这是为什么呢,这种优势尤其是体现在打印游戏菜单的时候,至少打印一次游戏菜单,再通过用户的选择进行是否要继续进行游戏。

8.  函数

什么是函数?我们要进行写C语言代码之前,我们总会在编译器内熟练地输入int main(),其中main就是一个函数,它是整个工程的主函数。

那么除了主函数外,还有什么函数呢?当然,还有我们耳熟能详的库函数,例如printf,scanf等函数,他们是输入输出函数,除了这些库函数外,还有一些能够实现其他功能的库函数,在这里我们就不一一赘述了。

那么还有什么函数呢,出以上两者外,还有一种函数也是我们常用的,那便是自定义函数,自定义函数就是通过自己的需求去定义一个函数以实现某种目的,如何设计这个函数完全取决个人,想设计什么类型的函数也取决本人。

这里简单讲一下自定义函数,当我们定义函数的时候,需要先对函数进行声明,其次才能对函数进行调用,同时,我们还要知道,如果自定义函数没有定义类型,则它的默认返回类型是int类型的,但并不支持没有定义自定义函数的类型这种做法。

那么函数该怎么声明呢,这里介绍一个常用的声明函数的方法,如:

函数返回类型    函数名(定义传入的数据变量类型   传入的数据变量)(PS:定义传入的数据可以传入多个,按照自己的需求传入数据)

{

通过编写的代码完成函数功能;

}

接下来介绍函数调用,函数调用一般可以用在main函数内部或者其他函数内部,接下来我们以main函数内部实现函数调用为例,一起了解函数调用的过程:

int main()

{
函数名(常量);

}

首先要注意函数调用和函数声明的形式是有区别的,首先函数调用不用加函数返回类型,而且也不用定义传入数据变量类型,而且调用函数和函数声明有一个本质化的区别,调用函数是将常量传给函数声明内部定义的数据变量,使数据变量接收这个常数,于是这个变量就被赋予了常数这个值了。以上就是函数的基本介绍。

9.数组

9.1 数组定义

C语言中给了数组的定义:一组相同类型元素的集合。

我们以整型数组为例,写一个整型数组:

int arr[] = {1, 2, 3, 4 ,5, 6};

下面我们介绍一下这个数组的各个组成元素,首先arr是数组名,在一般情况下数组名都是代表着数组首元素地址,而操作符[]表示下标引用操作符,在[]内加入数字可以表示数组可容纳的数组元素个数,int则是数组内部元素的类型,而{}内部就是数组的元素。如果你想表示一个整形数组有6个元素的话,可以这样写:
int arr[6] = {1,2 3,4,5,6};

以上两种整形数组定义的方式都是正确的,编译器系统会识别数组的内容给数组定义大小,因此在[]内加不加入数字均可。此外,我们要定义一个什么类型的数组,只需要在类型和数组元素进行修改即可。

9.2 数组的下标

数组的下标真的非常奇妙,由于数组下标的设定,让我们编程的过程中提供了一定的便利,首先,数组的下标是要在数组升序的基础上减一的,我们以一个整形数组的例子来看看数组下标的微妙:

arr[6] = {1, 2,3,4,5,6};

我们现在想知道元素5的下标是多少,从左往右数它是第五个元素,但它的数组下标却是4,完整表示元素5的的形式是arr[4],而不是arr[5]。所以我们在访问数组内元素的时候,一般使用数组名+[下标]进行访问的。

10. 操作符

C语言

为用户提供的操作符可以说是非常多的,对操作符的掌握也是自己的代码写得让人看出你的得心应手,下面我们介绍几类C语言的操作符:

算数操作符:

+    -    *     /    %    ……

以上五种操作符分别是:加、减、乘、除、取模。之所以称之算数操作符,是因为这类操作符可以进行基础的算数计算,但我们还需要把重点放在除法和取模这两个操作符上。

首先是除法。如果你创建两个变量,两个都是int类型的,若一个变量赋值为3,另一个变量赋值为2,如果你直接将这两个变量相除,你会发现得出的结果不是1.333……,而是1,因为整形数据相除他是不会自己进行类型转换的,它给到你的结果类型就是整形,而3除2的得数整数位是1,所以最后的结果也是1。但是,如果你对以上创建的变量除以一个带小数的常数的话,你会发现结果是带小数的,这就牵扯到类型转换的知识点了,这里就先不扯出这个知识点了。或者你想得到小数点的数,也可以对以上的变量进行类型重定义或强转换。

接下来我们介绍取模,顾名思义取模就是对这两个操作数取余数,如果a%b表示b对a取余数,然后得到的余数再由用户自由处理。

那么接下来介绍下一种操作符,位操作符:

>>       <<  ……
 

以上位操作符分别为:右移操作符、左移操作符,这就很好辨别了,看箭头指向哪个方向就是什么操作符,这类操作符牵涉到电脑对数据的存储方式,我们可以知道,电脑存储数据是用二进制的方式进行存储的,那么这种操作符就是对这种二进制存储方式进行处理的,可以通过这种操作符将这些二进制存储方式自定义左移或右移几位,这是取决于用户本人的。

我们来介绍一下赋值操作符:

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

赋值操作符是在算数操作符和位操作符的基础上加上=号,而最后达成的效果也是加上=后的效果,即将操作后的数赋值给原来的数值,举个例子:

a /= 2;

表示a/2这个结果赋值给a,这在一定程度上将表达式表达得更简洁,如果不用该操作符就需要这么写:

a = a/2;

因此可见,该种操作符还是在一定程度上使代码更加简洁,但同时也更不易理解。

单目操作符:

!     逻辑反操作

-        负值

+       正值

&       取地址

sizeof       操作数的类型长度

~      对一个数的二进制位取反

--      前置、后置--

++    前置、后置++

*       间接访问操作符(解引用操作符)

(类型)       强制类型转换

关系操作符;

>        大于

>=        大于等于

<          小于

<=         小于等于

!=           判断若不等于为真,等于为假

==        判断等于为真,不等于为假

逻辑操作符:

&&         逻辑与

||            逻辑或

条件操作符:

exp1 ? exp2 : exp3

这里就要重点介绍条件操作符了,首先,上述语句的意思是:

表达式一先进行判断,若表达式一判断为真,表达式二就执行,若表达式一判断为假,那么表达式三执行。通常可以进行最大值和最小值的判断。

逗号表达式:

exp1, exp2, exp3, ……

逗号表达式内每个逗号之间的的表达式都要执行,但整个表达式的取值是按照最后一个·表达式结果进行取值的。

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

[]             下标引用操作符,通常用在对数组元素的调用

()          函数调用操作符,对函数传参和接受参数时使用

.               结构体成员访问操作符,通常是这样使用的:结构体变量.结构体成员

->              结构体成员间接访问操作符,通常使用在结构体指针变量,使用:结构体指针变                   量-> 结构体变量成员

以上所有就是C语言常见的操作符。

11. 常见关键字

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……

C语言提供了丰富的关键字,这些关键字都是语言本身预先设定好的,用户自己是不能创建关键字的。

11.1  关键字typedef

typedef这个关键词拆开的话为type  defined,顾名思义是类型定义,但这里应该理解为类型重命名。

那么这个关键字应该如何使用呢·:

typedef + 数据类型 + 转变的类型名称;
如:
typedef unsigned int uint;
上面的类型重定义就是对一个unsigned int的类型定义为uint的类型,之后的代码可以直接使用uint代替unsigned int以减少代码量。

11.2 关键字static

在C语言中,static是用来修饰变量和函数的

1修饰局部变量----称为静态局部变量

2.修饰全局变量-----称为静态全局变量

3.修饰函数-----称为静态函数

11.2.1. 修饰局部变量

static修饰局部变量有以下场景:

//代码1  未使用static后变量在函数内每次初始化都是0,故每次打印的结果都是1
#include<stdio.h>
void test()
{
int i = 0;
i++;
printf("%d", i);
}
int main()
{
iint i = 0;
for (i = 0; i < 10; i++)
{
test();
}
return 0;
}
//代码2  当使用static修饰局部变量的时候,每次进入函数都回记录下在函数内修改变量的值,再进入函数则会使用上次修改过后变量的值
#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;
}

结论:

static修饰局部变量改变了变量的生命周期

让静态局部变量出了作用域仍然存在,到程序结束,生命周期才结束

11.2.2  修饰全局变量

//代码1  未使用static修饰全局变量
//add.c下定义全局变量
int g = 2022;
//test.c
int main()
{
printf("%d\n", g);
return 0;
}

//代码2  使用static修饰全局变量
//add.c定义静态全局变量
static g = 2022;
//test.c
int main()
{
printf("%d\n", g);
return 0;
}

最后的结果便是代码1正常,代码2在编译时会出现链接性错误

结论:

一个全局变量被static修饰,使得这个全局变量只能在本源文件内使用,不能在其他源文件内使用。

11.2.3  修饰函数

//代码1  未使用static修饰函数
//add.c下定义函数
int Add(int x, int y)
{
return x + y;
}
//test.c
iint main()
{
printf("%d\n", Add(2,3));
return 0;
}

//代码2  使用static修饰函数
//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修饰,使得这个函数只能在本源文件内使用,不能在其他源文件内使用。

12.  #define 定义常量和宏

//define定义标识符常量
#define MAX 100
这样在该源文件内使用MAX在编译期间都会被替换为100;

//define 定义宏

用#define定义宏和函数定义相似,但意义却不同,首先定义变量后,后面的表达式是准备在使用时替换的表达式
#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;
}
以上两个sum的结果分别为5和50

可能你会觉得宏替换好像没什么难的,那如果将宏改为

#define ADD(x,y)  (x) + (y)

那么第一个sum还是5,但第二个sum就不再是50了,而是23了,为什么是23呢?

很简单,将宏带入第二条计算sum的表达式,得到:

sum = 10 *2 + 3;

最后得到sum的值为23。

13.  指针

内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行得。

所以为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小都是1个字节

为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址。

变量是创建内存中的(在内存中分配空间的),每个内存单元都有地址,所以变量也是有地址的,而我们通常把存放这些地址的变量称为指针变量,在C语言中有常称之为指针。

指针变量和普通变量共用数据类型,如:

int a = 0;//创建一个变量a,并把10赋值给a

int* a = &b;//创建一个指针变量(指针),把b的地址赋给a

//那么如何使用指针变量a呢,这个时候我们就需要使用间接访问操作符了(前面有介绍到)。

*a = 10;

//解引用a以访问b,并将b的值修改为10,

以上就是初识C语言的相关基础知识,后期会更新各种富有挑战的C语言文章,敬请期待~~

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值