Clion与C语言
- Clion快捷键Mac OS
- Ctrl+A
- Ctrl+E
- Ctrl+P
- Ctrl+n
- Ctrl+m
- Ctrl+D
- Ctrl+R
- *Ctrl+F
- *Ctrl+B
- Ctrl+G
- *Ctrl+K
- Ctrl+C
- C语言基础知识
- 数据表示
- 字符型常量
- 特殊的字符型常量
- 字符串常量
- 符号常量
- 变量
- 变量定义
- 变量赋值
- 逗号表达式
- 复合语句
- 格式输出函数
- 格式输入函数
- C语句
- break与continue语句
- 一维数组的初始化
- 在定义数组时给数组元素赋值
- 二维数组的初始化
- 字符数组的初始化
- 字符串与字符串结束标志
- 字符数组的引用与输入/输出
- 通过指针引用数组元素
- 地址表示法
- 数组元素的引用法
- 指针变量加下标
- 指针变量与数组名的引用区别
- ++和+i不等价
- 数组名作为函数参数
- 数组指针作为函数参数
- 结构体变量的定义
- 结构体变量的引用
- 结构体指针变量
- 结构体指针变量访问结构体变量成员
- 分配内存空间函数malloc
- 分配内存空间函数calloc
- 用typedef定义类型
- 为指针类型命名
- 文件
- 文件的分类
- 文件的编码形式
- 文件的读写方式
Clion快捷键Mac OS
Ctrl+A
回到本行行首
Ctrl+E
回到本行行尾
Ctrl+P
回到上一行末尾
Ctrl+n
回到下一行末尾
Ctrl+m
回到所在范围的括号前面,回到所在范围的括号后面
Ctrl+D
执行代码
Ctrl+R
执行代码
*Ctrl+F
下一个字符
*Ctrl+B
上一个字符
Ctrl+G
可以从当前位置开始查找同样字符
*Ctrl+K
从当前光标位置删除后面所有字符
Ctrl+C
复制光标所在单行内容
C语言基础知识
数据表示
字符型常量
字符常量是用单引号’‘括起来的一个字符,如’a’;
C语言中,字符是按照其字符所对应的ASCII码值来存储的,一个字符占一个字节,ASCII码值共有0~255个,256个值,注意空格也是一个字符.
举例:
char a = ' ';
printf("the space value is %d\n", a);
- 1
- 2
我们把空格字符‘ ’存在声明的变量a中,以整形格式输出,得到的输出结果是ASCII码值空格字符对应的数值32,二进制表示为:00100000,占一个字符长度.
特殊的字符型常量
C语言中有一类特殊的字符常量,他们表示控制字符或特殊符号,如回车换行退格等字符,他们无法在屏幕上显示,也无法从屏幕上键入,但是我们可以利用转义字符来表示这些控制,转义字符是用反斜杠""后跟一个字符表示,如常用的:\a,\b,\f,\n,\r,\t,\v,\,",’,?,\0;
控制字符有32个,从数值从000到031,null是000空字符,而032是空格字符space.所以我们在计算string长度的时候,空格字符的个数也算进去,并且字符串常量在内存中存储时,系统自动在字符串末尾加上了“串结束标志”,也就是ASCII码值为0的空字符null,用转义字符’\0’表示,所以我们主要清楚空字符和空格字符space的差别.
字符串常量
字符串常量是用双引号""括起来的若干字符,如字符串长度为1的空格字符“ ”,双引号中一个字符都没有的称为空串,长度为0.
字符串常量在内存中存储时,系统自动在字符串末尾加上了“串结束标志”,也就是ASCII码值为0的空字符null,用转义字符’\0’表示,但是输出时不输出’\0’,所以长度为n的字符串常量,在内存中占n+1个字节的存储空间.
对于有转义字符的字符串,应将转义字符计算为1个字符,只是因为它们不能显示,所以我们用反斜杠 ''加字符表示它们(但是若转义字符与转义字符表中不匹配则忽略),不参与长度计算.
例如 “AB\n” 这样一个字符串长度为3.
注意字符常量与字符串常量的区别,它们表示形式不同,而且存储性质也不相同,字符常量’S’占1个字节,但是字符串常量"S"占2个字节.
符号常量
在一个程序中以一个符号代表的常量称为符号常量,如PI代表3.14,它的好处是当我们程序需要这个符号的值时,只要修改一处即可.
C语言中用宏定义命令#define定义符号常量,就像用char定义字符常量一样的使用方法,只是标识符与符号常量之间没有赋值符号.
变量
变量即在程序运行过程中可以改变值的量,我们引用一个变量之前需要先定义它,确定它的变量名字和数据类型.我们脑海中必须要清晰的印象,当我们定义一个变量时,其实就是在内存中分配了这个数据类型所定义大小的一块空间,数据类型呢,可以决定变量的存储方式和所占用的内存大小.
变量定义
例如
数据类型 变量表列;
可以同时定义多个变量,用","分隔
char a;
- 1
我们就是定义了一个变量a,我们可以在程序任何地方使用a,称为对变量的引用,我们用的char数据类型,意思是我们在内存中分配了一块1字节大小的空间,并且把它的名字命名为a,这个名字就好像一间办公室上贴的牌子:主任办公室,&a是这块空间的地址,如主任办公室房号是408,也是计算机内部真实存在的数字,计算机通过这个地址可以直接定位这个空间.
变量赋值
1.定义同时赋值
同时定义了三个变量
int i = 1, j = 1, k = 1;
- 1
注意根据C语言语法
不能出现这种情况
int i = j = k = 1;
- 1
因为j和k还没有定义,不能引用它们
2.定义完赋值
int i, j, k;
i = 1; j = 1; k = 1;
- 1
- 2
注意这里有三个赋值语句,用分号分隔
3.使用输入函数从键盘读取值赋值
int i, j, k;
scanf("%d%d%d", &i, &j, &k);
- 1
- 2
这里我们通过输入函数,参数表里面第二个参数传入三个内存空间,从键盘获取三个字符,以ASCII码值格式输入并存入三个空间内.
这样就完成了变量的初始化.
逗号表达式
使用逗号运算符将多个表达式连接在一起,就组成了逗号表达式.C语言中分为赋值表达式语句和运算符表达式语句,都以分号结尾.
逗号第一种作用是分隔参数,第二种作用就是使用在逗号表达式里面.
复合语句
我们用{ }把多个语句括起来组成的一个语句称为复合语句.我们应该把它看成单条语句, } 外不加分号,通过这个我们可以把控制语句和结构体,联合体区分开来.
C语言没有指明语句书写格式,可以一行写多个语句,也可以一个语句分行写.
表列中变量用逗号分隔开.输出数据的个数必须与前面前面格式化字符串说明输出个数一样.
格式输出函数
printf("<格式控制>", <输出表列>);
功能,将输出表列的值按指定格式输出到标准输出终端上.
括弧( )内包含两部分
1.格式控制:双引号括起来的字符串,也叫“格式控制字符串”
a.格式说明,由“%”和格式字符组成,确定输出内容格式,总是以“%”号字符开始.
b.普通字符,这些字符按原样输出,主要用于输出提示信息,如文字和逗号空格.
c.转义字符,用于指明特定的操作,如"\n"换行, "\r"回车.
carriage return CR
line feed LF
在html中
…
中间是一段是硬回车,而
是软回车
软回车能使两行之间的行间距大幅度缩小.
%[标志][输出最小宽度][.精度][长度][类型]
类型
d:以十进制输出带符号整数(正数不输出正号+)
o:以八进制形式输出无符号整数(不输出前缀0)
x:以十六进制形式输出无符号整数(不输出前缀0x)
u:以十进制形式输出无符号整数
f:以小数形式输出单、双精度实数,隐含输出6位小数
e:以指数形式输出单、双精度实数,尾数部分小数位数6位
g:以%f或%e中较短的输出宽度输出单、双精度实数
c:输出单个字符
s:输出字符串
%:输出百分号%
格式输入函数
1.格式控制字符串中除了格式说明之外,还包括其他字符,则在输入数据时,这些普通字符要原样输入.
例如
scanf("%d,%d", &i, &j);
- 1
则当运行到这行时,我们输入数据时,也同样需要输入两个字符中间的“,”,不然会有意想不到的结果发生.
2.在使用%c格式时,输入的数据之间不需要分隔符标志;空格,回车符都将作为有效字符读入.
3.从终端输入数据时,遇到下述情况系统将认为该项数据结束
a.遇到空格,回车符或制表符,故可用它们作为数值数据间的分隔符
b.遇到宽度结束 如%4d
c.遇到非法输入
%*,表示跳过遇到的数据项不予读入.
C语句
C程序对数据的处理时通过“语句”的执行来实现的,语句是用来向计算机系统发出操作指令,一条语句经过编译后产生若干条机器指令.C语句是C源程序的重要组成部分,使用来完成一定操作任务的.
一个函数应该包括声明和实现两个部分,声明部分的内容 不产生机器操作,仅对变量进行定义,也就是说声明的时候并不会对内存进行分配,因此不能称作语句.比如int a;不是C语句,而sum = a + b;是C语句.
C语句可以分成一下五大类:
1.表达式语句
表达式;
功能:计算表达式的值或者改变变量的值.
a.赋值语句
x = 7;
b.运算符表达式语句
i++;
C语言中把赋值语句和赋值表达式区分开,不仅增加了表达式的应用,而且使其具备了其他语言中难以实现的功能.
2.控制语句
语句(条件语句)
语句(多分支选择语句)
语句(循环语句)
while语句(循环语句)
语句(循环语句)
语句(中止执行switch或循环语句)
语句(无条件转向语句)
语句(结束本次循环语句)
语句(从函数中返回语句)
3.函数调用语句(由一次函数调用加一个分号构成)
函数名(实际参数表);
4.空语句
在程序中空语句常用于空循环体或被转向点,他在语法上占有一个简单语句的位置,实际上执行该语句不执行任何操作.
5.复合语句
用{ }把多个语句括起来组成的一个语句称为复合语句,在程序中应把复合语句看成单条语句而不是多条语句.
Tip:1.复合语句内的各条语句都必须以分号“;”结尾,此外,在“}”外不能再加分号
2.在复合语句内定义的变量是局部变量,仅在复合语句中有效.
break与continue语句
break语句终止本层循环
continue语句终止这次循环
一维数组的初始化
可以用赋值语句或输入语句对数组元素赋值,还可以定义数组时给数组元素赋值.
在定义数组时给数组元素赋值
1.对全部数组元素赋初值
int c[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
- 1
将数组元素的初值依次放在花括号内,上述定义和初始化的结果为:
c[0] = 0, c[1] = 1, c[2] = 2, c[3] = 3, c[4] = 4, c[5] = 5, c[6] = 6, c[7] = 7, c[8] = 8, c[9] = 9;
2.部分元素初始化
int c[10] = {0, 1, 2, 3, 4, 5};
- 1
仅对前五个元素赋初值后,后五个元素未指定初值,自动取0
3.全部元素均初始化为0
根据第2条规则我们知道,仅对前面元素赋初值,后面元素自动取0,所以我们全部元素初始化为0可以这样写
int c[10] = {0};
- 1
4.在对全部元素赋初值时,可以不指定数组长度
int c[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
- 1
此时系统会自动将此数组长度定义为10
二维数组的初始化
1.分行赋初值
第一个花括号的数据赋予第一行,依次下去
int b[3][4] ={{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
- 1
2.全部数组元素赋值可以放在一个花括号中,未赋值的元素自动初始化为0,不建议用这种方法
3.部分元素赋初值,其他元素系统自动初始化为0
int b[3][4] = {{1}, {2}, {3}, {4}};
- 1
4.如果对全部元素赋初字,数据可以写在一个花括号内
可以不指明第一维长度,但是必须指明第二维长度,如:
int [][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
- 1
系统可以自动确认第一维长度为3
字符数组的初始化
1.对数组元素逐个赋初值
char b[] = {'I', ' ', 'a', 'm', ' ', 'h', 'a', 'p', 'p', 'y'};
- 1
如果初值个数多于数组长度,按语法错误处理
如果初值个数少于数组长度,未取到初值的数组元素自动为空字符’\0’
字符’\0’是C语言规定的“字符串结束标志”
有了字符数组结束标志,字符数组的长度就没那么重要了.在程序中往往依靠检测字符串结束标志’\0’来判断字符串是否结束,而不再依靠字符数组的长度了.
2.用字符串初始化
字符串在存储时,系统自动在其后面加上了字符串结束标志’\0’
char c[] = {“I am happy”};
或
char c[] = “I am happy”;
char c[11] = “I am happy”;
所以字符串初始化时,数组的长度可以忽略,花括号也可以忽略,但存储长度为“字符串中字符数组+1”.
字符串与字符串结束标志
C语言中,字符串常量用双引号括起来,没有字符串变量,而是作为字符串数组来处理,例如char c[14] = “I am happy”, 数组长度为14,字符串长度为10,为了测定字符串的实际长度,检测“字符串结束符’\0’作为标志”.
字符串结束标志’\0’的ASCII码值为0,是一个空操作符,什么也不显示,用它作为字符串的结束标志不会产生附加的操作或增加有效字符,只是一个标志.
但是字符数组并不要求它的最后一个字符为’\0’,甚至可以不包括’\0’
例如:
char c[] = {‘c’, ‘h’, ‘i’, ‘n’, ‘a’};
数组长度为5,包含5个字符
char c[] = “china”;
数组长度为6,包含5个字符以及一个字符串结束标志’\0’
是否需要加入’\0’,根据需要决定,由于系统对字符串常量自动加了结束的标志,为了处理的方便,必要时在初始化时加入一个’\0’,例如:
char c[] = {‘c’, ‘h’, ‘i’, ‘n’, ‘a’, ‘\0’};
字符数组的引用与输入/输出
可以采用"%s"将整个字符串输出,输出时遇到’\0’即停止输出
用“%s”输出时,输出项只能是数组名,不能是数组元素,数组名代表数组的首地址,输出时从首地址开始输出直到’\0’结束.
scanf函数中的输入项如果是数组名,则不加取地址符号“&”, 因为C语言中数组名代表数组的起始地址.
通过指针引用数组元素
已知数组的指针后,数组中各元素可以通过起始地址加相对值的方式获得,从而增加了访问数组的渠道.
C语言规定,如果指针变量p指向数组中一个元素时,p+1指向同一数组中的下一个元素,而不是简单地将p的值加1.
地址表示法
a[3]的地址有三种表示方法
p+3, a+3, &a[3]
数组元素的引用法
a[5]的访问有下列三种不同的表示形式.
*(p+5), *(a+5), a[5]
指针变量加下标
p[5]和*(p+5)等价
指针变量与数组名的引用区别
一个是常量,一个是变量,常量不可改变
++和+i不等价
我们用指针变量逐个访问数组时,有两种方式*(p++)和*(p+i),表面上两种方式没什么区别,但是p++不必每次重新计算地址,这种自增操作比较快,能大大提高执行效率.
综上,引用数组元素的方法有下标法和指针法
数组名作为函数参数
sort(int x[], int n);
void main(){
int a[9];
sort(a, 9);
}
数组指针作为函数参数
形参数组x与主调函数的数组a具有相同的地址,这种现象好像是被调函数有多个值返回主函数,实际上还是严格按照单向传递原则的。
有了指针的概念后,对数组名作为函数参数可以有进一步的认识,实际上能够接受并存放地址值的形参只能是指针变量,C编译系统都是将形参数组名作为指针变量来处理的
综上,数组指针作为函数参数分以下3种情况。
1.形参,实参为数组名
2.形参是指针变量,实参是数组名
3.形参,实参均为指针变量
若实参为指针变量,在调用之前必须给指针变量赋值,使它指向某一数组.
结构体变量的定义
结构体类型定义是一个语句,应以分号结束.
1.定义类型后再定义变量
struct stu{
int num;
char name[20];
char sex;
int age;
};
struct stu wang, zhang;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
2.定义结构体类型的同时定义结构体变量
struct stu{
int num;
char name[20];
char sex;
int age;
}wang, zhang;
- 1
- 2
- 3
- 4
- 5
- 6
3.直接定义结构体变量
struct{
int num;
char name[20];
char sex;
int age;
}wang, zhang;
- 1
- 2
- 3
- 4
- 5
- 6
此方法中没有指出结构体类型名,在程序中仅有一处需要定义某种结构体变量时,可以使用此方法.
结构体变量的引用
可以引用结构体变量成员的地址,也可以引用结构体变量的地址.
scanf("%f", &};
不能以整体语句读入结构体变量,比如
scanf("%d%s%s%d", a};
结构体变量的地址主要用作函数参数,传递结构体变量的地址
结构体指针变量
结构体变量的指针定义
struct 结构体名 *结构体指针变量名;
也可以再定义结构体的同时定义结构体指针变量
struct data{int year; int month;}*q;
结构体指针变量也要先赋值后使用.
结构体指针变量访问结构体变量成员
(*结构体指针变量).成员名
或者
结构体指针变量->成员名
“->”是专门用于结构体指针变量引用结构体成员的一种形式.优先级为1级.
分配内存空间函数malloc
使用这些函数我们需要把头文件<>包含进来.
函数原型
void *malloc(unsigned size);
函数调用的一般形式
(类型说明符 *)malloc(size);
说明:
(1)malloc函数要求系统在内存中分配一块存储空间,这个存储空间是一块长度为size字节的连续区域,函数的返回值为该区域的首地址.
(2)函数返回的指针是无类型的,用户根据存储空间的用途把它强制转化成相应的类型.类型说明符表示把返回值强制转化为该类型指针.
(3)size是一个无符号数,单位是字节.
Tip:因为函数强制转化为我们需要的数据类型,所以这是一个又返回值的函数,我们需要定义一个相应的基类型指针变量接受这个返回值.
分配内存空间函数calloc
函数原型
void calloc(unsigned int n, unsigned int size);
函数调用一般形式
(类型说明符)calloc(n, size);
函数实现的功能是在内存动态存储区中分配n块长度为size字节的连续区域,函数的返回值为该区域的首地址.
calloc与malloc的区别就在于一次可以分配n块区域.
用typedef定义类型
在C语言程序中,我们可以用typedef为已有的类型名再命名一个新的类型名,即别名
1.为类型名定义别名
typedef 类型名 新类型名
或
typedef 类型定义 新类型名
typedef int COUNTER
typedef struct date{
int year;
int month;
int day;
}DATE;
这个时候int等价于COUNTER
struct date等价于DATE
2.为类型命名的方法
a.先按定义变量的方法写出定义体(例如 int i;)
b.将变量名换成新类型名(例如将i换成COUNTER)
c.在最前面加typedef(例如typedef int COUNTER)
d.然后可以用新类型名去定义变量
类型定义,定义一个DATE结构体类型
struct{
int month;
int year;
}DATE;
将这个结构体命名为DATE;
typedef struct{
int month;
int year;
}DATE;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
为指针类型命名
typedef int POINTER
在这里我们给一个整型指针类型重命名为POINTER
Tip:当号出现在类型名后面时,定义的是指向这个类型的指针变量.
文件
平时的输入输出以终端为对象,从操作系统的角度看,每一个与主机相连的输入/输出都看作是个文件,便于数据记录和处理,程序运行时,程序本身和数据一般都存于内存中。程序运行结束后,存放在内存中的数据被释放。如果需要长期保存程序运行所需的原始数据,或程序运行产生的结果,就必须以文件形式存储到外部存储介质上。
文件通常是存储在外部介质上的,从使用时才调入内存。
文件的分类
文件分为普通文件和设备文件。
设备文件是与主机相连的各种外部设备,如显示器,键盘等。外部设备也看成是一个文件来管理,把它们的输入/输出等同于对磁盘文件的读和写。显示器定义为标准输出文件,一般情况下在屏幕上显示有关信息就是向标准输出文件输出,如printf,putchar就是这类输出。键盘通常被指定为标准输出文件,从键盘上输入就意味着从标准输入文件上输入数据,scanf,getchar就属于这类输入。
文件的编码形式
文件的编码形式
ASCII码文件和二进制文件
ASCII码文件,也称为文本文件,这种文件在磁盘中存放时每个字符对应一个字节,用于存放对应的ASCII码。
二进制文件按二进制编码方式存放文件。十进制数1234的ASCII码共占用4个字节,ASCII码文件可在屏幕上按字符显示,因此能读懂文件内容。
十进制数1234的二进制存储形式只占两个字节,虽然也可在屏幕上显示,但是其内容无法读懂。
文件的读写方式
C语言系统处理文件时,并不区分类型,都看成是字符流,按字节进行处理。输入/输出字符流的开始和结束只由程序控制而不受物理符号(如回车符)的控制。因此也把这种文件称为 流式文件。系统自动在内存区中为每个正在使用的文件开辟一个缓冲区。从内存向磁盘输出数据时,必须首先输出到缓冲区中。缓冲区装满后,再一起输出到磁盘文件中。
这称为缓冲文件系统。
ANSI C标准正是采用这种缓冲文件系统,既处理文本文件,又处理二进制文件。
流式文件的各种操作中有个关键的指针,称为文件指针。文件指针在C语言中用一个指针变量指向一个文件,通过文件指针可对它所指的文件进行各种操作。
typedef struct{
short level;
unsigned flags;
char fd;
unsigned char hold;
short bsize;
unsigned char *buffer;
unsigned char *curp;
unsigned istemp;
short token;
}FILE;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11