discuz 科技网站模板下载,河南seo网站策划,wordpress 下载弹窗,讷河市铁道北建设高架桥当学习了C语言之后#xff0c;很多的小伙伴都想进一步学习C#xff0c;但两者有相当一部分的内容都是重叠的#xff0c;不知道该从哪些方面开始入门C#xff0c;这篇文章罗列了从C到C必学的入门知识#xff0c;学完就算是踏入C的大门了。 1. 命名空间
写C的时候#xff…当学习了C语言之后很多的小伙伴都想进一步学习C但两者有相当一部分的内容都是重叠的不知道该从哪些方面开始入门C这篇文章罗列了从C到C必学的入门知识学完就算是踏入C的大门了。 1. 命名空间
写C的时候偶尔可能不小心就和库函数冲突了又或者当两个程序员以相同的名字命名变量或函数就会发生冲突。C就提出了一个很好的解决方案——命名空间。
命名空间的关键字是namespace定义方式如下
【定义方式】
namespace N1
{int a 3;int b 4;
int Add(int x1, int x2){return x1 x2;}
struct Node{struct Node* next;int val;};
namespace N2{int c 0;int d 0;}
}从示例中可以看出命名空间中可以包含变量、函数、类型以及嵌套另一个命名空间
【使用方式】
1. 命名空间作用域限定符
int main() {printf(%d\n, N1::a);return 0;
}
2. using将命名空间中某个成员引入
using N1::b;
int main() {printf(%d\n, N1::a);printf(%d\n, b);return 0;
}
3. using namespace 变量空间
using namespace N1;
int main() {printf(%d\n, a);printf(%d\n, b);return 0;
} 2. 输入输出
其实C语言的printf/scanf在C中还可以使用不过C有独有的输入输出方式就是cin/cout
【使用说明】
1. 必须包含iostream头文件注意是iostream
2. 需要使用命名空间std因为cin/cout在其中的日常练习可以这么做但做项目的时候最好使用 std::cin 的方式展开
3. 使用时要用流插入操作符/流提取操作符不知道是什么没关系看示例是怎么用的就行cout用cin用
4. 变量之间也是用或连接如果需要换行用endl
【示例】
#include iostream
using namespace std;
int main()
{cout hello world! endl;return 0;
}【解惑】
我们有了printf和scanf为什么还要学习cin和cout呢因为其可以自动识别变量的类型相对来说就方便了很多不用考虑太多。不过cin/cout相对于前者慢一些在大量数据需要输入输出时就会有较大的时间差距。 3. 缺省参数
声明或者定义函数时为函数参数指定一个缺省值当函数没有传递对应的参数时就用缺省参数来代替有点像备胎的感觉doge
#include iostream
using namespace std;void Func (int a 10)
{cout a endl
}int main()
{Func(); //输出10Func(100); //输出100return 0;
}
【分类】
全缺省参数所有形参都加上了缺省参数
void Func(int a 10, int b 20, int c 30)
{cout a a endl;cout b b endl;cout c c endl;
}int main()
{Func(9, 8, 5);Func(9, 8);return 0;
}
半缺省参数只有部分参数给缺省值
void Func(int a, int b 20, int c 30)
{cout a a endl;cout b b endl;cout c c endl;
}//错误写法
//void Func(int a 10, int b, int c 30)
//void Func(int a 10, int b 20, int c)
//void Func(int a 10, int b, int c)int main()
{Func(9);Func(9, 8);Func(9, 8, 5);return 0;
}
注意
1. 半缺省参数只能从右往左给不能跳跃给也是为了避免传错参数出现歧义
2. 缺省参数不能同时在定义和声明中出现一般在声明中给
3. 缺省值必须是全局变量或常量 4. 函数重载
C中允许在同一个作用域中出现参数列表不同参数个数或类型不同的同名函数称这种现象为函数重载
【示例】
#include iostream
using namespace std;
//参数个数不同
void f1(int x, int y)
{cout void f1(int x, int y) endl;
}
void f1(int m)
{cout void f1(int m) endl;
}
//参数类型不同
void f2(int m)
{cout void f2(int m) endl;
}
void f2(double m)
{cout void f2(double m) endl;
}
//参数类型顺序不同本质就是类型不同
void f3(int x, double y)
{cout void f3(int x, double y) endl;
}
void f3(double x, int y)
{cout void f3(double x, int y) endl;
}
int main()
{f1(10, 20);f1(10);cout endl;f2(10);f2(1.0);cout endl;f3(10, 1.0);f3(1.0, 10);
return 0;
}【原理】
C的编译器会对函数进行修饰一种函数变量类型对于一种编码所以不同的变量类型或者个数对应不同的汇编代码所以函数名相同并不影响其分别不同的函数。
而C语言中相同的函数名是区分不开的。
此部分需要对程序的翻译和执行部分有一定的了解可以暂时跳过 5. 引用
引用是对已经创建的变量起别名操作符是
【示例】
#include iostream
using namespace std;int main()
{int a 1;int b a;cout a endl;cout b endl;//打印结果都是1cout a endl;cout b endl;//打印出来是同一个地址也就意味着在同一个空间return 0;
}
结果如下 所以当其中一个加的时候另一个也加效果如下 注意
1. 引用和实体的类型要相同鲁迅和周树人都是人
2. 引用在定义时必须初始化
3. 一个变量可以多个引用也就是可以多个别名
4. 引用一个实体就不能再引用其他的实体鲁迅是周树人的别名就不能再用“鲁迅”代指张三了
5. 引用不能作函数局部变量的返回值因为返回值的空间在退出函数之后就销毁了而引用与它共用一块空间所以此时为非法访问空间。当然如果是全局变量/函数外局部变量/静态变量/堆上变量也是可以的作为返回值的。
【使用方式】
1. 输出型参数
#include iostream
using namespace std;
void Swap1(int x, int y)
{int temp x;x y;y temp;
} //节省拷贝的空间在传大的对象时对比更加明显
void Swap2(int* m, int* n)
{int temp *m;*m *n;*n temp;
} //需要额外开辟一块空间存临时变量
int main()
{int a 1, b 2;Swap1(a, b);cout a b endl;int c 1, d 2;Swap2(c, d);cout c d endl;
return 0;
}2. 函数返回值注意返回局部变量时不可用
#include time.h
#include iostream
using namespace std;struct A
{ int a[10000];
};A a; A TestFunc1()
{ return a;
}A TestFunc2()
{ return a;
}int main()
{size_t begin1 clock();for (size_t i 0; i 100000; i)TestFunc1();size_t end1 clock();size_t begin2 clock();for (size_t i 0; i 100000; i)TestFunc2();size_t end2 clock();cout TestFunc1 time: end1 - begin1 endl;cout TestFunc2 time: end2 - begin2 endl;return 0;
}这效率赢麻了 有小伙伴又要问了引用这么香谁还用指针呀
那我们就得来看看指针和引用的区别了【面试考点】 语法 引用是别名不开空间指针是地址需要开空间存地址引用必须初始化指针可以初始化也可以不初始化引用不能改变指向指针可以不可替代的关键引用相对更安全没有空引用但是有空指针容易出现野指针但是不容易出现野引用sizeof引用为引用类型的大小指针为地址的大小、引用实体1指针偏移一个类型的大小、解引用访问引用不用解引用等方面的区别 底层 汇编层面上没有引用都是指针引用编译后也转换成指针了 总结C的引用对指针使用比较复杂的场景进行一些替换让代码更简单易懂但是不能完全替代指针因为引用定义后不能改变指向 【常引用】
如果我需要一个不可被修改的别名就会使用到常引用
//代码一正常引用权限平移
int a 10;
int ra a;
//代码二会报错本来我设的变量不可被改但是你的引用可以改相当于给它的权限过大了
const int b 10;
int rb b;
//代码三常引用相当于创建了一个不可修改的别名权限缩小
int c 10;
const int rc c;//代码四d转换成int需要生成临时变量再将临时变量赋给rd引用
//而临时变量是常量所以rd要用常量引用此代码没有const是编译错误的
double d 3.14;
const int rd d; 6. 内联函数
一般来说函数调用都会建立栈帧而如果有方式可以避免栈帧的调用可以大大提高运行的效率。
C引入了一个关键字inline以inline修饰的函数叫做内联函数编译时C编译器会在调用内联函数的地方展开函数调用替换为函数体没有函数调用建立栈帧的开销从而大大提升运行效率。
【示例】
inline int Add(int x, int y)
{return x y;
}int main()
{int ret Add(3, 4);cout ret endl;return 0;
}其实没什么好说的就是在函数前加上inline。
不过编译器会判断此代码是否大小合适如果比较大的话还是会建立栈帧避免在调用处展开导致程序膨胀。 注意
1. 不能是递归的函数且最好规模较小、频繁调用的函数。
2. 不建议声明和定义分离分离会导致链接错误。因为inline被展开就没有函数地址了链接就会找不到。 【拓展】 【面试考点】如果在头文件中包含了一个函数的声明和定义导致出现链接错误该如何处理 1. 声明和定义分离 2. 用static修饰函数链接属性只在当前文件可见不会进符号表大函数 3. inline修饰没有进符号表不会出现链接冲突 有小伙伴就要问了好像C语言里的宏也可以做到类似的效果(不建立栈帧就能调用)呀
但是宏也是有缺点的详细的内容可看这篇文章-链接
在C中有很多设计都可以替代宏constenuminline 7. auto关键字
在C中有的类型的名字会很长所以很容易会出错而这就引出了auto关键字
这个关键字的作用就是自动识别类型
当然除了用在比较长的类型名上还可以用于for循环这个也是C特有的
示例如下
int main()
{int array[] { 1,2,3,4,5 };for (auto e : array){e * 2;}
for (auto e : array){cout e ;}
return 0;
}上面这段代码等价于
int main()
{int array[] { 1,2,3,4,5 };for (int i 0; i sizeof(array) / sizeof(array[0]); i){array[i] * 2;}
for (int* p array; p array sizeof(array) / sizeof(array[0]); p){cout *p ;}
return 0;
}可见这里可以省去了不少的代码不过要注意如果不是遍历数组就不能这么操作了 【注意点】
1. auto声明指针类型时用auto和auto*没有区别但用auto声明引用类型时必须加。
2. auto不能作为函数参数和返回值也不能用来声明数组 8. 空指针nullptr
NULL可作常量0也可作无类型指针的常量
一般情况下NULL会被编译器认为是0常量但是我们想用它的时候往往是当作指针来用为了避免会出现麻烦的情况所以C又设计了一个nullptr指针就是表示指针空值即(void*)0 这篇内容很多可以收藏下来慢慢看感谢大家的点赞和支持