【编程基础】C++比C牛逼的七个点

1. 函数检测增强

在C语言中,重复定义多个同名的全局变量是合法的,在C++中,不允许定义多个同名的全局变量。

C语言中多个同名的全局变量最终会被链接到全局数据区的同一个地址空间上。

下面的代码在c中完全合法:

#include <stdlib.h>

#include <stdio.h>

int g_var;

int g_var = 1;

void main()

{

printf("g_var = %d\n", g_var);

system("pasue");

}

而C++直接拒绝这种二义性的做法。

2. struct类型加强

C语言的struct定义了一组变量的集合,C编译器并不认为这是一种新的类型

C++中的struct是一个新类型的定义声明

下面的代码在c编译器下是通不过的,不过在c++编译器下确可以通过:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

struct Student

{

char name[100]; int age;

};

int main(int argc, char *argv[])

{

Student s1 = {"wang", 1};

Student s2 = {"wang2", 2};

return 0;

}

c语言中需要用typedef将Student重命名为Student才能如此大张旗鼓的使用student。

typedef struct Student

{

char name[100];

int age;

}Student;

3. C++中所有的变量和函数都必须有类型

很难想像,下面的代码居然在c编译器下面可以通过:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

f(i)

{

printf("i = %d\n", i);

}

g()

{

return 5;

}

int main(int argc, char *argv[])

{

f(10);

printf("g() = %d\n", g(1, 2, 3, 4, 5));

getchar();

return 0;

}

总结:

在C语言中:

int f(); //表示返回值为int,接受任意参数的函数

int f(void);//才表示返回值为int的无参函数

在C++中,

int f()和intf(void)具有相同的意义,都表示返回值为int的无参函数

C++更加强调类型,任意的程序元素都必须显示指明类型。

4. 三目运算符

下面一段代码在c编译器里通不过,不过在c++编译器里可以通过:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

int main()

{

int a = 10;

int b = 20; //返回一个最小数 并且给最小数赋值成3

//三目运算符是一个表达式 ,表达式不可能做左值

(a < b ? a : b )= 30;

printf("a = %d, b = %d\n", a, b);

system("pause"); return 0;

}

三目运算符在c编译器中返回的是一个变量的值。例如在上面返回的是10,对10进行赋值,自然出现错误。

三目运算符在C++语言是返回的“变量本身”---内存空间地址。

在c语言中做些许改变就可以达到相同的效果:

void main()//改进的C语言代码

{

int a = 10; int b = 20;

*(a < b ? &a : &b) = 30; //返回变量a的地址值,对地址值取值,可以对变量进行修改

printf("a = %d, b = %d\n", a, b);

system("pause");

}

结论:

C语言中的三目运算符返回的是变量值,不能作为左值使用,但是可以用作右值,如 int c = a < b ? a : b

C++中的三目运算符可直接返回变量本身,因此可以出现在程序的任何地方

需要注意的是:

三目运算符可能返回的值中如果有一个是常量值,则不能作为左值使用(a < b ? 1 : b ) = 30; 这句话即使在c++中也会报错。

5. bool类型

c++添加了新的类型,bool类型。

void main()

{

int a;

bool b =true; printf("b = %d, sizeof(b) = %d\n", b,sizeof(b));

b = 4;

a = b; printf("a = %d, b = %d\n", a, b);

b = -4;

a = b; printf("a = %d, b = %d\n", a, b);

a = 10;

b = a; //b还是等于1

printf("a = %d, b = %d\n", a, b);

b = 0; printf("b = %d\n", b); system("pause");

}

/**结果:

b = 1, sizeof(b) = 1a = 1, b = 1a = 1, b = 1a = 10, b = 1b = 0*/

结论:bool类型的大小是一个字节、只有0和1两个值,如果赋值不是这两者,结果还是1。

6. const

a. 有关于const的简单理解

关于const一些简单的理解:

const int a = 10; //a是常量(a所代表的内存块不能被修改)

const int *p; // p所指向的内存块是不可修改的

int * const p; // p是常指针(指针变量不能被修改,但是它所指向内存空间可以被修改)

const int *p;//

我们需要这么来理解 ;

int *p表示的是一个int型变量,不过该变量的地址存在p中,因此const修饰的是一个int型变量。这和const int a其实区别不大,因为*p等价于a。注意比较a和*p,两者都是代表变量,*p表示p是指针,p是指向变量的指针,*p代表的才是变量, 一个类似的例子是

void func(int (*p)[3]) 和 void func(int a[][3])

(*p)[3]和a[][3]所代表的东西在编译器看来都是一样的:

+ (*p)代表步长为3的一级指针,a[]代表的也是步长为3的一级指针

+ p代表的是二级指针,a代表的也是二级指针

同理我们看int * const p,const修饰的是p这个指针,因此该指针为常指针。

b. const在c和c++之中的不同

在c中const是一个冒牌货:

int main()

{

const int a = 10; int *p = (int*)&a;

printf("a===>%d\n", a);

*p = 11;

printf("a===>%d\n", a);

printf("Hello......\n");

return 0;

}

/**

a的值可以被修改

a===>10

a===>11

*/

C语言中const变量是只读变量,注意,是变量,有自己的存储空间。

在c++中情况大为不同:

#include <iostream>

using namespace std;

void main()

{

const int a = 10;

int *p = (int*)&a;

*p = 11;

printf("a = %d \n", a);

printf("*p = %d \n", *p);

system("pause");

}

/**

我们发现结果很令人吃惊:

a = 10

*p = 11

*/

解释:

C++编译器这么对const常量进行处理:

当碰见常量声明时,在符号表中放入常量。问题:那有如何解释上面的a和*p的不同?

编译过程中若发现使用常量则直接以符号表中的值替换

编译过程中若发现对const使用了extern或者&操作符,则给对应的常量分配存储空间(兼容C)

联想: int &a = 1(err) & const int &a = 10(ok)?

下面一段代码,在c和c++编译器中有不同的表现:

int main()

{

const int a = 1;

const int b = 2;

int array[a + b] = {0};

int i = 0; for(i=0; i<(a+b); i++)

{

printf("array[%d] = %d\n", i, array[i]);

}

printf("Press enter to continue ...");

getchar();

return 0;

}

/**

c中编译通不过,c++中却可以

*/

结论:C++中由const修饰的,是一个真正的常量,而不是C中变量(只读)。

c. C++中的const和#define的区别

总体来说,const int c = 5; ≈ #define c 5

C++中的const常量在与宏定义不同:

const常量是由编译器处理的,提供类型检查和作用域检查

宏定义由预处理器处理,单纯的文本替换

#include <iostream>

using namespace std;

void fun1()

{

#define a 10

const int b = 20;

//#undef a

}

void fun2()

{

printf("a = %d\n", a);

//printf("b = %d\n", b);

}

int main(int argc, char *argv[])

{

fun1();

fun2();

return 0;

}

/**

在func1中运用#define定义的a,在func2中仍然可以使用,但是用const定义的常量b在func2中却无法使用。

如何消除 #define a 10对后面的代码的影响呢?

我们可以使用#undef,她的作用是在该代码后面取消以前定义的宏定义,她的用法是 #undef + 之前已经宏定义的量,如

#define a 10

#undef a //该句后面预处理器不再用10提换a了

*/

7. 实用性增强

//C语言中的变量都必须在作用域开始的位置定义!!

//C++中更强调语言的“实用性”,所有的变量都可以在需要使用时再定义。

int main()

{

int i = 0;

printf("ddd");

int k;

system("pause");

return 0;

}

转自csdn lishuhuakai的博客

原文发布于微信公众号 - 程序员互动联盟(coder_online)

原文发表时间:2015-05-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏ml

关于如何来构造一个String类

  今天帮着一位大二的学弟写了一个String的类,后来一想这个技术点,也许不是什么难点,但是还是简单的记录一些吧! 为那些还在路上爬行的行者,剖析一些基本的实...

3445
来自专栏C语言及其他语言

数组

1、 一维数组的定义和使用 通过对前面知识的学习,我们已经知道如何定义和使用一个一个的各种变量,但总有不够用的时候。举个例子,我要记录一个班32个同学C语...

3838
来自专栏F_Alex

数据结构与算法(三)-线性表之静态链表

前言:前面介绍的线性表的顺序存储结构和链式存储结构中,都有对对象地引用或指向,也就是编程语言中有引用或者指针,那么在没有引用或指针的语言中,该怎么实现这个的数据...

592
来自专栏后端沉思录

hashCode、equals的使用

hash code、equals是Java用来比较对象是否相等,下面介绍一下自己在工作中对hash code、equals的使用. 首先介绍下String类中的...

622
来自专栏大前端_Web

js正则表达式(一)

版权声明:本文为吴孔云博客原创文章,转载请注明出处并带上链接,谢谢。 https://blog.csdn.net/wkyseo/articl...

874
来自专栏Python

Python正则表达式中的re.S的作用

在Python的正则表达式中,有一个参数为re.S。它表示“.”(不包含外侧双引号,下同)的作用扩展到整个字符串,包括“\n”。看如下代码: import re...

1725
来自专栏Java帮帮-微信公众号-技术文章全总结

第十二天 面向对象-构造方法继承this super【悟空教程】

1507
来自专栏Java学习网

Java变量类型转换规则与注意事项

Java变量类型对于每个从事Java开发工作的人员来说再熟悉不过了,正如你所知,Java的数据类型分为三大类:布尔型、字符型和数值型,而其中数值型又分为整型和浮...

2076
来自专栏每日一篇技术文章

Swift3.0 - 属性

743
来自专栏技术之路

c++虚函数注意事项

》在基类方法声明中使用关键字virtual,可以使该方法在基类及所有的派生类中是虚的 》如果使用指向对象的引用或指针来调用虚方法,程序将使用对象类型定义的方法,...

1738

扫码关注云+社区