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

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

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

1)指针

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

指针是什么?

指针是一个存放另外一个东西的地址的变量。指针是一个变量,把一个具有特殊作用的变量称为指针。它的特殊作用就是:存放另外一个东西的内存地址。也

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

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

*、&的使用

在声明语句中:

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

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

在使用指针变量时,

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


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

函数指针、指针函数 

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

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

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

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

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

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

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

typedef int (* func) (int x);

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


  1. typedef int (*func)(int arg); // 定义一个函数指针 
  2.  
  3. /* 一个函数指针的实现 
  4. * funcImpl就可以作为func的值进行赋值。 
  5.  */ 
  6. int funcImpl(int arg){ 
  7.     return arg; 
  8.  
  9. /*  
  10. * 声明一个函数,将函数指针作为函数call的参数 
  11.  */ 
  12. void call(func f){ 
  13.     for(int i=0; i<10; i++){ 
  14.         cout << f(i) << endl; 
  15.     } 
  16.  
  17. // 进行测试 
  18. int main(int argc, char* args[]) 
  19.     call(funcImpl); 

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

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


  1. function funcImpl(int num){ 
  2.     return num; 
  3. (function call(f){ 
  4.     if(f){ 
  5.         if(f instance Function){ 
  6.             for(int i=0; i<10; i++){ 
  7.                alert(f(i)); 
  8.             } 
  9.         } 
  10.      } 
  11. })(funcImpl); 

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


  1. interface Callback{ 
  2.     int doCall(int num); 
  3.  
  4. static void call(Callback callback){ 
  5.     if(callback==null) return; 
  6.     for(int i=0; i<10; i++){ 
  7.         System.out.println(callback(i)); 
  8.     } 
  9.  
  10. public static void main(string[] args ){ 
  11.     call(new Callback(){ 
  12.        public int doCall(int num){ 
  13.           return num; 
  14.        } 
  15.      }); 

在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中的回收机制是:采用分代回收算法对于不可达的对象进行回收。


  1. void fun(){ 
  2.     Menu* m1=new Menu();  // 显式声明对象 
  3.     Menu m2;              // 隐式声明对象 
  4.     this->menulist->push_back(m1); 
  5.     this->menulist->push_back(&m2); 
  6.  
  7. void showList(){ 
  8.     list<Menu*>::iterator iter=this->menulist->begin(); 
  9.     while(iter!=this->menulist->end()){ 
  10.         Menu* menu=*iter;  
  11.         cout << m->toString() << endl; 
  12.         iter++; 
  13.     } 

这段代码,在编译时,是没有问题的,也就是说从写法来讲,没有错误的。但是在执行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++程序员。

作者:螺 丝 钉

来源:51CTO

时间: 2024-10-03 22:00:24

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

Java程序员学习Flex和BlazeDS的十三个理由

在阐述Java程序员应当学习BlazeDS的13条理由时,我以一个假想的苏打分派 系统来展示如何让已有的Java程序转变为RIA应用.通过这个例子,我同时还会 讲解到BlazeDS在已有Java应用或新建Java应用中的多种不同用法. 理由 一:开源 Flex软件开发工具箱(SDK)的核心是个开源框架,专门用来开 发.维护那些在不同浏览器.不同操作系统下界面都相同的RIA应用.Flex发布 采用的是Mozilla公共许可证(Mozilla Public License).编译后的Flex应用 在

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

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

Java程序员学习流程

问题描述 对Java很感兴趣,现在在学j2se,想知道怎样才能成为一名合格的java程序员呢? 解决方案 解决方案二:我一直用的java,简单说说我的想法,仅供参考.我一开始学java的时候是看基础书籍,理解了基础知识后,我就进入公司开始做项目了.那时候懂得很少,在做项目的过程中自己去慢慢学的.老实说自己去看书真的没有在项目中得到的锻炼多.等有一定的项目经验后,有时候回过头来再看看这些书籍,理解就会加深很多.还有补充一点,等你在项目中遇到这样那样的问题,在你解决问题的过程中,你就会不知不觉地学会

Java程序员需要学习哪些基础知识?

一个合格的java程序员,必须需要牢固的基础,这样在未来接触新的知识的时候,才能快速吸收,基础不牢固的程序员,随时都会被新的知识和技术所淘汰,下盘不稳风一吹就倒,那么作为一个合格的java程序员应该具备哪些知识呢?

学习JavaFX Script,第一部分:针对Java程序员的JavaFX介绍

      原文地址:http://java.sun.com/developer/technicalArticles/scripting/javafxpart1/          JavaFX Script编程语言(以下称为JavaFX)有Sun微系统公司开发的一种declarative, statically typed(声明性的.静态类型)脚本语言.如Open JavaFX(OpenJFX)网站所述,JavaFX技术有着良好的前景,包括可以直接调用Java API的能力.因为JavaFX

阿里面试回来,想和Java程序员谈一谈

引言 其实本来真的没打算写这篇文章,主要是LZ得记忆力不是很好,不像一些记忆力强的人,面试完以后,几乎能把自己和面试官的对话都给记下来.LZ自己当初面试完以后,除了记住一些聊过的知识点以外,具体的内容基本上忘得一干二净,所以写这篇文章其实是很有难度的. 但是,最近问LZ的人实在是太多了,为了避免重复回答,给自己省点力气,干脆就在这里统一回复了. 其实之前LZ写过一篇文章,但是那篇文章更多的是在讨论"面试前该不该刷题"这个话题,而这篇文章将会更加聚焦在面试前如何准备,以及工作当中如何学习

java程序员的迷茫?

昨天在论坛上看见有人问毕业之后java程序员薪资能拿到多少?我看见后下意识的关注了,我是一个java程序员,刚刚毕业一年,我却感觉我的java水平没有什么可以迅速提高的了(我个人迷茫的感觉吧),所以我狂妄的在下面回帖精通java 可能被其他的已经看到另一个风景的java程序员来说,我的狂妄很幼稚,不过我周围能接触到的已经有十年以上的程序员在java上的水准已经让我能看的清摸得着了,不妄自菲薄,但从语言角度来看由于,刚毕业对java的热度还很足所以颇为下功夫,与换过多门语言的老程序员来说,但从语言

JAVA程序员必读:基础篇(2)

程序|程序员 JAVA程序员必读:基础篇时间:2001/09/13 13:31作者:ZSC 太平洋网络学院 二.面向对象编程 如果你以前从来没有使用面向对象语言,你需要在开始编写JAVA代码之前先理解这个概念.你需要理解什么是对象.什么是类.对象和类的关系怎样以及使用消息怎样在对象之间进行通讯.本教程的前面部分将描述面向对象编程的概念,而后面的教程将教你怎样将这个概念编成代码. 2.1什么是对象 对象是一些相关的变量和方法的软件集.软件对象经常用于模仿现实世界中我们身边的一些对象.对象是理解面向

JAVA程序员必读:基础篇(1)

程序|程序员 JAVA程序员必读:基础篇 时间:2001/09/13 13:31 作者:ZSC 太平洋网络学院 JAVA是有SUN公司开发的新一代编程语言,它可以用在各种不同的机器.操作系统的网络环境中进行开发.不论你使用哪种浏览器或者使用哪种操作系统(Windows.Unix等等),只要浏览器支持JAVA,你就可以看到生动的主页.JAVA正在逐步成为Internet应用的主要开发语言,它彻底改变了应用软件的开发模式,为迅速发展的信息世界增添了新的活力.所以作为Internet应用的开发技术人员