【C->Cpp】深度过渡由C迈向Cpp(1)

目录

(一)第一个Cpp程序

(二)命名空间 

 (三)输入输出流


        本篇文章针对有一定C语言基础的读者,如果你有一定的C语言基础,那么你可能会对本文有更好的理解。

        C->Cpp(由C迈向Cpp)这个栏目,就是在为Cpp的学习打下坚实的基础。

C与Cpp有什么关系呢? 具体来说:

        Cpp包含了C的绝大部分语法,也就是说Cpp兼容C的大部分语法。

                (<iostream.h>这个头文件兼具<stdio.h>这个头文件的作用,这就是众多例子中的一个)

        Cpp针对C的缺陷,在C的基础上增加了许多用法和规则。

                (仅从关键字上,Cpp就比C多了一倍,这也是一个例子)

        当然,这只是我的个人理解,并不能涵盖Cpp对于C的改进的良苦用心,希望你能在学习中感受到Cpp的强大与魅力。

 

(一)第一个Cpp程序

        在这里你是不是闻到了熟悉的味道——在我们刚刚接触C语言的时候,似乎也是以第一个C语言程序开始的。

#include<stdio.h>
int main()
{
    printf("hello world\n");

    return 0;
}

        说实话,还是有些感慨的:

        从一个到另一个,长长的路,慢慢的走。


 


         既然要认识Cpp,当然离不开第一个Cpp程序:

​
#include<iostream>
using namespace std;
int main()
{
    cout << "hello world\n" << endl;

    return 0;
}

​

 这两个简单的程序的作用是一样的,从这两个程序的对比中,我们们可以发现:

        cpp的头文件,头文件下方的一句代码,标准输出打印完全不同与C,在这里,我们就不得不引入一些新的概念了,这些概念的引入,是有原因的。

         其实,原因是显而易见的:

                Cpp在构建自己的大厦之前,必须先要补一补C语言的不足,引入这些概念的核心目的是为了解决C的一些不足。

       


(二)命名空间 

我们先考虑两个场景。


          场景一:

        我们编译下方的代码,却发现报错了

#include<stdio.h>
#include<stdlib.h>
int rand = 0;
int main()
{
	printf("%d",rand);
	return 0;
}


        场景二:

        假设,你与同事合作共同进行一个项目的代码的编写, 你们分别完成不同的模块,但不幸的是,你们缺乏沟通,结果导致你们的模块在组合后出现了命名冲突。


 名字冲突:

        我们自己定义和库里面的名字冲突;

        项目组,多个人之间的名字冲突。

        这样的错误在C语言中是无法挽回的,唯一的办法只有一人妥协,改掉冲突的名字,但是这很费工夫。

         C语言中有域的概念,域又分为局部域和全局域;在局部域里面的变量是局部变量,在全局域的变量是全局变量。

        对于同名变量,在局部域内部优先使用全局变量,这是已知的C语言的知识。其实也是C语言在解决同名问题的一个规定。

        在Cpp中,你可以忽略局部域内部定义的变量a,正常使用定义在全局域的一个重名的变量a。我们引入域作用限定符(::);

        :: 操作符左侧是特定的域,右侧是变量。 

        它的作用是在操作符左侧的域中寻找操作符右侧的变量。


#include<iostream>
int a = 10;
int main()
{
	
	int a = 1;
	printf("%d\n",a);//在默认情况下,优先使用全局变量a = 10;
	printf("%d\n",::a);//在域作用符左侧不写任何域,表示在全局域中找变量a = 1;
	return 0;
}

 ::左侧不写任何内容,表示在全局去找变量a


         Cpp对于重命名的局部和全局变量,用::操作符来解决冲突,而C回避了这一问题。

        这就是Cpp相对于C的优势。

        命名空间就是与此相似:

        命名空间——命名空间域,只影响使用,不影响生命周期。


 命名空间把两个重名的对象放在了两个不同的域中,这样就不存在重名的问题了;

        那么,在需要的时候,如何从命名空间中找的需要的变量呢?

        有三种方法: 

1.在展开的命名空间中找,对应的代码是:

using namespace std;

2.提前把需要的放出来,代码如下:

//比如说,需要cout 和 endl;
//就可以提前把这两个的定义找出来

using std::cout;
using std::endl;

 3.直接指定需要的特定位置的变量,代码:

//比如我们要打印hello world;
//在使用cout 和endl的时候在找出来;

std::cout << "hello world" << std::endl;

        第一种用法对应的是——全局展开;后两种用法对应的是——指定命名空间访问。

         一般是不建议全局展开的,一旦全局展开,你定义对象的时候,必须避开可能重名的可能。这样就白费了Cpp的命名空间这一功能的苦心了。

         当两个人的代码中定义有重名的函数,变量等时,可以把两个人的变量,函数等分别放在两个命名空间中,在需要使用的时候再拿出来,就解决了命名冲突的问题。


多个文件的命名空间可合并:

        对于多个文件的同名命名空间,编译器会把多个文件中的同名命名空间合并,作为一个命名空间来使用。

编译器关于命名空间的查找顺序

        编译器默认查找:

        a,局部域查找

        b,全局域查找

        c,展开的命名空间查找

        对于全局已经存在的定义,如果将命名空间的同名定义展开,则会报错。最好的做法就是每次使用的时候指定命名空间。

        全局: 用  “ ::”  指定

        命名空间:用  “名称::”  指定

         此外,如果多个两个即以上的不同命名空间展开,其中定义有同名的对象,那么编译器也会报错:重复定义的对象。

对展开命名空间的理解:

         注意展开命名空间并不是说命名空间的对象就变成全局对象了,而是说,可以在展开的命名空间中找寻变量或者函数的定义。


 (三)输入输出流

Cpp中的I/O流是用于输入和输出数据的机制。它允许程序通过不同的设备(如键盘、屏幕、文件等)与外部环境进行交互。

Cpp中的I/O流分为两种类型:输入流和输出流。

输入流用于从外部设备读取数据,输出流用于向外部设备写入数据。

Cpp中的I/O流库提供了多个流类,每个流类都有相应的成员函数和操作符重载,用于实现对流的操作。

流插入:  <<

流提取:  >>

在初始阶段,我们先理解

cout << "hello world\n" << endl;

 这段代码是不是就像一个河流,<< << 表示流向;endl其实就是‘\n’;

        cout的优势是自动识别数据类型,与printf不同,printf需要由一定的格式符 “%d”等,但是cout可以自动识别类型。

#include<iostream>


int main()
{
	int a = 40;
	std::cout << "hello wrold" << std::endl;
	std::cout << "   "<< "heomk " << 'd' << " "<< a << std::endl;
	float b = 8.6;
	double c = 5.9;
	std::cout << b << "  " << c << std::endl;
	
	return 0;
}

 

printf:

        需要指定格式,可以一个次操作打印多个类型;

printf("%d%c%f%lf",(int)a,(char)b,(float)c,(double)d);

cout:

        自动识别格式,但只能一次打印一种类型。

                (两个<< << 之间只能写一种数据类型:)

std::cout << "   "<< "heomk " << 'd' << " "<< a << std::endl;

他们各有优势。

        重要的是Cpp可以兼容C。

        其实,在我看来,我们完全可以按照自己的意愿,选择使用cout与printf,怎么舒服怎么来。 


完~ 

未经作者同意禁止转载

#include "mylogin.h" mylogin::mylogin(QWidget *parent) : QDialog(parent) { this->init_ui(); connect(this->bnt_login, &QPushButton::clicked, this, &mylogin::do_login); connect(this->bnt_register, &QPushButton::clicked , this ,&mylogin::do_enroll); } mylogin::~mylogin() { } void mylogin::init_ui() { this->setFixedSize(QSize(600,350)); this->setWindowTitle(tr("岑超升")); this->setWindowIcon(QIcon(":/src/1.png")); this->lb1 = new QLabel(); this->lb2 = new QLabel(); this->lb3 = new QLabel(); this->lb1->setFixedSize(QSize(560,200)); QPixmap pic; pic.load(":/src/2.png"); //this->lb1->setPixmap(pic.scaled(this->lb1->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); this->lb1->setPixmap(QPixmap(":/src/2.png")); this->lb2->setText(tr("用户名:")); this->lb3->setText(tr("密 码:")); this->usr_name_le = new QLineEdit(); //这两个参数后面传入信号中去,然后emit发射出去 this->usr_pass_le = new QLineEdit(); this->usr_pass_le->setEchoMode(QLineEdit::Password); this->bnt_login = new QPushButton(tr("登 陆")); this->bnt_register = new QPushButton(tr("注 册")); this->hb1 = new QHBoxLayout(); this->hb2 = new QHBoxLayout(); this->hb3 = new QHBoxLayout(); this->hb1->addWidget(this->lb2); this->hb1->addWidget(this->usr_name_le); this->hb2->addWidget(this->lb3); this->hb2->addWidget(this->usr_pass_le); this->hb3->addWidget(this->bnt_login); this->hb3->addWidget(this->bnt_register); this->vb1 = new QVBoxLayout(); this->vb1->addWidget(this->lb1); this->vb1->addLayout(this->hb1); this->vb1->addLayout(this->hb2); this->vb1->addLayout(this->hb3); this->setLayout(this->vb1); } void mylogin::do_login() { emit sig_login(usr_name_le->text(), usr_pass_le->text()); //需要把这里输入的账号密码信息发送到myapp那去,用到的函数是emit //需要自定义一个信号,sig_login //这个槽函数能够发出信号 } void mylogin::do_enroll() { emit sig_enroll(); }用C++语言解释并注释每行代码的语法
06-09
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水墨不写bug

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值