安装网站模版视频教程,品牌网站策划书,深圳代理记账公司电话,最专业网站建设公司目录 一.C基础
1.第一个C程序#xff1a;
2.头文件#xff1a;
3.cin和cout初识#xff1a;
4.命名空间#xff1a; 二.顺序表和vector#xff08;STL#xff09;
1.顺序表的基本操作#xff1a;
2.封装静态顺序表#xff1a;
3.动态顺序表--vector#xff1a;…目录 一.C基础
1.第一个C程序
2.头文件
3.cin和cout初识
4.命名空间 二.顺序表和vectorSTL
1.顺序表的基本操作
2.封装静态顺序表
3.动态顺序表--vector
1创建vector
2size和empty
3begin和end
4front和back
5resize和clear 一.C基础 1.第一个C程序 可能有些同学跟我一样一直以来学习的都是基础的C语言而在接触蓝桥杯这类相比较正规的竞赛时会发现它所使用的程序规范与基础的C语言大相径庭但没关系的虽然他使用的规范隶属于C范畴但只要掌握以下几条差异C于我们也不会再陌生光说不算先直接来看一下我们的第一个C程序
#include iostream //头⽂件
using namespace std; //使⽤std的名字空间
int main() //main函数
{cout hello world! endl; //输出在屏幕打印hello world! return 0;
} 2.头文件
ok接下来我就来详细说说这其中的一些区别当然最先注意到的就是包含的头文件的差异了 前⾯的代码中写的 #include 就是在包含头⽂件头⽂件的名字叫 iostream 使用 #include 的形式进行包含 iostream 文件中的 io 指的是输⼊进入程序的信息简单理解就是可以给程序输⼊数据和输出从程序中输出的信息简单理解就是程序 会打印数据在屏幕上。 在 C 程序中要完成输⼊和输出的操作会涉及到 iostream 文件中的多个定义所以就要包含这个 头⽂件的 比如代码中的 cout 是输出流对象就是⽤来完成数据输出的就需要包含头文件。 简单些理解iostream这个头文件就当于是一个我们之前学习C语言里无数头文件的一个集合为的就是使我们对头文件的包含的使用更加方便和简洁 注 1. 在C语⾔中头文件的扩展名是 .h 但是C中的⽤法发生了⼀些变化对⽼式C的头⽂件保留了扩展名 .h 但是C自己的⽂件没有扩展名了如原来的C语⾔头⽂件 2. 有些C的头⽂件被转换成C头⽂件这些⽂件名被重命名去掉了.h扩展名并在⽂件名的前⾯加 上了前缀c表示来⾃C语⾔例如C语⾔中有关数学的头⽂件名字是 math.h 在C中就 是 cmath 当然还得注意有时头⽂件的C语⾔版本和C版本相同⽽有时候新版本做了⼀些 修改 3.cin和cout初识 cout hello world! endl;这句代码在上⾯的程序中是最重要的代码其他所有的 代码都是为了编写这句代码。 cout是标准输出流对象(针对控制台也就是屏幕)其实还有标准输⼊流对象cin(针对的是键 盘) 即cout 告诉程序把后⾯双引号中的内容打印到标准输出设备屏幕上双引号中的内容可以替换 #includeiostream
using namespace std;
int main()
{int num;cin num; //获取标准输⼊ cout num endl; //对获取到的结果标准输出 return 0;
} 总结 1.cin 和 cout 是全局的流对象 cin 负责输⼊数据(scanf) cout 负责输出数据(printf) 2. endl 是C中⼀个特殊的操作符效果是换行和刷新缓冲区使⽤时必须包含在 iostream 头文件里 3. 是流插⼊运算符和 cout 配合使用 是流提取运算符和 cin 配合使⽤两者容易混 淆⼤家⼀定要仔细区分不可混用 使⽤C输⼊输出更⽅便不需要像 printf / scanf 输⼊输出时那样需要⼿动控制格式。 C的输⼊输出可以⾃动识别变量类型。后面会提到到慢慢体会就好 #include iostream
using namespace std;
int main()
{float score 0;cin score;//直接读取的就是浮点数 cout score;//直接输出的就是浮点数 return 0;
}4.命名空间 using namespace std; 这句代码的意思是使⽤名字空间 std 名字空间也叫命名空间 为了理解什么是名字空间名字空间要解决什么问题先看⼀下下面的例子 在C中变量、函数和类都是⼤量存在的这些变量、函数和类的名称如果都存在于全局作⽤域中 可能会导致很多冲突。使⽤ 名字空间 的⽬的是对标识符的名称进⾏隔离以避免命名冲突或名字污染 namespace 关键字的出现就是针对这种问题的。 std 是C标准库的名字空间名C将标准库的定义实现都放到这个命名空间中当我们需要使用标准库中的内容时就需要加上 using namespace std 当有了这句代码的时候表示命名空间 std 中信息都是可见和可⽤的比如 cin 、 cout 、 endl 等 当然使用using namespace std;是⼀种简单粗暴的做法直接这样使⽤就意味着后续在std这个名字空间中的各种定义都可以直接使⽤但是我们往往只是使⽤部分。所以名字空间其实也可以这样使⽤ #incldue iostream
int main()
{ std::cout hello world std::endl;return 0;
} 代码中的 std::cout的意思就是使⽤std名字空间中的cout 欧克到这里为止再看一下最初的C程序是不是就好理解多了 #include iostream //头⽂件
using namespace std; //使⽤std的名字空间
int main() //main函数
{cout hello world! endl; //输出在屏幕打印hello world! return 0;
} 二.顺序表和vectorSTL
说完了上面C的基础格式接下来就是正式的蓝桥杯知识点的干货分享了
1.顺序表的基本操作 其实顺序表的基本操作无非就是我们老生常谈的那几种尾插尾删头插头删指定位置插入和删除和对某一个元素的查找这些在C语言基础里我都有提及详细可以看我附在下面的这篇文章 https://blog.csdn.net/2403_87691282/article/details/144203616?spm1001.2014.3001.5501 方便起见我还是把简化的一些操作附在下面以便阅览 // 打印顺序表
void print()
{for(int i 1; i n; i){cout a[i] ;}cout endl endl;
}// 尾插
void push_back(int a[], int n, int x)
{a[n] x;
}// 头插
void push_front(int x)
{// 1. 先把 [1, n] 的元素统⼀向后移动⼀位 for(int i n; i 1; i--){a[i 1] a[i];}// 2. 把 x 放在表头 a[1] x;n; // 元素个数 1
}// 在任意位置插⼊
void insert(int p, int x)
{//把 [p, n] 的元素统⼀向后移动⼀位 for(int i n; i p; i--){a[i 1] a[i];}a[p] x;n;
}// 尾删
void pop_back()
{n--;
}// 头删
void pop_front()
{// 1. 先把 [2, n] 区间内的所有元素统⼀左移⼀位 for(int i 2; i n; i){a[i - 1] a[i];}n--;
}// 任意位置删除
void erase(int p)
{// 把 [p 1, n] 的元素统⼀左移⼀位 for(int i p 1; i n; i){a[i - 1] a[i];}n--;
}// 按值查找
int find(int x)
{for(int i 1; i n; i){if(a[i] x) return i;}return 0;
}// 按位查找
int at(int p)
{return a[p];
}// 按位修改
int change(int p, int x)
{a[p] x;
}// 清空操作
void clear()
{n 0;
} 2.封装静态顺序表 所谓封装静态顺序表就是当我们在面对需要创建好几个顺序表并且对它们进行操作及以下情况时而产生的简化操作的行为 可见当涉及到多个顺序表时虽然上述的代码可以套用但还是略显麻烦这个时候就不由得发问了博主博主这些函数固然好用但有没有什么其他更简便的套用方式有的兄弟有的这么方便的用法当然是有的 #include iostream
using namespace std;
const int N 1e5 10;
// 将顺序表的创建以及增删查改封装在⼀个类中
class SqList
{int a[N];int n;
public:// 构造函数初始化 SqList(){n 0;}// 尾插 void push_back(int x){a[n] x;}// 尾删 void pop_back(){n--;}// 打印 void print(){for (int i 1; i n; i){cout a[i] ;}cout endl;}
};
int main()
{SqList s1, s2; // 创建了两个顺序表 for (int i 1; i 5; i){// 直接调⽤ s1 和 s2 ⾥⾯的 push_back s1.push_back(i);s2.push_back(i * 2);}s1.print();s2.print();for (int i 1; i 2; i){s1.pop_back();s2.pop_back();}s1.print();s2.print();return 0;
}在上述代码里博主使用了class类的运用对几个函数进行封装这样在以后对顺序表的操作时就可以直接使用”.“进行各种简洁的运用了 当然这里还需再提一下class和public的使用了蓝桥杯作为一个应试考试好些代码的具体原理就不再在这里进行深究了未来我会具体介绍但也仅供了解 在C中class是定义类的关键字而public是访问修饰符之一 以下是详细解释 class类 类是C中的基本构造块用于定义对象的属性和行为 类使用class关键字声明后面跟着类名和类体类体中包含成员变量和成员函数2。public公有 public是类的访问修饰符之一表示该成员变量或函数是公有的可以被类的外部访问 公有成员在类的内部和外部都可以被访问相当于C语言中的struct结构体成员 ps 在C中类和结构体struct都是用于定义复合数据类型的构造它们都可以包含成员变量和成员函数。然而尽管它们在许多方面相似但也有一个关键的区别 即默认访问权限 类class在类中默认的访问权限是私有的private这意味着除非明确指定为public或protected否则类的成员是不可从类外部访问的。 结构体struct在结构体中默认的访问权限是公有的public这意味着结构体的所有成员默认都是可以从外部访问的除非它们被明确指定为private或protected 当然我这边讲封装肯定不仅仅是为了简洁更多的还是为我接下来介绍SYL做一个铺垫 当然STL具体是啥我还是先说明一下 提供高效的数据结构 STL包含了多种高效的数据结构如vector动态数组、list双向链表、map映射/字典、set集合等。这些数据结构都是经过精心设计和优化的可以在不同的场景下提供高效的数据存储和访问。 实现常用的算法 STL提供了一系列常用的算法如排序、搜索、合并、拷贝等。这些算法都是以模板函数的形式提供的可以适用于不同的数据类型和容器。通过使用STL的算法可以避免重复编写常见的算法代码提高开发效率。 3.动态顺序表--vector 在之前C语言的学习过程中一提到动态顺序表就不由得会回忆起被malloc和freenew和deletae支配的恐惧而这里需要强调一点的就是竞赛代码不同于我们之前学的工程代码什么是工程代码就是以malloc为首的一系列相比来说在竞赛中使用效率不高而且容易超时的一系列函数因此当我们在竞赛过程中使用动态顺序表的时候就有了一种更好的方式 C 的STL 提供了⼀个已经封装好的容器vector 有的地⽅也叫作变⻓数组 vector 的底层就是⼀个会⾃动扩容的顺序表其中创建以及增删查 改等等的逻辑已经实现好了并且也完成了封装 接下来就重点了解以下vector 的使用 1创建vector
#include vector // 头⽂件
using namespace std;
const int N 20;
struct node
{int a, b, c;
};
// 创建
void init()
{vectorint a1; // 创建⼀个空的可变⻓数组 vectorint a2(N); // 指定好了⼀个空间⼤⼩为 N vectorint a3(N, 10); // 创建⼀个⼤⼩为 N 的 vector并且⾥⾯的所有元素都是 10 vectorint a4 { 1, 2, 3, 4, 5 }; // 使⽤列表初始化创建⼀个 vector // ⾥⾯可以放任意的类型这就是模板的作⽤也是模板强⼤的地⽅ // 这样vector ⾥⾯就可以放我们接触过的任意数据类型甚⾄是 STL vectorstring a5; // 放字符串 vectornode a6; // 放⼀个结构体 vectorvectorint a7N; vectorint a8[N];
} 大家仔细看的话会发现我最后俩没写注释为啥因为我觉得这俩在理解上有些不太容易所以我就单独把它们拎出来做解释 就正如上图字可能有些丑凑合看看吧捂脸所示可以理解为前者的主体时vectorint类型的变长数组而后者则是已顺序表为主体来存放变长数组 其实在C中vectorvectorint a7(N); 和 vectorint a8[N]; 是两种不同的方式来创建数组或数组的数组即二维数组但它们依旧有着本质的区别 vectorvectorint a7(N); 这是一个使用vector容器创建的二维动态数组。vector是C标准模板库STL中的一个序列容器它可以动态地管理内存根据需要自动调整大小。这里的a7是一个包含N个vectorint的vector即一个二维数组其中每一行都是一个可以独立调整大小的vectorint 优点 动态调整大小每一行都可以根据需要独立增加或减少元素。 内存管理自动化vector会自动管理内存减少内存泄漏的风险。缺点 可能的性能开销由于动态调整大小和自动内存管理可能会引入一些性能开销。 不是连续内存vector的底层实现通常是一个指向动态分配内存的指针数组因此二维vector的元素在内存中不是连续存储的。 vectorint a8[N]; 这是一个静态数组其中每个元素都是一个vectorint不同于第一个例子这里的数组大小N必须在编译时就已知且整个数组的大小在创建后是固定的。 优点 可能的性能优势由于是静态数组其大小在编译时确定可能在某些情况下提供更好的性能尤其是在访问连续内存时。缺点 固定大小数组的大小在创建后不能改变这限制了其灵活性。 非标准C使用静态数组的方式在某些情况下可能不符合现代C的最佳实践尤其是在需要动态调整大小或跨函数共享数据时。 总结来说选择哪种方式取决于具体需求如果需要一个大小可变的二维数组或者希望自动管理内存那么vectorvectorint是一个好选择如果知道数组的大小并且希望利用静态数组可能的性能优势那么vectorint a8[N];也可以考虑不过在现代C编程中推荐使用vector和智能指针等STL组件来管理动态数据结构以减少内存管理错误和提高代码的可维护性 2size和empty 1. size 返回实际元素的个数 2. empty 返回顺序表是否为空因此是⼀个bool 类型的返回值 a. 如果为空返回true b. 否则返回false 时间复杂度O(1) 以下是具体使用方式接下来我介绍的几个都是vector里常用的关键字了解会用就行 void test_size()
{// 创建⼀个⼀维数组 vectorint a1(6, 8);for(int i 0; i a1.size(); i){cout a1[i] ;}cout endl endl;// 创建⼀个⼆维数组 vectorvectorint a2(3, vectorint(4, 5));for(int i 0; i a2.size(); i){// 这⾥的 a2[i] 相当于⼀个 vectorint a(4, 5) for(int j 0; j a2[i].size(); j){cout a2[i][j] ;}cout endl;}cout endl endl;
}3begin和end 1. begin 返回起始位置的迭代器左闭 2. end 返回终点位置的下⼀个位置的迭代器右开 利⽤迭代器可以访问整个vector 存在迭代器的容器就可以使⽤范围for 遍历 说到迭代器还有一点不得不提一下我们的auto了 在C11及更高版本中auto 关键字被引入以支持类型自动推导。这意味着编译器可以根据初始化表达式自动推断变量的类型而无需指定auto 的使用可以简化代码尤其是在处理复杂类型或模板时 int x 10;
auto y x; // y 的类型被推导为 int 当使用STL容器如 vector, map, set 等的迭代器时auto 可以避免冗长的迭代器类型声明 std::vectorint vec {1, 2, 3, 4};
for (auto it vec.begin(); it ! vec.end(); it){// it 的类型被推导为 std::vectorint::iteratorstd::cout *it std::endl;} 还可以与语法糖结合在一起使用 for (auto x : a)
{cout x ;
}
cout endl; 当然这里的a是指一个vectorint类型的变长数组 上面这两行代码都可以实现对a数组的遍历与打印 4front和back 1. front 返回⾸元素 2. back 返回尾元素 时间复杂度O(1) // ⾸元素和尾元素
void test_fb()
{vectorint a(5);for(int i 0; i 5; i){a[i] i 1;}cout a.front() a.back() endl;
}这个使用并不难看一下了解即可 5resize和clear 1.resize修改vector 的大小 • 如果⼤于原始的大小多出来的位置会补上默认值⼀般是0 • 如果⼩于原始的大小相当于把后⾯的元素全部删掉。 时间复杂度O(N) 2.clear清空vector 底层实现的时候会遍历整个元素⼀个⼀个删除因此时间复杂度O(N) // resize
void test_resize()
{vectorint a(5, 1);a.resize(10); // 扩⼤ print(a);a.resize(3); // 缩⼩ print(a);
}// clear
void test_clear()
{vectorint a(5, 1);print(a);a.clear();cout a.size() endl;print(a);
}尾言 欧克全文终