语言有独特的语法规则和定义,双方必须遵循这些规则和定义才能实现真正的交流。
C语言特点
1.2.2 学习C语言理由
1.2.3 C语言应用领域
C语言的应用极其广泛,从网站后台,到底层操作系统,从多媒体应用到大型网络游戏,均可使用C语言来开发:
C语言的简洁
C语言仅有32个关键字,9种控制语句,34种运算符,却能完成无数的功能:
第一个C语言程序:HelloWorld 编写C语言代码:hello.c
#include
int main()
{
//这是第一个C语言代码
printf("hello world\n");
return 0;
}
C语言的源代码文件是一个普通的文本文件,但扩展名必须是.c。
gcc最初用于编译C语言,随着项目的发展gcc已经成为了能够编译C、C++、Java、Ada、fortran、Object C、Object C++、Go语言的编译器大家族。
编译命令格式:
gcc [-option1] …
g++ [-option1] …
gcc、g++编译常用选项说明:
选项 含义
-o file 指定生成的输出文件名为file
-E 只进行预处理
-S(大写) 只进行预处理和编译
-c(小写) 只进行预处理、编译和汇编
#include
#include
int main()
{
printf("hello world\n");
system("pause");
return 0;
}
1.3.3 代码分析
#include< > 与 #include ""的区别:
stdio.h是在操作系统的系统目录下:
printf函数
printf是C语言库函数,功能是向标准输出设备输出一个字符串
printf(“hello world\n”);//\n的意思是回车换行
return语句
C语言编译过程
gcc编译过程
选项 含义
-E 只进行预处理
-S(大写) 只进行预处理和编译
-c(小写) 只进行预处理、编译和汇编
-o file 指定生成的输出文件名为 file
文件后缀 含义
.c C 语言文件
.i 预处理后的 C 语言文件
.s 编译后的汇编文件
.o 编译后的目标文件
64位和32位系统区别
1.6.3 寄存器、缓存、内存三者关系
按与CPU远近来分,离得最近的是寄存器,然后缓存(CPU缓存),最后内存。
CPU计算时,先预先把要用的数据从硬盘读到内存,然后再把即将要用的数据读到寄存器。于是 CPU<—>寄存器<—>内存,这就是它们之间的信息交换。
那为什么有缓存呢?因为如果经常操作内存中的同一址地的数据,就会影响速度。于是就在寄存器与内存之间设置一个缓存。
因为从缓存提取的速度远高于内存。当然缓存的价格肯定远远高于内存,不然的话,机器里就没有内存的存在。
由此可以看出,从远近来看:CPU〈—〉寄存器〈—> 缓存 <—> 内存。
单行注释 //
多行注释 /* */
标识符命名规则:
变量特点:
声明和定义区别
#include
int main()
{
//extern 关键字只做声明,不能做任何定义,后面还会学习,这里先了解
//声明一个变量a,a在这里没有建立存储空间
extern int a;
a = 10; //err, 没有空间,就不可以赋值
int b = 10; //定义一个变量b,b的类型为int,b赋值为10
return 0;
}
从广义的角度来讲声明中包含着定义,即定义是声明的一个特例,所以并非所有的声明都是定义:
一般的情况下,把建立存储空间的声明称之为“定义”,而把不需要建立存储空间的声明称之为“声明”。
作用: ⽤于记录程序中不可更改的数据
C 定义常量两种⽅式
1. #define 宏常量: #define 常量名 常量值 通常在⽂件上⽅定义,表⽰⼀个常量
2. const修饰的变量 const 数据类型 常量名 = 常量值
通常在变量定义前加关键字const,修饰该变量为常量,不可修改
#include
#define MAX 10 //声明了一个常量,名字叫MAX,值是10,常量的值一旦初始化不可改
int main()
{
int a; //定义了一个变量,其类型为int,名字叫a
const int b = 10; //定义一个const常量,名为叫b,值为10
//b = 11; //err,常量的值不能改变
//MAX = 100; //err,常量的值不能改变
a = MAX;//将abc的值设置为MAX的值
a = 123;
printf("%d\n", a); //打印变量a的值
return 0;
}
#include
int main()
{
int a = 123; //定义变量a,以10进制方式赋值为123
int b = 0567; //定义变量b,以8进制方式赋值为0567
int c = 0xabc; //定义变量c,以16进制方式赋值为0xabc
printf("a = %d\n", a);
printf("8进制:b = %o\n", b);
printf("10进制:b = %d\n", b);
printf("16进制:c = %x\n", c);
printf("16进制:c = %X\n", c);
printf("10进制:c = %d\n", c);
unsigned int d = 0xffffffff; //定义无符号int变量d,以16进制方式赋值
printf("有符号方式打印:d = %d\n", d);
printf("无符号方式打印:d = %u\n", d);
return 0;
}
#include
int main()
{
int a;
printf("请输入a的值:");
//不要加“\n”
scanf("%d", &a);
printf("a = %d\n", a); //打印a的值
return 0;
}
#include
int main()
{
short a = 10;
int b = 10;
long c = 10l; //或者10L
long long d = 10ll; //或者10LL
printf("sizeof(a) = %u\n", sizeof(a));
printf("sizeof(b) = %u\n", sizeof(b));
printf("sizeof(c) = %u\n", sizeof(c));
printf("sizeof(c) = %u\n", sizeof(d));
printf("short a = %hd\n", a);
printf("int b = %d\n", b);
printf("long c = %ld\n", c);
printf("long long d = %lld\n", d);
unsigned short a2 = 20u;
unsigned int b2 = 20u;
unsigned long c2= 20ul;
unsigned long long d2 = 20ull;
printf("unsigned short a = %hu\n", a2);
printf("unsigned int b = %u\n", b2);
printf("unsigned long c = %lu\n", c2);
printf("unsigned long long d = %llu\n", d2);
return 0;
}
#include
int main()
{
signed int a = -1089474374; //定义有符号整型变量a
printf("%X\n", a); //结果为 BF0FF0BA
//B F 0 F F 0 B A
//1011 1111 0000 1111 1111 0000 1011 1010
return 0;
}
#include
int main()
{
unsigned int a = 3236958022; //定义无符号整型变量a
printf("%X\n", a); //结果为 C0F00F46
return 0;
}
当我们写程序要处理一个不可能出现负值的时候,一般用无符号数,这样可以增大数的表达最大值
3) 有符号和无符号整型取值范围
#include
int main()
{
int a;
int b = sizeof(a);//sizeof得到指定值占用内存的大小,单位:字节
printf("b = %d\n", b);
size_t c = sizeof(a);
printf("c = %u\n", c);//用无符号数的方式输出c的值
return 0;
}
字符变量的定义和输出
字符型变量用于存储一个单一字符,在 C 语言中用 char 表示,其中每个字符变量都会占用 1 个字节。在给字符型变量赋值时,需要用一对英文半角格式的单引号(’ ')把字符括起来。字符变量实际上并不是把该字符本身放到变量的内存单元中去,而是将该字符对应的 ASCII 编码放到变量的存储单元中。char的本质就是一个1字节大小的整型。
#include
int main()
{
char ch = 'a';
printf("sizeof(ch) = %u\n", sizeof(ch));
printf("ch[%%c] = %c\n", ch); //打印字符
printf("ch[%%d] = %d\n", ch); //打印‘a’ ASCII的值
char A = 'A';
char a = 'a';
printf("a = %d\n", a); //97
printf("A = %d\n", A); //65
printf("A = %c\n", 'a' - 32); //小写a转大写A
printf("a = %c\n", 'A' + 32); //大写A转小写a
ch = ' ';
printf("空字符:%d\n", ch); //空字符ASCII的值为32
printf("A = %c\n", 'a' - ' '); //小写a转大写A
printf("a = %c\n", 'A' + ' '); //大写A转小写a
return 0;
}
#include
int main()
{
char ch;
printf("请输入ch的值:");
//不要加“\n”
scanf("%c", &ch);
printf("ch = %c\n", ch); //打印ch的字符
return 0;
}
ASCII 码大致由以下两部分组成:
ASCII 非打印控制字符: ASCII 表上的数字 0-31 分配给了控制字符,用于控制像打印机等一些外围设备。
ASCII 打印字符:数字 32-126 分配给了能在键盘上找到的字符,当查看或打印文档时就会出现。数字 127 代表 Del 命令。
#include
int main()
{
printf("abc");
printf("\refg\n"); //\r切换到句首, \n为换行键
printf("abc");
printf("\befg\n");//\b为退格键, \n为换行键
printf("%d\n", '\123');// '\123'为8进制转义字符,0123对应10进制数为83
printf("%d\n", '\x23');// '\x23'为16进制转义字符,0x23对应10进制数为35
return 0;
}
实型变量也可以称为浮点型变量,浮点型变量是用来存储小数数值的。在C语言中, 浮点型变量分为两种: 单精度浮点数(float)、 双精度浮点数(double), 但是double型变量所表示的浮点数比 float 型变量更精确。
由于浮点型变量是由有限的存储单元组成的,因此只能提供有限的有效数字。在有效位以外的数字将被舍去,这样可能会产生一些误差。
不以f结尾的常量是double类型,以f结尾的常量(如3.14f)是float类型。
#include
int main()
{
//传统方式赋值
float a = 3.14f; //或3.14F
double b = 3.14;
printf("a = %f\n", a);
printf("b = %lf\n", b);
//科学法赋值
a = 3.2e3f; //3.2*1000 = 3200,e可以写E
printf("a1 = %f\n", a);
a = 100e-3f; //100*0.001 = 0.1
printf("a2 = %f\n", a);
a = 3.1415926f;
printf("a3 = %f\n", a); //结果为3.141593
return 0;
}
当超过一个数据类型能够存放最大的范围时,数值会溢出。
有符号位最高位溢出的区别:符号位溢出会导致数的正负发生改变,但最高位的溢出会导致最高位丢失。
#include
int main()
{
char ch;
//符号位溢出会导致数的正负发生改变
ch = 0x7f + 2; //127+2
printf("%d\n", ch);
// 0111 1111
//+2后 1000 0001,这是负数补码,其原码为 1111 1111,结果为-127
//最高位的溢出会导致最高位丢失
unsigned char ch2;
ch2 = 0xff+1; //255+1
printf("%u\n", ch2);
// 1111 1111
//+1后 10000 0000, char只有8位最高位的溢出,结果为0000 0000,十进制为0
ch2 = 0xff + 2; //255+1
printf("%u\n", ch2);
// 1111 1111
//+1后 10000 0001, char只有8位最高位的溢出,结果为0000 0001,十进制为1
return 0;
}
字符串常量
字符串是内存中一段连续的char空间,以’\0’(数字0)结尾。
字符串常量是由双引号括起来的字符序列,如“china”、“C program”,“$12.5”等都是合法的字符串常量。
字符串常量与字符常量的不同:
每个字符串的结尾,编译器会自动的添加一个结束标志位’\0’,即 “a” 包含两个字符’a’和’\0’。
printf函数和putchar函数
printf是输出一个字符串,putchar输出一个char。
#include
int main()
{
int a = 100;
printf("a = %d\n", a);//格式化输出一个字符串
printf("%p\n", &a);//输出变量a在内存中的地址编号
printf("%%d\n");
char c = 'a';
putchar(c);//putchar只有一个参数,就是要输出的char
long a2 = 100;
printf("%ld, %lx, %lo\n", a2, a2, a2);
long long a3 = 1000;
printf("%lld, %llx, %llo\n", a3, a3, a3);
int abc = 10;
printf("abc = '%6d'\n", abc);
printf("abc = '%-6d'\n", abc);
printf("abc = '%06d'\n", abc);
printf("abc = '%-06d'\n", abc);
double d = 12.3;
printf("d = \' %-10.3lf \'\n", d);
return 0;
}
#include
int main()
{
char ch1;
char ch2;
char ch3;
int a;
int b;
printf("请输入ch1的字符:");
ch1 = getchar();
printf("ch1 = %c\n", ch1);
getchar(); //测试此处getchar()的作用
printf("请输入ch2的字符:");
ch2 = getchar();
printf("\'ch2 = %ctest\'\n", ch2);
getchar(); //测试此处getchar()的作用
printf("请输入ch3的字符:");
scanf("%c", &ch3);//这里第二个参数一定是变量的地址,而不是变量名
printf("ch3 = %c\n", ch3);
printf("请输入a的值:");
scanf("%d", &a);
printf("a = %d\n", a);
printf("请输入b的值:");
scanf("%d", &b);
printf("b = %d\n", b);
return 0;
}
插件安装
single file execution
打开cmakelist.txt
cmake_minimum_required(VERSION 3.19) 这是指定cmake执行的最小版本
project(c_workspace1) 项目名
set(CMAKE_CXX_STANDARD 11) # 语言版本
add_executable(c_workspace1 demo1.cpp) 将我们的cpp文件注册到cmakelist中
第一个参数是项目名, 第二个参数cpp文件名
自己编写一个helloword文件
#include
using namespace std;
int main(){
cout<< "hello" << endl;
}
tab键可以进行代码补全, / 是根目录, ~是用户目录
cd 目录名
ls
pwd
clear
cd ..
mkdir day01
touch demo1.cpp
vim demo1.cpp
i 是进入编辑状态; 编辑完毕后按esc ; 输入 :wq保存退出
cat demo1.cpp
g++ -o demo1 demo1.cpp
g++ -o 源文件名 编译源文件
./demo1
rm -f hello.txt
mv demo1.cpp demo2.cpp
mv demo2.cpp /Users/ericli/CLionProjects/houjiheng/demo2.cpp
cp demo2.cpp /Users/ericli/CLionProjects/houjiheng/demo2.cpp
使用gcc -o 编译文件的名字 源文件
本身不会被执行, 是给别人看的, 对程序的解释
单行注释 //
多行注释 /* */
给⼀段指定的内存空间起名,⽅便操作这段内存
格式: 数据类型 变量名 = 变量值;
#include
using namespace std;
int main(){
// c++中创建变量是必须要给变量一个初始值,否则会报错
// 第一种变量声明方式. 声明+初始化
int a = 888;
a = 333;
cout<< "a = " << a << endl;
// 第二种变量声明方式 先声明 在初始化
int b;
b = 999;
cout<< "b = " << b << endl;
}
作用: ⽤于记录程序中不可更改的数据
C++定义常量两种⽅式
1. #define 宏常量: #define 常量名 常量值 通常在⽂件上⽅定义,表⽰⼀个常量
2. const修饰的变量 const 数据类型 常量名 = 常量值
通常在变量定义前加关键字const,修饰该变量为常量,不可修改
举个例子
#include
#define day 7
#define PI 3.14
using namespace std;
// 常量
int main(){
// 宏常量
cout<< "a week have "<< day << " days"<< endl;
cout<< "PI = "<< PI << endl;
// const 修饰变量
const int month = 12;
// month = 13; 常量是不能修改的 会报错
cout<< "month = "<< month << endl;
}
注意: 在定义变量或者常量时候,不要⽤关键字
作⽤:关键字是C++中预先保留的单词(标识符)
C++规定给标识符(变量、常量)命名时,有⼀套⾃⼰的规则
#include
using namespace std;
int main(){
# 两个变量
int num = 100;
int NUM = 200;
cout<< num << endl;
cout<< NUM << endl;
}
C++规定在创建⼀个变量或者常量时,必须要指定出相应的数据类型,否则⽆法给变量分配内存
1 字节(Byte) = 8 位(bit)
利⽤sizeof关键字可以统计数据类型所占内存⼤⼩
语法: sizeof( 数据类型/ 变量)
#include
using namespace std;
// size of
int main(){
int a =100;
cout<< "short = "<< sizeof(short)<<endl;
cout<< "int = "<< sizeof(int)<<endl;
cout<< "long = "<< sizeof(long)<<endl;
cout<< "long long = "<< sizeof(long long )<<endl;
cout<< "a = "<< sizeof(a)<<endl;
// 结论
// short < int <= long <= long long
}
浮点型有两种
#include
using namespace std;
int main(){
cout.precision(10);// 设置consle输出有效数字的范围
float f1 = 3.141592653f;//整数部分也算有效位的范围
double d1 = 3.141592653;
cout<< f1 << endl;
cout<< d1 << endl;
cout<<"float sizeof = " <<sizeof(f1)<< endl; // 4
cout<<"double sizeof = " <<sizeof(d1)<< endl; // 8
// 科学计数法
float f2 = 3e2; // 3*10^2
cout<<"f2 = " <<f2<< endl; //
float f3 = -4e3; // -4*10^3
cout<<"f3 = " <<f3<< endl; //
float f4 = 4e-2; // 4* 10 -2 次方 计算机浮点数计算会损失精度
cout<<"f4 = " <<f4<< endl; //
}
作用: 字符型变量⽤于显⽰单个字符
#include
using namespace std;
// 字符型
int main(){
char ch = 'a'; // 单引号
cout<<"ch = " <<ch<< endl; //
cout<<"size of char " <<sizeof(ch)<< endl; // 占一个字节
// ch = 'abcde'; // 错误 单引号内只能是一个字符
// ch = "abcde"; // 错误 不能用双引号
// 查看字符对应的 ASCII码
cout<<"a ASCII码 = " <<(int)ch<< endl; // 97
char ch2 = 'A'; // 单引号
cout<<"A ASCII码 = " <<(int)ch2<< endl; // 97
// 可以直接用ascii码给字符型变量赋值
ch = 97;
char ch3 = 98;
cout<<"ch = " <<ch<< endl; // 97
cout<<"ch3 = " <<ch3<< endl; // 97
}
ASCII 码⼤致由以下两部分组成:
作⽤:⽤于表⽰⼀些不能显⽰出来的ASCII字符
现阶段我们常⽤的转义字符有: \n \ \t
#include
using namespace std;
// 转义字符
int main(){
// \本身代表转义的意思, 他已经不是本身\的意思了
cout<< "\\" << endl; // 只输出一个斜杠
// 换行
cout<< "hello\nhaha" << endl; // 只输出一个斜杠
// 等价于tab键
cout<< "hello\thaha" << endl; // 只输出一个斜杠
}
作⽤:⽤于表⽰⼀串字符
两种风格
#include
using namespace std;
// 字符串
int main(){
char str1[] = "hello world";
cout<< str1 << endl;
}
#include
#include
using namespace std;
// 字符串
int main(){
char str1[] = "hello world";
cout<< str1 << endl;
string str = "hello world";
cout<< str << endl;
}
c++风格字符串需要引入头文件#include
布尔数据类型代表真或假的值
布尔数据类型代表真或假的值
bool类型只有两个值:
#include
using namespace std;
int main(){
bool flag = true;
cout<< flag << endl;// 1
flag = false;
cout<< flag << endl;// 0
cout<< "bool size" <<sizeof(flag)<< endl;// 1
}
cin >> 变量
#include
using namespace std;
int main(){
// 整型输入
int a;
cout << "please input a number "<<endl;
cin>>a;
cout << "a = "<< a << endl;
// 浮点型输入
double d;
cout << "please input double number "<<endl;
cin>>d;
cout << "d = "<< d << endl;
// 字符型输入
char ch;
cout << "please input a char "<<endl;
cin>>ch;
cout << "ch = "<< ch << endl;
// 字符串型输入
string str;
cout << "please input a string "<<endl;
cin>>str;
cout << "str = "<< str << endl;
// 布尔型输入
bool flag;
cout << "please input a bool value "<<endl;
cin>>flag;
cout << "flag = "<< flag << endl;
}