C语言内容

本文详细介绍了C语言中的数据类型,包括整型、浮点型、字符型,以及运算符和表达式,如赋值、算术、逻辑等运算符,同时讲解了条件运算符、逗号运算符等。接着阐述了语句的种类,如表达式语句、函数调用语句、控制语句等。还详细讨论了循环结构,包括for、while、do-while循环,并对比了不同循环的特点。此外,还涵盖了分支结构(if-else、switch-case)和跳转语句(return、goto、break、continue)。最后提到了C语言中的函数、数组、结构体、联合体和指针的基本概念及应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一,数据类型

1、整(数)型

int:基本整数型,用于存储整数,占4个字节;默认值为0,数据范围是-2147483648~2147483647。

short:短整型,占2个字节,存储方式与基本整形int相同,数据范围是-32768-32767。

long:长整型,占4个字节,数据范围是-263~263-1。

long long:双长整型,占8个字节,数据范围是-263~263-1;这种数据类型一般比较少用。

2、浮点型

float:单精度浮点型,占4个字节,有效数字为(6~7位),数据范围是-3.4*1038~+3.4*1038。

float型变量是由有限的存储单元组成 ,因此,只能提供有限的有效数字,在有效位以外的数字将不精确,这样,可能会产生一些误差。

double:双精度浮点型,占8个字节,有效数字为(1516位),数据范围是-1.7*10^-3081.7*10^308。

3、字符型

char:字符型,用于存储单个字符,占1个字节。

4、下面用图片来准确的理解一下数据类型在这里插入图片描述

在这里插入图片描述

二,运算符,表达式和语句

运算符

1.赋值运算符:赋值运算符的作用是把某个常量或变量或者表达式的值赋值给另一个变量。符号为“=”。(注意:这里并不是等于的意思,等于用“==”表示,常数只能作为“=”的右值。)

2.算数运算符:在C语言中有两个单目和五个双目运算符。“+单目正”,“-单目减”,“*乘法”,“/除法”,“%取模”,“+加法”,“-减法”。

3.逻辑运算符:“&&逻辑与”,“||逻辑或”,“!逻辑非”。当表达式进行&&运算时,只要有一个为假,总的表达式就为假,只有当所有都为真时,总的式子才为真。当表达式进行||运算时,只要有一个为真,总的值就为真,只有当所有的都为假时,总的式子才为假。逻辑非(!)运算是把相应的变量数据转换为相应的真/假值。若原先为假,则逻辑非以后为真,若原先为真,则逻辑非以后为假。

4.关系运算符:“>大于”,“<小于”,“>=大于等于”,“<=小于等于”,“=等于”,“!=不等于”。

5.自增自减运算符:自增运算符++,自减运算符–。运算符在前面还是在后面对本身的影响都是一样的,都是加1或者减1,但是当把他们作为其他表达式的一部分,两者就有区别了。运算符放在变量前面,那么在运算之前,变量先完成自增或自减运算;如果运算符放在后面,那么自增自减运算是在变量参加表达式的运算后再运算。

6.复合赋值运算符:“+= 加法赋值”,“-= 减法赋值”,"*= 乘法赋值","/= 除法赋值","%= 模运算赋值","<<= 左移赋值",">>= 右移赋值","&= 位逻辑与赋值","|= 位逻辑或赋值","^= 位逻辑异或赋值"。

7.条件运算符:“<表达式1>?<表达式2>:<表达式3>”。在运算中,首先对第一个表达式进行检验,如果为真,则返回表达式2的值;如果为假,则返回表达式3的值。

8.逗号运算符:多个表达式可以用逗号分开,其中用逗号分开的表达式的值分别结算,但整个表达式的值是最后一个表达式的值。

表达式

1.算术表达式:由数字和运算符号组成的式子。

2、关系表达式:关系表达式的值是逻辑值“真”或“假”。但是C语言没有逻辑型变量和逻辑型常量,也没有专门的逻辑值,故以“非0”代表“真”,以“0”代表“假”。在关系表达式求解时,以“1”代表“真”,以“0”代表假。当关系表达式成立时,表达式的值为1,否则表达式的值为0。

3、条件表达式:由条件运算符构成,并常用条件表达式构成一个赋值语句,其一般形式如下:x=<表达式1>?<表达式2>:<表达式3>其意义是:先求解表达式1,若为非0(真),则求解表达式2,将表达式2的值赋给x。若为0(假),则求解表达式3,将表达式3的值赋给x。

4、逻辑表达式:指运算符为或||、与&&、非!的表达式。返回值为0或1,0表示false,非0表示true. 例如!0返回1,0&&1返回0,0||1返回1。

5、赋值表达式:运算符号的优先级别;强制类型转换的使用。

运算符与表达式一般是联合起来使用,一般不会单独使用。

语句
1.表达式语句:表达式+分号。
2.函数调用语句:函数名+实际参数+分号
3.控制语句:1.条件控制语句,2.循环语句
4.复合语句:多个语句yong{}括起来,组成复合语句,其中每条语句都以;结束,但}外不能加分号。
5.空语句:只有分号(;)的语句。由一个分号组成,它表示什么操作也不做,但从语法上讲,它的确是一条语句。

三.循环
循环条件决定了在语句中循环体被重复执行的次数,称为控制表达式。这个表达式是标量类型,即属于算数表达式或指针表达式。在控制表达式不等于0的情况下,循环条件为true,反之则为false。

  1. for循环:for (<初始化>;<条件表现式>;<增量>)初始化总是一种赋值语句,用于将初始值分配到循环控制变量;一个条件表达式是一种确定何时退出循环的关系表达式;递增定义了循环控制变量在每次循环之后的变化。三.部件之间使用;分开使用。比如:for(i=1;i<=10;i++)。
  2. while循环:
    while (条件)while循环指出当条件为 true时将执行语句。直至条件失效只是结束循环。然后继续循环程序之外的后续语句。
    比如:
    char c;
    c="\0";/初始化 c
    while (c!="\n’)
    已车结束循环*/
    c= getcheQ;
    /带回显的从键盘接收字符*/
  3. do–while循环:
    do
    {
    报表模块;
    }
    while (条件);
    此循环不同于 while循环:它首先在循环中执行语句这样,就可以判断该条件是否为真,如果为真则继续循环;时,结束循环。所以,do-while循环至少要执行一个-次要循环语句。

与此类似,当有多个语句参与循环时,要将它们括起来。

四.分支和跳转

C语言中的分支结构有三种:
1.单分支结构:
if(<条件表达式>)
{
(语句块)
}
2.双分支结构:
if(<条件表达式>)
{
语句1;
}
else
{
语句2;
}
3.多分支结构:
(1):
if(<条件表达式>)
{
if(<条件表达式>)
{
语句1;
}
else
{
语句2;
}
}
else
{
if(<条件表达式>)
{
语句3;
}
else
{
语句4;
}
}
(2)switch语句:
switch(表达式)
{
case 常量1:语句1;break;
case 常量2:语句2;break;
case 常量3:语句3;break;

case 常量n:语句n;break;
default:语句n+1;
}
这几种结构的区别:
1、单分支结构在满足条件时执行,不满足条件不执行。

2、在双分支结构中,如果条件表达式成立,则执行语句块1,否则,执行语句块2,所以双分支结构至少执行一次。

3、多分支结构的分支结构的嵌套中,分支结构的嵌套包含了单分支结构与双分支结构的特性,可以用单分支结构嵌套双分支结构,也可用双分支结构嵌套单分支结构,通俗的来讲就是分支结构中放入一个分支结构,当条件成立则执行分支结构中嵌套的分支结构。

4、switch语句可以理解成其他的分支结构的总和,switch集成了上述所有分支结构的特性,在有多种情况的时候才使用switch,当switch(条件)满足case 后面的常量,则执行对应的语句,若满足的条件未能匹配到对应的常量,则执行default后的语句,有default的switch语句是至少执行一次的,当然default也可省略不写,这样switch语句也可以一次都不执行。

跳转语句:
1.return语句:return 语句会中止执行当前函数,跳转回到调用该函数的位置:return [表达式];这里的表达式会被计算,且结果会被传送给函数调用者,当作被调用函数的返回值。如有必要,返回值会被转换到被调用函数返回值类型。

2.goto语句:goto 语句会造成无条件跳转,它跳转到同一个函数中的另一条语句。跳转的目的地使用标签名称来指定标签有自己的命名空间。也就是说,标签可以使用与变量或类型一样的名称,而不会发生冲突。标签可以被放在任何语句的前面,并且一条语句也可以有多个标签。

3.break语句:break语句只能用于循环体内或switch语句内,并且会使程序跳到该循环或该switch语句的后面的第一条语句。因此,无论在循环体内的什么位置,break语句都可以造成循环的结束。

4.continue语句:continue语句只能使用在循环体内,并且会造成程序跳过当前循环中尚未执行的代码。在 while 或 do … while 循环中,当遇到 continue 语句时,程序会跳转到循环的控制表达式,并进下一次的循环条件计算。在
for 循环中,程序会跳转到循环头部的第三个表达式,并进行下一次的循环条件计算。

五.函数
修行 2022/4/15 19:56:03
C语言标准库包含了几百个函数,我们收集了一部分常用的函数及其声明:

2、printf格式输出函数

3、systemdos命令函数

4、sort排序

5、main主函数

6、fgets文件读取字符串函数

7、fputs文件写入字符串函数

8、fscanf文件格式读取函数

9、fprintf文件格式写入函数

10、fopen打开文件函数

11、getchar输入字符函数

12、putchar输出字符函数

13、malloc动态申请内存函数

14、free释放内存函数

15、abs求绝对值数学函数

16、sqrt求平方根数学函数
1.函数只能定义在函数外,不能定义在函数内。
2.函数不允许重名,C语言中函数没有重载。
3.函数只要一经定义,就可以在任意函数中调用。
注意:如果函数定义在它调用之后,那么必须在调用之前,先声明这个函数。

六.数组
1、一维数组,声明时数组名称前面的类型是数组元素的类型。
例:inta[4];这表明一个整型数组的长度是4,每个元素都是一个整型数组。
分组的赋值方法如下:

1 数组类型 数组名 [自定义数组的长度] 数组名[下标]=值

2 int 数组名[数组的长度]={数组的第一个元素,数组的第二个元素,… ,数组的第N个元素}

注:若数组中的某一元素没有赋值,则默认值为0。 我们通常通过for循环给数组赋值。

2、二维数组,可以作为种表格,它有行有列。

例: 数组类型 数组名[数组中一维数组的长度][数组中二维数组的长度]

二维数组的赋值:

1.数组类型 数组名[一维数组的长度][二维数组的长度]; 数组名[一维数组某个元素的下标][二维数组某个元素的下标]=值;

3、字符数组,c语言中没有字符串的概念只有单个字符,所以称一串字符串为字符数组。

字符数组的定义是这样的:

1.char 字符串名 [字符串长度]=“字符串”

注意:另外在c语言的字符串中要以\0去进行结尾否则这个字符数组是没有结尾的。

数组有一下几个特点:

  1. :数组可以看做是一个变量的集合,在这个集合中,所有变量的数据类型都是相同的。

  2. :每个数组元素的作用相当于简单的变量。

  3. :同一数组中的数组元素在内存中占据的地址空间是连续的。

  4. :数组的大小(数组元素的个数)必须在定义时确定,在程序中不可改变。

  5. :数组名代表的是数组在内存中的首地址。

七.结构体,联合体
1.结构体:
1.在C语言中,可以使用结构体(Struct)来存放一组不同类型的数据。结构体的定义形式为:struct 结构体名{ 结构体所包含的变量或数组};

2.结构体是一种集合,它里面包含了多个变量或数组,它们的类型可以相同,也可以不同,每个这样的变量或数组都称为结构体的成员。

3.结构体也是一种数据类型,它由程序员自己定义,可以包含多个其他类型的数据:像 int、float、char 等是由C语言本身提供的数据类型,不能再进行分拆,我们称之为基本数据类型;而结构体可以包含多个基本类型的数据,也可以包含其他的结构体,我们将它称为复杂数据类型或构造数据类型。

4.结构体变量:既然结构体是一种数据类型,那么就可以用它来定义变量。例如:struct stu stu1, stu2;定义了两个变量 stu1 和 stu2,它们都是 stu 类型,都由 5 个成员组成。

5.结构体和数组类似,也是一组数据的集合,整体使用没有太大的意义。数组使用下标[ ]获取单个元素,结构体使用点号.获取单个成员。

6.注意:结构体是一种自定义的数据类型,是创建变量的模板,不占用内存空间;结构体变量才包含了实实在在的数据,需要内存空间来存储。

2.联合体:
1.像结构体一样,联合体(Union)在C语言中是一个用户定义的数据类型,用于保存不同类型的元素,但它并不占所有成员的内存总和。它只占最大成员的内存,它分享最大成员的内存。

2.联合体完全就是共用一个内存首地址,并且各种变量名都可以同时使用,操作也是共同生效。如此多的访问内存手段,确实好用,不过这些“手段”之间却没法互相屏蔽——就好像数组+下标和指针+偏移一样。

3.由于联合体中的所有成员是共享一段内存的,因此每个成员的存放首地址相对于于联合体变量的基地址的偏移量为0,即所有成员的首地址都是一样的。为了使得所有成员能够共享一段内存,因此该空间必须足够容纳这些成员中最宽的成员。对于这句“对齐方式要适合其中所有的成员”是指其必须符合所有成员的自身对齐方式。

4.联合体优点:
它占用较少的内存,因为它只占最大的成员的内存量。

5.联合体缺点:
它将数据存储在一个成员中。

八.指针
1.联合体完全就是共用一个内存首地址,并且各种变量名都可以同时使用,操作也是共同生效。如此多的访问内存手段,确实好用,不过这些“手段”之间却没法互相屏蔽——就好像数组+下标和指针+偏移一样。

2.由于联合体中的所有成员是共享一段内存的,因此每个成员的存放首地址相对于于联合体变量的基地址的偏移量为0,即所有成员的首地址都是一样的。为了使得所有成员能够共享一段内存,因此该空间必须足够容纳这些成员中最宽的成员。对于这句“对齐方式要适合其中所有的成员”是指其必须符合所有成员的自身对齐方式。

3.常见指针变量的定义:
int *p; p 可以指向 int 类的数据,也可以指向类似 int arr[n] 的数组。
int **p; p 为二级指针,指向 int * 类型的数据。
int *p[n]; p 为指针数组。[ ] 的优先级高于 *,所以应该理解为 int *(p[n]);
int (*p)[n]; p 为二维数组指针。
int *p(); p 是一个函数,它的返回值类型为 int *。
int (*p)(); p 是一个函数指针,指向原型为 int func() 的函数。

4.相关注意和说明:
(1) 指针变量可以进行加减运算,例如p++、p+i、p-=i。指针变量的加减运算并不是简单的加上或减去一个整数,而是跟指针指向的数据类型有关。

  1. 给指针变量赋值时,要将一份数据的地址赋给它,不能直接赋给一个整数,例如int *p = 1000;是没有意义的,使用过程中一般会导致程序崩溃。

  2. 使用指针变量之前一定要初始化,否则就不能确定指针指向哪里,如果它指向的内存没有使用权限,程序就崩溃了。对于暂时没有指向的指针,建议赋值NULL。

  3. 两个指针变量可以相减。如果两个指针变量指向同一个数组中的某个元素,那么相减的结果就是两个指针之间相差的元素个数。

  4. 数组也是有类型的,数组名的本意是表示一组类型相同的数据。在定义数组时,或者和 sizeof、& 运算符一起使用时数组名才表示整个数组,表达式中的数组名会被转换为一个指向数组的指针。

在这里插入图片描述

6.总结:指针是C 语言的灵魂。

九.宏定义

1.在C语言源程序中,允许用一个标识符来表示一个字符串,称为宏,宏定义是由源程序中的宏定义命令完成的,宏替换是由预处理程序自动完成的。

2.宏定义是比较常用的预处理指令,即使用“标识符”来表示“替换列表”中的内容。标识符称为宏名,在预处理过程中,预处理器会把源程序中所有宏名,替换成宏定义中替换列表中的内容。

3.常见的宏定义有两种,不带参数的宏定义和带参数的宏定义,宏定义可以帮助我们防止出错,提高代码的可移植性和可读性等。

4.和使用函数相比,使用宏的不利之处在于每次使用宏时,一份宏定义代码的拷贝都会插入到程序中。除非宏非常短,否则使用宏会大幅度增加程序的长度。

5.函数调用时,先求出实参表达式的值,然后代入形参,而使用带参数的宏只是进行字符替换。函数调用是在程序运行时处理的,为形参分配临时的内存单元。而宏置换则是在预处理阶段进行的,在置换时并不分配内存单元,不进行值的传递处理,也没有“返回值”的概念。

6.对函数中的实参和形参都要定义类型,二者的类型要求一致,如不一致,应进行类型转换。而宏不存在类型问题,宏名无类型,它的参数也无类型,只是一个符号代表,置换时,代入指定的字符串即可。定义宏时,字符串可以是任何类型的数据。

7.定义宏时,字符串可以是任何类型的数据。调用函数只可得到一个返回值,而用宏可以设法得到几个结果。

8.使用宏次数多时,宏展开后源程序变长,因为每展开一次都使程序增长,而函数调用不会使源程序变长。宏替换不占运行时间,只占预处理时间。而函数调用则占运行时间(分配单元、保留现场、值传递、返回)。

9.一般用宏来代表简短的表达式比较合适。有些问题,用宏和函数都可以。
如果善于利用宏定义,可以实现程序的简化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值