C和C++常见误区以及问题整理
c和c++的关系
c是面向过程的语言,c++是在c的基础上扩展的面向对象的编程语言。
c++具备c的所有功能,对c的库完全兼容。
c++的标准在98年确定,在那之前已经有一些库大量使用。
新标准中,推出了名称空间的概念,既是为了方便人们使用新标准的同时,不用大量修改之前的代码,对之前的代码兼容,同时可以有效的避免名称冲突。
旧标准中以.h结尾
新标准没有.h
旧标准中可以直接包含c的库文件,编译器会附带c的兼容库实现
新标准中有一样的c库子模块支持,命名方式变更为:原stdio.h,新cstdio,即前面+c,后面去掉.h
C++标准库(C++ Standard Library),是类库和函数的集合。
C++编译器厂商根据C++标准委员会官方的ISO规范并将其转化为代码。
C++编译器厂商在实现C++标准库过程中必须依赖其不同操作系统所提供的系统调用接口,因此每个平台都有其自己的C++标准库实现。
C++标准库的特点如下:
A、C++标准库不是C++语言标准的一部分,由类库和函数库组成。
B、C++标准库中定义的类和对象都位于std命名空间中。
C、C++标准库的头文件都不带.h后缀。
D、C++标准库涵盖了C库的功能
E、C++标准库中包含一个涵盖C库功能的子库,通常头文件以c开头,如#include <cmath>
,#include <cstring>
等。
如何理解名称空间
命名空间存在的目的是为了解决源代码中的重名问题。比如你写代码的时候需要用到矩阵计算,于是你定义了一个类,叫做Matrix。然后你引入的第三方库中,也有一个叫做Matrix的类,于是乎就重名了。为了解决这个问题,只需要把它们放在不同的命名空间里,比如你的叫做foo::Matrix, 第三方库的叫做third_party::Matrix,这样它们就有了不同的名字,编译器就可以正确识别出你在代码中用的Matrix是哪一个。
这个时候如果你同时使用了using namespace foo,using namespace third_party,就又会使这两个不同的类具有相同的标识符。因此在良好的编程风格中,尽可能的避免使用using namespace,或者仅在翻译单元(可以理解为是一个cpp文件)内、函数内、类内使用(using具体的对象、函数)。
第二个问题是是不是所有的程序名字都要在std中。恰恰相反,C++标准禁止用户自己扩充std命名空间,所以用户的代码应该是处于非std空间中,例如默认命名空间:: 。但是,事实上每一个编译器都支持用户在std空间中定义自己的类、函数、对象,因此在std实现自定义类的哈希函数也是可以编译通过的,尽管这是一个违背标准的行为。
在刷算法时,可以随意一点,按照这种方式使用
using namespace std; // avoid as too indiscriminate(随意)
严谨一点可以这样,最大限度地避免冲突的产生
using std::cin;
using std::cout;
using std::endl;
int x;
cin >> x;
cout << x << endl;
或者这样
int x;
std::cin >> x ;
std::cout << x << std::endl;
However,
using namespace std;
is considered a bad practice because you are practically importing the whole standard namespace, thus opening up a lot of possibilities for name clashes. It is better to import only the stuff you are actually using in your code, like
using std::string;
字符串类型
C语言不支持真正意义上的字符串,但可以使用字符数组和一组函数实现字符串操作。C语言不支持自定义类型,因此也不能定义字符串类型。
C++语言可以自定义类型,可以通过类完成字符串类型的定义,但C++语言也没有原生的字符串类型。C++语言通过C++标准库提供的string类型实现对字符串类型的支持。string类的特性如下:
A、string直接支持字符串连接
B、string直接支持字符串的大小比较
C、string直接支持子串查找和提取
D、string直接支持字符串的插入和替换
变量声明与定义
extern int i; //声明,不是定义
int i; //声明,也是定义
定义只能出现在一处。也就是说,不管是 int a 还是 int a=0 都只能出现一次,而 extern int a 可以出现很多次。
当你要引用一个全局变量的时候,你就要声明 extern int a 这时候 extern 不能省略,因为省略了,就变成 int a 这是一个定义,不是声明。
前缀指定基数:
- 0x 或 0X 表示十六进制,
- 0 表示八进制,
- 0b表示二进制
- 不带前缀则默认表示十进制
后缀是 U 和 L 的组合,U 表示无符号整数(unsigned),L 表示长整数(long)。后缀可以是大写,也可以是小写,U 和 L 的顺序任意。
结构数据类型
结构数据类型允许构造由多个基础数据类型组合而成的复杂结构,结构数据类型为面向对象的蓝本。以下的结构数据类型通过指针实现了二叉树结构
typedef struct Bintree {
int data;
struct bintree *lchild; // left child of the node
struct bintree *rchild; // right child of the node
} bintree; // 自定义 bintree 类型
&&,||,&,|
&&:逻辑与,前后条件同时满足表达式为真
||:逻辑或,前后条件只要有一个满足表达式为真
&:按位与
|:按位或
&&和||是逻辑运算,&与|是位运算
*,&
*
的作用
1.乘号(Multiply)
2.声明指针(Pointer Statement)
//就是声明变量a是5,把a的地址附到指针ptr上
int a =5; int* ptr=&a;
3.解引用 (Dereference)
*ptr 单独拿出来就是找出 ptr指针指向的值,按照第二点的说法就是5
&
的作用
&叫做取地址符号
一般指针只能接受一个内存地址而不能接受一个值
//错误表达,指针不能接受一个值
int a =5; int* ptr=a;
//正确表达,把a的地址给指针ptr
int a =5; int* ptr=&a;
案例:
数据结构伪代码理解
比如定义链表时:
typedef struct Node{
}Node,*Linklist;
在创建函数时候这样,
int creatlist(Linklist &L){}
用这个函数时候需要这样写
creatlist(L);
而定义顺序表时
typedef struct{
}List;
创建函数时候
int creatlist(List *l){}
用函数的时候
creatlist(&l);
解答
不关引用和题主C语言不好的事,事情应该是这样的:
并不是你的教材和你的老师讲错了,这样的代码是有意为之。但是程序又跑不起来,那问题出在哪呢。问题就在于大多数数据结构教材一开始就告诉了你,
本书的算法都是用类C语言伪码实现的,并非是严格意义上的C语言。在创建函数时候这样,
int creatlist(Linklist &L){}
用这个函数时候需要这样写creatlist(L);
为什么这么创建(定义)函数呢?因为编书人想告诉你的是函数的参数并非变量本身,而是存放变量的地址(有些答主学了C++,看到&就是引用,真的,你太敏感了)。
为什么要这么调用呢?因为函数的定义,函数调用需要传一个地址进去,那么传一个指针进去是理所当然的。再来看这段代码。而定义顺序表时
typedef struct{
}List;
创建函数时候
int creatlist(List *l){}
用函数的时候
creatlist(&l);
WTF?看起来跟上面的定义和调用格式都完全不一样哎,又懵逼了...其实是这样的:为什么这样创建(定义)函数呢?和上其实同理,如果这样写,typedef struct{
}List;
int creatlist(List l){}就是在说你只是传了一个结构体进去。所以作者加个*,是想告诉你这里传进去的是个顺序表。
为什么这么调用呢?还是因为定义,函数需要一个地址,那么我们就传一个地址进去。综上所述,这几段代码肯定是跑不起来的,因为根本不是C语言代码,只是伪代码而已,那作者是吃多了才这么写么?不是。作者只是想简化用来实现算法的语言,因为数据结构中选用的语言根本不是重点,重点是各种数据结构的思想。换句话说作者没想让你把程序跑起来,作者只是想让你能更容易懂。说到这里我想你应该很明白了,程序跑不起来书和老师都没有错(也不是某些答主说的C++中的引用或者你的C语言学得不好),既然作者已经将语法简化得不能再简化了,何妨不将教材上的伪代码充分理解,然后选取一门语言自己实现它呢?或许作者选用伪代码来讲述也有这一层原因(逼你自己动手)吧。
参考链接:请问 C 语言中 & 和 * 的用法? - 陈思定的回答 - 知乎
gcc,g++,gdb,cc
gcc and g++ are compiler-drivers of the GNU Compiler Collection (which was once upon a time just the GNU C Compiler).Even though they automatically determine which backends (cc1 cc1plus ...) to call depending on the file-type, unless overridden with -x language, they have some differences.The probably most important difference in their defaults is which libraries they link against automatically.According to GCC's online documentation link options and how g++ is invoked, g++ is equivalent to gcc -xc++ -lstdc++ -shared-libgcc (the 1st is a compiler option, the 2nd two are linker options). This can be checked by running both with the -v option (it displays the backend toolchain commands being run).
GCC: GNU Compiler Collection
- Referrers to all the different languages that are supported by the GNU compiler.
gcc: GNU C Compiler
g++: GNU C++ Compiler
The main differences:
- gcc will compile: *.c , *.cpp files as C and C++ respectively.
- g++ will compile: *.c , *.cpp files but they will all be treated as C++ files.
- Also if you use g++ to link the object files it automatically links in the std C++ libraries (gcc does not do this).
- gcc compiling C files has fewer predefined macros(预定义宏命令).
- gcc compiling *.cpp and g++ compiling *.c/*.cpp files has a few extra macros.
C和C++常见误区以及问题整理的更多相关文章
- NODE.JS学习的常见误区及四大名著
NODE.JS学习的常见误区及四大名著 前段时间由于不满于社区里很多人对于NODE.JS的种种误解而写了一篇文章名为: NODE.JS之我见:http://www.cnblogs.com/pugang ...
- 绝对定位常见误区:position:absolute相对于谁定位、及当溢出时怎么隐藏
1.绝对定位元素溢出父元素,怎么隐藏问题? 通常,为了让DIV子元素超出部分隐藏,都是在父元素设置overflow:hidden,这样即可防止子元素撑开父元素,使子元素能够溢出隐藏! 但是,对于pos ...
- nginx反向代理跨域基本配置与常见误区
最近公司前后端分离,前端独立提供页面和静态服务很自然的就想到了用nginx去做静态服务器.同时由于跨域了,就想利用nginx的反向代理去处理一下跨域,但是在解决问题的同时,发现网上有些方案的确是存在一 ...
- 【原创】C语言和C++常见误区(一)
本文仅在博客园发布,认准原文地址:https://www.cnblogs.com/jisuanjizhishizatan/p/15414469.html 问题1:int类型占几个字节? 常见误区:占4 ...
- JavaScript的一些常见误区
原文出处: 色拉油的博客 接触JavaScript两年多遇到过各种错误,其中有一些让人防不胜防,原来对JavaScript的误会如此之深,仅以此文总结一下常见的各种想当然的误区. String r ...
- oc常见误区
1.同步请求可以从因特网请求数据,一旦发送同步请求,程序将停止用户交互,直至服务器返回数据完成,才可以进行下一步操作, 2.异步请求不会阻塞主线程,而会建立一个新的线程来操作,用户发出异步请求后,依然 ...
- 也许是关于C#的一些常见误区
写这点东西主要是看到知乎上有人在讨论相关的问题,但是有不少人都在说一些不严谨,甚至是完全错误 但是流传甚广的东西,甚至是一些大神都在说,以下根据我的回答总结. 一个很常见又很低级的误区是:认为引 ...
- Lodop客户端本地角色注册号常见误区
之前写过一篇关于Lodop和c-lodop注册号的区别:LODOP.C-LODOP注册号的区别第一种角色客户端本地打印角色是最常见的角色,最常见的场景,关于c-lodop云打印,它的第一种角色是取代L ...
- Java的常见误区与细节
网上转来的 昨天整整一天,我都都呆在图书里.本打算找一些书学习“正则表达式”,很失望,没找到有这部分的内容的书.发现了一本<Java深入解析>,其中涉及了很多平时没有注意的一些误区,也许开 ...
随机推荐
- mysql慢查询相关
如何查看执行较慢的sql: 1.使用show variables like '%query%'; 查询结果: ft_query_expansion_limit 20have_query_cache Y ...
- ACM-ICPC 2018 徐州赛区网络预赛 H. Ryuji doesn't want to study (线段树)
Ryuji is not a good student, and he doesn't want to study. But there are n books he should learn, ea ...
- 微服务架构 SpringBoot(二)
第二天内容:想来想去玩个ssm小demo吧 1.创建表 2..引入相关mybatis 数据库jar: <!--mybatis --> <dependency> <grou ...
- Mybatis中的 >= <= 与 sql写法区别
- Wonder暂停开发,开始写书
公告 大家好,我们决定暂时停止开发Wonder,但会继续维护当前的Wonder版本(如继续维护官网.在线编辑器.QQ群等). 我们当前的主要任务是 写书:基于Wonder 1.0版本的开发经验,写一本 ...
- 常见的 由于未调整服务器 ulimit 而引起的内存溢出问题
原文内容来自于LZ(楼主)的印象笔记,如出现排版异常或图片丢失等问题,可查看当前链接:https://app.yinxiang.com/shard/s17/nl/19391737/e3bb62c9-9 ...
- LeetCode 11月第2周题目汇总
开源地址:点击该链接 前言 最近比较忙,这周几乎没有刷题,只刷了6道题~ 题目汇总 0387_first_unique_character_in_a_string类似的题目比较多了,字符串中找出特别的 ...
- 从零开始学.net core(一)
https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/first-web-api?view=aspnetcore-3.0
- sql server的简单分页
--显示前条数据 select top(4) * from students; --pageSize:每页显示的条数 --pageNow:当前页 )) sno from students); --带条 ...
- Shell(五):函数
linux shell 可以用户定义函数,然后在shell脚本中可以随便调用. shell中函数的定义格式: [ function ] funname [()] { action; [return i ...