Java程序员学习一天半C++的感想

  大学期间,学了一学期的C语言,当然包括学习数据结构时,用的也是C语言。当时刚刚接触计算机,对于编程更是一无所知。上课学习学习,偶尔会照着书上敲一下代码。大二下学期,就丢掉了不用了。最近由于工作的需要,要使用Java Native Interface,所以就学习了1天半的C++,对C++有了一点点的了解,写一下自己的理解。

一天半时间,也学不多少东西,我主要就搞明白了下面几个问题:

1)指针

  这么多年了,还记得在C语言时,最难以理解的,应该属于指针了。还记得谭浩强的那本C语言书(书名是啥,真的忘了。不过作者谭浩强老师,绝大多数的中国开发人员应该都知道的),前面大部分用的都是基本数据类型(也就是Java中的原生类型),后面一小部分突然讲起了指针,当时立马就 蒙 圈了。不过好在最后还是理解了指针,虽然后来又忘记了。

指针是什么?

指针是一个存放另外一个东西的地址的变量。指针是一个变量,把一个具有特殊作用的变量称为指针。它的特殊作用就是:存放另外一个东西的内存地址。也就是说指针变量的值代表了一个地址,这个地址是另外一个东西的。那另外一个东西是什么呢?就是我们说的对象(或者实例)。在C++中,还为这个对象起了一个别名:引用。

总结一下就是:指针变量指向一个对象(或者引用)。

*、&的使用

在声明语句中:

*表示声明的是指针,&表示引用。

这里说的声明语句,可以是变量声明,也可以是函数声明中。在函数声明中,返回值、函数名、参数都可以声明为指针。

在使用指针变量时,

(* 变量名)代表取对象。(& 引用)代表取指针。

void personTest(Person * p){
    if(p!=NULL){
        p->setAddress("Bei Jing, Hai Dian"); // 采用指针的方式赋值
        (*p).setName("Fang JiNuo");    // 采用对象的方式赋值。
        (*p).setAge(23);
        printf("show info:\n%s\n", (*p).toString());
        delete p;
        p=NULL;
    }
}

函数指针、指针函数

这个两个词八个字,不知道有多少人载了跟头,其实很好理解了。中国人说话,多以叙述的方式为主。这个两个词都是省略句,不过省略的是助词。

函数指针全名是:函数名是指针。

指针函数全名是:返回值是指针的函数。

这两个中,指针函数很容易理解了:

char * func(char[] p);这个函数就是一个指针函数。

函数指针,函数名是指针。指针也是变量,所以就可以理解为:函数名是变量。

下面是一个函数指针变量的声明:

typedef int (* func) (int x);

然后把这个变量作为另外一个函数的参数来使用:

typedef int (*func)(int arg); // 定义一个函数指针

/* 一个函数指针的实现
* funcImpl就可以作为func的值进行赋值。
 */
int funcImpl(int arg){
    return arg;
}

/*
* 声明一个函数,将函数指针作为函数call的参数
 */
void call(func f){
    for(int i=0; i<10; i++){
        cout << f(i) << endl;
    }
}

// 进行测试
int main(int argc, char* args[])
{
    call(funcImpl);
}

程序执行结果是,打印出0到9。

这个函数指针与下面JavaScript的代码有同样的作用:

function funcImpl(int num){
    return num;
}
(function call(f){
    if(f){
        if(f instance Function){
            for(int i=0; i<10; i++){
               alert(f(i));
            }
        }
     }
})(funcImpl);

当然了与下面的Java代码代码也是一样的:

interface Callback{
    int doCall(int num);
}

static void call(Callback callback){
    if(callback==null) return;
    for(int i=0; i<10; i++){
        System.out.println(callback(i));
    }
}

public static void main(string[] args ){
    call(new Callback(){
       public int doCall(int num){
          return num;
       }
     });
}

在C#中,它还有另外一个名字,delegate。

其实它们都是传说中的钩子函数callback。

2)头文件、#include

在大学时,没有写过头文件,也没有看过头文件。所以头文件对我来说,一直是个谜。不过在学习了Java、C#后,就自然而然的会将#include 头文件理解为import、using等。

那么头文件中,会写什么呢?

一般来说,会将声明(类中的字段、方法的声明)写在.h文件中,将方法的实现,写在cpp文件中。以此来达到接口与实现的分离。其他地方使用#include时,就只会看到.h文件中的声明,看不到具体的实现。

另外要说的是#include的两种方式。 例如#include <xxxx.h>、#include “xxxx.h”。这两种方式,还是有区别的,<>方式是先从系统目录下找.h文件,” ”则是先从用户目录下去找.h文件。有点类似于Java中ClassLoader了,默认采用委托加载,也可以使用子类优先方式进行加载。

创建实例与回收

在C语言中,声明一个变量,可以直接使用声明的方式、也可以使用molloc的方式。

在C++中,又加入了一种new的方式,这种方式的写法与Java中是一样的。


创建


释放


声明(隐式):创建的是对象本身,而不是指针


隐式释放,不需要通过写代码。因为声明的对象在栈内,出栈后自动释放


molloc(显示):该方法用于分配内存,返回值是指针


使用free()进行释放


new :分配内存,返回值是指针


使用delete 进行释放

Molloc、new 分配内存后,返回值都是指针。且分配在内存中Heap区,不会自动释放,所以需要使用free、delete进行释放。

另外在使用feee、delete后,最好是将指针的值设置为NULL, 因为free、delete只是释放了对象占用的内存空间,而指针的值仍然是对象在被释放前占用空间的首地址。

这与Java是不同的,Java能够自动的进行回收。对象设置为null即可。Java中的回收机制是:采用分代回收算法对于不可达的对象进行回收。

void fun(){
    Menu* m1=new Menu();  // 显式声明对象
    Menu m2;              // 隐式声明对象
    this->menulist->push_back(m1);
    this->menulist->push_back(&m2);
}

void showList(){
    list<Menu*>::iterator iter=this->menulist->begin();
    while(iter!=this->menulist->end()){
        Menu* menu=*iter;
        cout << m->toString() << endl;
        iter++;
    }
}

这段代码,在编译时,是没有问题的,也就是说从写法来讲,没有错误的。但是在执行showList()时就会出现空指针异常。原因如下:

在fun()中,创建的m1在heap中,不会自动的释放,创建的m2,在stack中,会自动的释放,当fun执行完毕时m2对象实际已经不存在了。然后执行showList()时,变量到m2对象时,肯定空的了,list中存储的m2的指针,已经成为野指针了。

3)namespace

命名空间,在大多数语言中都有的。他们的作用都是为了区分。

//定义命名空间

namespace ns{

// your code

}

// 导入命名空间:

using namespace std;

// 使用命名空间:

std::xxxx

4)#define 、typedef

typeof 是为已有类型取别名。在编译阶段有效,由于是在编译阶段,因此typedef有类型检查的功能。

#define是宏定义,发生在预处理阶段,也就是编译之前,它只进行简单而机械的字符串替换,而不进行任何检查。#define不只是可以为类型取别名,还可以定义常量、变量、编译开关等。

5)操作符重载

学习C#时,知道可以对已有操作符进行重组,也就是赋予操作法新的功能。但是在C#中,我们很少这么做。Java中虽然没有语言级别的支持,但是Java中字符串拼接使用的+,其实就可以看做是操作符的重载。

在了解到C++中有操作符重载后,哦,原来这一点,C#是借鉴C++的呀。另外C#中还保留了struct。说到struct,再提一点,struct完全可以理解为C语言中的类。

C++ 中则使用了大量的操作符重载。具体的怎么去定义操作符重载,用到的时候再说吧。

  一天半时间,了解的东西真的不多,都是最基本的。虽然我也知道C++中的字符串拼接没有Java、JavaScript那么随意那么任性。但是这些不属于难点,所以我认为不需要再提了。

  最后,开一个玩笑,不懂JavaScript的Java程序员不是一个好的C++程序员。不懂Java的JavaScript程序员也不是一个好的C++程序员。

时间: 2024-10-10 22:41:34

Java程序员学习一天半C++的感想的相关文章

Java程序员学习之路

1. Java语言基础 谈到Java语 言基础学习的书籍,大家肯定会推荐Bruce Eckel的<Thinking in Java>.它是一本写的相当深刻的技术书籍,Java语言基础部分基本没有其它任何一本书可以超越它.该书的作者Bruce Eckel在网络上被称为天才的投机者,作者的<Thinking in C++> 在1995年曾获SoftwareDevelopment Jolt Award最佳书籍大奖,<Thinking in Java>被评为1999年Java

聊聊阿里社招面试,谈谈“野生”Java程序员学习的道路

阿里社招面试都问什么? 和之前一样,文章一上来,我们先来谈谈阿里的社招面试都问什么,其实这个话题并不是什么秘密,所有来阿里面试过的同学,都能回答一二. 两年前的时候,笔者在文章里是这么回答的. 这个是让LZ最头疼的一个问题,也是群里的猿友们问的最多的一个问题. 说实话,LZ只能隐约想起并发.JVM.分布式.TCP/IP协议这些个关键字,具体的问题真的是几乎都没记住.而且就算LZ记住了,也告诉你了,你也背会了,但LZ觉得,在面试中,你被问到一模一样问题的可能性依然很小. 甚至,就算你运气好被问到了

【Python】Java程序员学习Python(五)— 函数的定义和使用

不想做一个待宰的羔羊!!!!要自己变得强大.... 函数的定义和使用放在最前边还是有原因的,现在语言趋于通用,基本类型基本都是那些,重点还是学习对象的使用方法,而最根本的还是方法的使用,因此优先介绍,方法的目的还是重用和封装 一.方法的定义 方法的定义使用关键词def来定义,定义格式如下: def 方法名(参数定义): 方法体 方法名:方法名的规范同变量名规范一样 参数定义:比较复杂,后面会进行讲解 冒号:这个类似于Java的{},必不可少 方法体:方法实现的功能在此定义即可 简单的例子: #定

Java程序员学习的6个小技巧

Java程序员学习的6个小技巧 知识改变命运,对于Java程序员来说,技术不断更新,只有及时充电,才能不被市场淘汰.北京Java培训机构分享Java程序员学习的6个小技巧兄弟连IT教育作为全国最大的PHP培训机构,迄今已有10年的教育历史,7大特色课程:PHP教程.安卓培训.JAVAEE+大数据.UI设计.HTML5培训.云计算架构师,全栈工程师培训,在目前IT市场特别火,每门课程都由名师牵头,以认认真真的态度做教育,培养的学员过万,在学员心中树立了良好的口碑. 1.一定要看书 现在学习Java

java程序员学习c++的感觉

大学编程课期间, 学了一学期的C语言,当然包括学习数据结构时,用的也是C语言.当时刚刚接触计算机,对于编程更是一无所知.上课学习学习,偶尔会照着 书上敲一下代码.大二下学期,就丢掉了不用了.最近由于工作的需要,要使用Java Native Interface,所以就学习了两天半的C++,对C++有了一点点的了解,写一下自己的理解. AD: 两天半时间,也学不了多少东西,我主要就搞明白了下面几个问题: 1)指针 这么多年了,还记得在C语言时,最难以理解的,应该属于指针了.还记得谭浩强的那本C语言书

【Python】Java程序员学习Python(二)— 开发环境搭建

巧妇难为无米之炊,我最爱的还是鸡蛋羹,因为我和鸡蛋羹有段不能说的秘密. 不管学啥,都要有环境,对于程序员来说搭建个开发环境应该不是什么难题.按顺序一步步来就可以,我也只是记录我的安装过程,你也可以滴. 一.准备Java环境 我已经说过了,其实我是一个Java程序员,所以学习过程中会有很多Java相关的内容和对比.先介绍下我的基本情况 jdk1.8 eclipse即可,版本最新的 怎么安装java,配置环境变量什么的,我都不会再说了,我这不是小白教程,我相信具备一定的能力. 二.准备Python环

写给自己的Java程序员学习路线图

如下是我做开发这几年经常使用一些技术和工具,当然这些技术也都是需要加强的(有些是我一直使用的,不过不深入,有些内部的原理等等不是很清楚) 前端部分: 1)HTML:网页的核心语言,构成网页的基础 2)CSS:使网页更加丰富多彩灿烂的利器 3)JavaScript:使网页动起来的根本,加强了网页和用户之间的交互 4)HTML DOM:换一种更加形象化的角度来看待网页,让我们更加方便的控制网页 5)HTML BOM:与浏览器交互不可或缺的工具 6)JavaScript库,主要是:jQuery及其插件

面试?顺谈Java程序员学习中各阶段的建议

第一个问题:阿里面试都问什么? 这个是让LZ最头疼的一个问题,也是群里的猿友们问的最多的一个问题.说实话,LZ只能隐约想起并发.JVM.分布式.TCP/IP协议这些个关键字,具体的问题真的是几乎都没记住.而且就算LZ记住了,也告诉你了,你也背会了,但LZ觉得,在面试中,你被问到一模一样问题的可能性依然很小. 甚至,就算你运气好被问到了,你也照着背下来了,也不一定就能对你的面试起到正面的作用,因为面试官万一多问一句,你可能就露馅了,那还不如干脆点说不会更好. LZ参加的是阿里的社招面试,而社招不同

普通Java程序员学习使用的6个JDK内建工具

与你的问题不同,我认为软件工程主要是用来解决问题的.有些博客认为“每个小孩都应该学习编程”,“你认为学数学只是玩玩而已?如果你有看过我的HTML5调试器的话,你会发现我是一个程序员,但我做的工作远不止数学这些”. 上面两者都同意一个观点,软件工程不只是用计算机语言写的一些只言片语.软件解决的问题诠释了程序员的价值. 解决问题的最终进展来自科学.强化清晰的头脑和我们一路以来使用的工具. 你有没有留意过那些 JDK 安装附带的工具?既然那些大牛同意把那些工具加到 JDK 里,应该是有用的. 因此,在