Clion与C语言

时间:2025-03-27 08:10:35

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