1.C语言——基础知识

C语言基础知识

  • ==1.第一个C语言程序==
  • ==2.注释==
  • ==3.标识符==
  • ==4.关键字==
  • ==5.数据类型==
  • ==6.变量==
  • ==7.常量==
  • ==8.运算符==
  • ==9.输入输出==
      • 输入
      • 输出

1.第一个C语言程序

C语言的编程框架

#include <stdio.h>
int main()
{
    /* 我的第一个 C 程序 */
    printf("Hello, World! \n");
    return 0;
}

2.注释

单行注释:    //第一种写法      /* 单行注释 */
多行注释:
			/* 
			 多行注释
			 多行注释
			 多行注释
			 */

3.标识符

C 标识符是用来标识变量、函数,或任何其他用户自定义项目的名称
规定:C语言的的标识符由数字字母下划线构成,但不能以数字开头

可以作为标识符的
mohd ,  zara ,   abc ,  move_name ,  a_123
myname50 ,   _temp ,  j ,   a23b9 ,   retVal

不可以作为标识符的
12mb ,  23_m

4.关键字

具有特殊含义的标识符,C语言已经使用的了,用户自定义标识符时不能再使用。 后续的学习都会慢慢接触这些,现在只需要眼熟即可。

在这里插入图片描述

5.数据类型

数据类型就像一个盒子一样,盒子中存放数据,不同的数据要用不同的盒子装。
为了限制变量中所存储的数据(至少是可以兼容的)。
为了限制变量所占空间

在这里插入图片描述
先学习基本数据类型,其他的数据类型后续学习
char //字符数据类型
short //短整型
int //整形
long //长整型
long long //更长的整形
float //单精度浮点数
double //双精度浮点数

C语言本身并没有字符串类型,我们在C语言程序中使用的字符串实际上是字符数组,即多个字符构成的就是字符串!

  • 整型
    在这里插入图片描述
  • 浮点型
    在这里插入图片描述

为了得到某个类型或某个变量在特定平台上的准确大小,可以使用 sizeof 运算符。表达式 sizeof(type) 得到对象或类型的存储字节大小。

 #include<stdio.h>
 int main(){
	printf("int 存储大小 : %d \n", sizeof(int)) ;
	return 0;
 } 

数据类型的转换
类型转换是将一个数据类型的值转换为另一种数据类型的值。

  • 隐式类型转换:隐式类型转换是在表达式中自动发生的,无需进行任何明确的指令或函数调用。它通常是将一种较小的类型自动转换为较大的类型,例如,将int类型转换为long类型或float类型转换为double类型。隐式类型转换也可能会导致数据精度丢失或数据截断。

    	int i = 10;
    	float f = 3.14;
    	double d = i + f; // 隐式将int类型转换为double类型
    
  • 显式类型转换:显式类型转换需要使用强制类型转换运算符(type casting
    operator),它可以将一个数据类型的值强制转换为另一种数据类型的值。强制类型转换可以使程序员在必要时对数据类型进行更精确的控制,但也可能会导致数据丢失或截断。

       double d = 3.14159;
       int i = (int)d; // 显式将double类型转换为int类型
    

6.变量

生活中有些值是可变的(比如:年龄,体重,薪资),需要用变量来表示 数据类型决定了变量存储的大小和布局,该范围内的值都可以存储在内存中

变量两部步骤(定义,初始化)

1.定义: 数据类型 variable_list;

数据类型,可以是整型、浮点型、字符型、指针等,也可以是用户自定义的对象。
variable_list 可以由一个或多个变量的名称组成多个变量之间用逗号,分隔
举例:

int age;      //age 被定义为一个整型变量。
float salary; //salary 被定义为一个浮点型变量。
char grade;   //grade 被定义为一个字符型变量。
int *ptr;     //ptr 被定义为一个整型指针变量。
int  i, j, k; //声明并定义了变量 i、j 和 k

2.初始化(赋值)

int x;          // 整型变量x定义
x = 20;         // 变量x初始化为20
float pi;       // 浮点型变量pi定义
pi = 3.14159;   // 变量pi初始化为3.14159
char ch;        // 字符型变量ch定义
ch = 'B';       // 变量ch初始化为字符'B'

为了简化,可以定义的同时初始化

int x = 10;         // 整型变量 x 初始化为 10
float pi = 3.14;    // 浮点型变量 pi 初始化为 3.14
char ch = 'A';      // 字符型变量 ch 初始化为字符 'A'
extern int d = 3, f = 5;    // d 和 f 的声明与初始化
int d = 3, f = 5;           // 定义并初始化 d 和 f
byte z = 22;                // 定义并初始化 z

如果变量不初始化

整型变量(int、short、long等):默认值为0。
浮点型变量(float、double等):默认值为0.0。
字符型变量(char):默认值为’\0’,即空字符。
指针变量:默认值为NULL,表示指针不指向任何有效的内存地址。

7.常量

常量是固定值,在程序执行期间不会改变。这些固定的值,又叫做字面量。

  1. 整数常量
    前缀:整数常量可以是十进制、八进制或十六进制的常量。前缀指定基数:0x 或 0X 表示十六进制0 表示八进制不带前缀则默认表示十进制

    后缀:后缀是 U 和 L 的组合,U 表示无符号整数(unsigned)L 表示长整数(long)。后缀可以是大写,也可以是小写,U 和 L 的顺序任意。

    212         /* 合法的 */
    215u        /* 合法的 */
    0xFeeL      /* 合法的 */   十六进制数 FEE
    078         /* 非法的:8 不是八进制的数字 */
    032UU       /* 非法的:不能重复后缀 */
    ==============================================
    85         /* 十进制 */
    0213       /* 八进制 */
    0x4b       /* 十六进制 */
    30         /* 整数 */
    30u        /* 无符号整数 */
    30l        /* 长整数 */
    30ul       /* 无符号长整数 */
    
  2. 浮点常量
    浮点常量由整数部分小数点小数部分和指数部分组成

    当使用小数形式表示时,必须包含小数点
    例如 0.123、.123、123.、0.0等都是合法的实型常量。

    当使用指数形式表示时,字母e或E之前必须要有数字,且e或E后面的指数必须为整数
    例如 +1.2E+5,1.5e-9,-5.0e10等都是合法的实型常量。

    不带 f、F、l 或 L 后缀的浮点常量类型为 double。 如果后缀是字母 f 或 F,则常量的类型为 float。 如果后缀是字母 l 或 L,则常量的类型为 long double。

    10.0   /* Has type double       */
    10.0F  /* Has type float        */
    10.0L  /* Has type long double  */
    
  3. 整数常量
    字符常量是括在单引号中,例如,‘x’ 可以存储在 char 类型的简单变量中
    字符常量可以是一个普通的字符(例如 'x')一个转义序列(例如 '\t'),或一个通用的字符(例如 '\u02C0')

    在 C 中,有一些特定的字符,当它们前面有反斜杠时,它们就具有特殊的含义,被用来表示如换行符(\n)或制表符(\t)等。下表列出了一些这样的转义序列码:
    在这里插入图片描述
    字符常量的 ASCII 值可以通过强制类型转换转换为整数值。

    char myChar = 'a';
    int myAsciiValue = (int) myChar; // 将 myChar 转换为 ASCII 值 97
    

常量的定义
在 C 中,有两种简单的定义常量的方式:

  1. 使用 #define 预处理器: #define 可以在程序中定义一个常量,它在编译时会被替换为其对应的值。

  2. 使用 const 关键字:const 关键字用于声明一个只读变量,即该变量的值不能在程序运行时修改。

#define 预处理器

#define 常量名 常量值

#define PI 3.14159

在程序中使用该常量时,编译器会将所有的 PI 替换为 3.14159

#include <stdio.h>
 
#define LENGTH 10   
#define WIDTH  5
#define NEWLINE '\n'
 
int main()
{
 
   int area;  
  
   area = LENGTH * WIDTH;
   printf("value of area : %d", area);
   printf("%c", NEWLINE);
 
   return 0;
}

const 关键字

const 数据类型 常量名 = 常量值;

const int MAX_VALUE = 100;

在程序中使用该常量时,其值将始终为100,并且不能被修改。
在这里插入图片描述
在这里插入图片描述

#include <stdio.h>
 
int main()
{
   const int  LENGTH = 10;
   const int  WIDTH  = 5;
   const char NEWLINE = '\n';
   int area;  
   
   area = LENGTH * WIDTH;
   printf("value of area : %d", area);
   printf("%c", NEWLINE);
 
   return 0;
}

#define 与 const 区别(了解即可)
#define 与 const 这两种方式都可以用来定义常量,选择哪种方式取决于具体的需求和编程习惯。通常情况下,建议使用 const 关键字来定义常量,因为它具有类型检查和作用域的优势,而 #define 仅进行简单的文本替换,可能会导致一些意外的问题。

#define 预处理指令和 const 关键字在定义常量时有一些区别:

替换机制:#define 是进行简单的文本替换,而 const 是声明一个具有类型的常量。#define 定义的常量在编译时会被直接替换为其对应的值,而 const 定义的常量在程序运行时会分配内存,并且具有类型信息。

类型检查:#define 不进行类型检查,因为它只是进行简单的文本替换。而 const 定义的常量具有类型信息,编译器可以对其进行类型检查。这可以帮助捕获一些潜在的类型错误。

作用域:#define 定义的常量没有作用域限制,它在定义之后的整个代码中都有效。而 const 定义的常量具有块级作用域,只在其定义所在的作用域内有效。

调试和符号表:使用 #define 定义的常量在符号表中不会有相应的条目,因为它只是进行文本替换。而使用 const 定义的常量会在符号表中有相应的条目,有助于调试和可读性。

8.运算符

在这里插入图片描述

9.输入输出

输入

1.输入:scanf()

格式:scanf(控制串,&var1,&var2,…);

其中控制串由三部分组成:

  • 格式说明符:前缀为%,用于告诉方法下次要读入何种数据类型的数据,并顺次放到方法后的变量中.
  • 空白符:由空格(" ")、制表符("\t")和新行符("\n")表示,让方法在输入流中忽略一个或多个空白符(只要存在一个就可以忽略多个)。控制串中的空白符使 scanf() 在输入流中读,但不保存结果,直到发现非空白字符为止。
  • 非空白符:除去格式说明符和空白符以外的其他字符,如逗号,分号,于空白符相同,scanf()在输入流中读,但不保存结果。

如果格式符之间添加了空格,那么按照规则,会忽略掉全部的空白符直到遇到下一个不是空白符的字符

格式说明符意义
%d输入有符号的十进制数
%u输入无符号的十进制数
%o输入无符号的八进制数
%x/X输入无符号的十六进制数
%i输入八进制,十进制,十六进制数 (更通用)
%c输入单个字符
%s输入字符串,将字符串送到一个字符组中,在输入时以非空白字符开始以第一个空白字符结束
%f输入实数,可以用小数形式或指数形式输入
%e,E,g,G与f作用相同,e与f,g可以相互替换

附加格式符(也称修饰符)

字符说明
h输入短整型数据(可用到%hd,%ho,%hx)
l输入长整型数据(可用到%ld,%1o,%lx.%lu)以及double型数据%lf,%le)
域宽指定输入数据所占的宽度(列数),域宽应为正整数
*本输入项在读入后不赋给相应的变量

举例
读入整数

读入一个整数:
int a;
scanf("%d",&a);

读入多个整数  输入12 1 3
int a,b,c;
scanf("%d %d %d,&a,&b,&c);

读入以逗号分隔的多个整数:  输入1,2,3
int a,b,c;
scanf("%d,%d,%d",&a,&b,&c);

总之一句话,按照格式输入进行读取整数

读入其他类型的数字
参考读入整数,其他类型的数字使用方式相同,要注意的是
为了读取长整数,可以将 l 放在格式说明符的前面(如%ld,%lu);
为了读取短整数,可以将 h 放在格式说明符的前面(如%hd),
如果要强调。这些修饰符可以与 d、i、o、u 和 x 格式代码一起使用。

读入单个字符
在用%c格式声明输入字符时,空格“转义字符”中的字符都会作为有效字符输入!所以如果要连续赋给变量

scanf(”%c%c%c",&a,&b,&c),此时应该连续输入abc,而不是a b c。

int i;
char k;
scanf("%d %c",&i,&k);
/**
* 这个时候输入"1\na"和"1a"的效果是一样的,因为无论怎么换行,都属于空白符,会被忽略
*/
scanf("%d%c",&i,&k);
/**
* 这个时候输入"1\na",运行后k会接收到换行符,而不是"a",因为空白符没有被忽略,而%c对所有字符一视同仁。
*/

读入字符串
始终要注意的是读入字符串是scanf()方法的功能,而该方法是属于c的,因此它不支持c++新增的string类型

char str[80];
scanf("%s",str);//注意这里不需要&,因为str是数组,传入的已经是指针了

要注意%s虽然是读入字符串,但它也会忽略空白符,下面例子中的两行scanf()方法是等价的,因为%s本身就有忽略空白符的功能。

char stra[80];
char strb[80];
scanf("%s %s",stra,strb);
scanf("%s%s",stra,strb);
以非空白字符开始,以第一个空白字符结束为第一个字符串

虽然会忽略空白符,但是会主动的在最后一个字符后添加"\0"表示字符串结束(也因此,char数组不需要初始化就可以接受字符串,一般情况下不影响操作),因此在设置char数组长度时候,最好要比理论中的最大长度多预留一个长度

char str[5];//如果题目接受的最大字符串长度是4,那么设置的数组长度最好大于等于5
scanf("%s",str);

要注意的是,方法对空白符的忽略不是抛弃了空白符,如果没有继续读下去的话,接受字符串后的空白符是会保留在缓冲区的,这个时候使用%c接收是可以接收到,这个可能困扰了很多人,一定要注意。

char k;
char str[10];
scanf("%s%c",str,&k);
/**
* 如果输入"abcd",那么会直接运行结束,str="abcd",k='\n'
*/

2.输入:getchar()
字面意思,接收单个字符,使用方法

char a;
a = getchar();

实际上效果等同于

char a;
scanf("%c",&a);

3.输入:gets()
字面意思,读取多个字符,实际上是读取一整行,使用方法

char str[80];
gets(str);

由于gets()不检查字符串string的大小,必须遇到换行符或文件结尾才会结束输入,因此容易造成缓存溢出的安全性问题,导致程序崩溃,可以使用fgets()代替。

区别:
scanf() 读取字符串时以空格为分隔,遇到空格就认为当前字符串结束了,所以无法读取含有空格的字符串。
gets() 认为空格也是字符串的一部分,只有遇到回车键时才认为字符串输入结束,所以,不管输入了多少个空格,只要不按下回车键,对 gets() 来说就是一个完整的字符串。
也就是说,gets() 能读取含有空格的字符串,而 scanf() 不能。

4.输入:fgets()
是对gets()方法的扩展,gets()是从标准输入流中读取,而fgets()是从文件输入流中读取,但是文件输入流并不局限于普通的文件,只要是流都可以用来输入,使用方法:

char str[80];
fgets(str,79,stdin);

fgets()函数的作用可以这么解释:从第三个参数指定的流中读取最多第二个参数大小的字符到第一个参数指定的容器地址中。在这个过程中,在还没读取够第二个参数指定大小的字符前,读取到换行符’\n’或者需要读取的流中已经没有数据了。则提前结束,并把已经读取到的字符存储进第一个参数指定的容器地址中。

注意事项
1.fgets()函数的注意事项1
fgets()函数的最大读取大小是其“第二个参数减1”,这是由于字符串是以’\0’为结束符的,fgets()为了保证输入内容的字符串格式,当输入的数据大小超过了第二个参数指定的大小的时候,fgets()会仅仅读取前面的“第二个参数减1”个字符,而预留1个字符的空间来存储字符串结束符’\0’
2.fgets()函数的注意事项2
在fgets()函数的眼里,换行符’\n’也是它要读取的一个普通字符而已。在读取键盘输入的时候会把最后输入的回车符也存进数组里面,即会把’\n’也存进数组里面,而又由于字符串本身会是以’\0’结尾的。所以在输入字符个数没有超过第二个参数指定大小之前,你输入n个字符按下回车输入,fgets()存储进第一个参数指定内存地址的是n+2个字节。最后面会多出一个’\n’和一个’\0’,而且’\n’是在’\0’的前面一个(\n\0)。

输出

1.输出:printf()

printf函数一般格式:printf(格式控制,输出列表)
1)格式控制:格式声明:由“%"和格式字符组成,如%d,%f

(1)格式控制:格式声明:由“%"和格式字符组成,如%d,%f
               普通字符:需要在输出时原样输出的字符。
(2)输出列表:是程序需要输出的一些数据,可以是常量,变量或表达式。

格式字符
在这里插入图片描述
格式附加字符
在这里插入图片描述
*号的用法

*在printf里可以代表一个泛整数,可以代表任何整数。它可以出现在位宽的位置,也可以出现在小数位数的位置。但在printf的双引号外面,必须要有*对应的数值

比如我的位宽不确定,想用整数a表示,则可以写成:
在这里插入图片描述

2.输出:putchar()
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/335360.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C#使用Graphics绘图通过加载纹理底图的方式绘制纹理效果

纹理图片 加载效果如下图&#xff1a; 在扇形上把纹理图片作为底&#xff0c;渲染到绘制的图像中。 图形渲染中&#xff0c;纹理可以包括各种图像&#xff0c;如照片、图标、图案等。这些图像被映射到三维模型的表面&#xff0c;使得表面看起来像是被这些图像所包裹。 主要特点…

基于SSM的图书馆管理系统(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的图书馆管理系统&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spring Sp…

AIGC - 视频生成模型的相关算法进展

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/135688206 视频生成技术确实是一个很有潜力的颠覆性技术领域&#xff0c;可以作为企业创新梯队的重点关注方向&#xff0c;最近发展很快&#xff…

Docker--harbor

目录 一、搭建本地私有仓库 Docker容器的重启策略如下&#xff1a; 二、Harbor 简介 2.1Harbor是什么 2.2Harbor的特性 2.3Harbor的构成 2.4架构的数据流向 三、harbor部署以及配置文件 环境准备 部署Docker-Compose服务 下载或上传Docker-Compose&#xff1a; 赋予…

验证回文串[简单]

优质博文&#xff1a;IT-BLO-CN 一、题目 如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后&#xff0c;短语正着读和反着读都一样。则可以认为该短语是一个回文串。 字母和数字都属于字母数字字符。 给你一个字符串s&#xff0c;如果它是回文串&#xff…

MySQL---视图索引

表定义&#xff1a; 学生表&#xff1a;Student (Sno, Sname, Ssex , Sage, Sdept) 学号&#xff0c;姓名&#xff0c;性别&#xff0c;年龄&#xff0c;所在系 Sno为主键 课程表&#xff1a;Course (Cno, Cname,) 课程号&#xff0c;课程名 Cno为主键 学生选课表&#xff1a;S…

【JavaEE】文件操作 —— IO

文件操作 —— IO 1. 文件的属性 文件内容文件大小文件路径文件名称 2. 文件的管理 采用树形结构进行管理。 3. 文件路径 分为两种&#xff1a;相对、绝对路径。 相对路径&#xff1a;相对于当前位置的路径&#xff0c;以“./xxx.xxx”为标志绝对路径&#xff1a;以从盘符…

MySQL作业

目录 1.实验需求1&#xff1a; &#xff08;1&#xff09; &#xff08;2&#xff09; &#xff08;3&#xff09; &#xff08;4&#xff09; &#xff08;5&#xff09; 2.实验步骤1&#xff1a; &#xff08;1&#xff09;完成上述实验需求1&#xff0c;需要先创建一…

DAY13--learning English

一、积累 1.jog Riding rollercoaster is even like a daily jog for this man, 对这个男人来说坐过山车甚至就像每天散步一样轻松. 2.admission Admission to guilt. 承认有罪 3.summon I love the guy hes literally summon Karpov into material plane. 我喜欢这家伙他真…

牛牛的猜球游戏

置换群 前缀和 思想 学好线性代数 做这题很有意思&#xff0c;记得多校也有一道置换群的好题&#xff5e; 把多次变换看成一个置换矩阵就好也就是 I (一开始为单位矩阵) ->经过A作用产生了B->经过C作用产生了D 即 CAI D 现在让我们求一下 CI &#xff1f; 两边右…

C++浮点数比较

根据资料&#xff0c;C浮点数计算时存在精度误差&#xff0c;在一些情况下比较浮点数可能应使用特定的比较函数&#xff1b; #include "stdafx.h" #include<iostream>using namespace std;#define EPS 1e-9int main(int argc, char* argv[]) {double a 0.3;do…

利用appium自动控制移动设备并提取数据

安装appium-python-client模块并启动已安装好的环境 安装appium-python-client模块 在window的虚拟环境下执行pip install appium-python-client 启动夜神模拟器&#xff0c;进入夜神模拟器所在的安装路径的bin目录下&#xff0c;进入cmd终端&#xff0c;使用adb命令建立adb…

Klocwork—符合功能安全要求的自动化静态测试工具

产品概述 Klocwork是Perforce公司产品&#xff0c;主要用于C、C、C#、Java、 python和Kotlin代码的自动化静态分析工作&#xff0c;可以提供编码规则检查、代码质量度量、测试结果管理等功能。Klocwork可以扩展到大多数规模的项目&#xff0c;与大型复杂环境、各种开发工具集成…

在k8s上部署ClickHouse

概述 clickhouse的容器化部署&#xff0c;已经有非常成熟的生态了。在一些互联网大厂也已经得到了大规模的应用。 clickhouse作为一款数据库&#xff0c;其容器化的主要难点在于它是有状态的服务&#xff0c;因此&#xff0c;我们需要配置PVC。 目前业界比较流行的部署方式有…

使用pyechart创建基础柱状图

from pyecharts.charts import Bar# 构建柱状图对象 bar Bar()# 添加X轴数据 bar.add_xaxis(["中国","美国","英国"])# 添加Y轴数据 bar.add_yaxis("GDP",[30,20,10])# 绘图 bar.render("基础柱状图.html")效果演示&#x…

Git学习笔记(第6章):GitHub操作(远程库操作)

目录 6.1 远程库操作 6.1.1 创建远程库 6.1.2 命名远程库 6.1.3 本地库推送到远程库(push) 6.1.4 远程库拉取到本地库(pull) 6.1.5 远程库克隆到本地库(clone) 6.2 团队内协作 6.3 跨团队协作 6.4 SSH免密登录 6.1 远程库操作 命令 作用 git remote -v 查看所有远程…

C语言·预处理详解

1. 预定义符号 C语言设置了一些预定义符号&#xff0c;可以直接使用&#xff0c;预定义符号也是在预处理期间处理的 __FILE__ 进行编译的源文件 __LINE__ 文件当前的行号 __DATE__ 文件被编译的日期 __TIME__ 文件被编译的时间 __STDC__ 如果编译器遵循ANSI C&#xff0c;…

正则表达式..

1.字符串的合法检验 现在有一个字符串验证码 我们需要检验其的合法性 什么条件才能够使得字符串合法呢&#xff1f;就是6-10个字符串长度 并且以字母开头 并且其中由字母、数字、下划线构成 那么我们可以先通过自定义的方式进行检验 public class Main {public static void m…

CodeWave智能开发平台--03--目标:应用创建--10初级采购管理系统总结

摘要 本文是网易数帆CodeWave智能开发平台系列的第14篇&#xff0c;主要介绍了基于CodeWave平台文档的新手入门进行学习&#xff0c;实现一个完整的应用&#xff0c;本文主要完成10初级采购管理系统总结 CodeWave智能开发平台的14次接触 CodeWave参考资源 网易数帆CodeWave…

day3:基于UDP模型的简单文件下载

思维导图 tftp文件下载客户端实现 #include <head.h> #define SER_PORT 69 #define SER_IP "192.168.125.223" int link_file() {int sfdsocket(AF_INET,SOCK_DGRAM,0);if(sfd-1){perror("socket error");return -1;}return sfd; } int filedownloa…
最新文章