代码改变世界

学习Objective-C--第一天

2011-06-10 14:49  Paul Wong  阅读(73545)  评论(33编辑  收藏  举报

前言:

  在这里,翻译Dan WalkerLearn Objective-C 这个系列作为我学习Objective-C的开始,由于第一次翻译技术文章,欢迎指正……

教程详细:

      技术:Objective-C    难度:初学者     完成时间:30-60分钟

  欢迎步入我的有关有趣的语言Objective-C的学习系列,虽然本系列的文章不多,然而我的目标是带你从零接触Objective-C到最终自信地使用它进行应用程序的开发。这可不是一件急于求成的事情哟,所以呢,大家别漫不经心地快速浏览这些基础知识就走开,我们即将给出并不是是空洞的理论,而是提供确保能运行的代码及更好的实践。好吧,让我们开始吧。

什么是Objective-C?

  如果你在阅读这个系列,我估计你已经知道了,但对于那些还不知道的同鞋,不必担心,在这部分结束的时候,你会对它有一个由里到外的了解。

  Objective-C是一门基于C语言的面向对象语言,它在现代计算机的主要作用于Mac OS X作为桌面语言以及作用于iPhone OS(亦称:iOS)。它原是NeXTSTEP 操作系统的主要语言,NeXTSTEP OS随后被苹果公司收购,并派生出Mac OS X,所以这可以很好地说明今天的苹果操作系统和它有异曲同工之妙。

  由于Objective-C是C语言的一个严格超集,所以我们可以在Objective-C文件里自由地使用C语言并会顺利编译通过。因为任何Objective-C的编译器会将C代码编译过去,也就是说,我们拥有通过Objective-C实现C的面向对象能力。

  如果你对这点的理解有困惑的话,那就这理解吧:C能做的,Objective-C都能做,但反过来不成立。

我需要什么?

  在这系列文章里,我们不会把重点放在如何编写iPhone应用程序上,相反,我们将更专注于语言本身,理由是我们需要的是一个带有编译器的Mac,例如GCC。如果你已经安装了苹果公司的开发工具(Xcode,Interface Builder等),这意味着GCC已被安装了。否则,我们可以苹果开发者网站以获得免费下载。

  至于开始的先决条件,我并不希求你有一个完备的计算机专业背景,当然,一些基本的编程知识以及C语言基础会让你学起来更容易。如果你没有太多的编程经验,也不必担心,你完全可以及时的补回来。

  如果你正用Windows操作系统(这看起来不大可能,因为这系列是针对iPhone开发者的),当然你仍然可以用一些编译器编译Objective-C,例如CygWin或是MinGW。虽这系列是迎合Mac用户,但当你在用Windows编译Objective-C时,遇到任何困难可以留言,看看我能不能帮到你?

编译你的代码

  在你看到你代码可以运行之前,你需要把它编译成能够执行的东西哟。希望你现在已经准备好了GCC,这样编译是很简单的,仅仅是一句命令而已。

附言:

编译是一个将高级语言(例如Objective-C或PHP)翻译成低级机器编码的一个过程,以便让计算机执行。

  所有我们看到运行在Mac操作系统的程序,是由一系列展示给我们的GUI或是用户界面的指令组成。然而这与用鼠标互动,也就是我们都很熟悉的GUI程序相反,这可能是直接通过基于文本的终端或命令行发出指令到操作系统。

这命令行程序在Mac操作系统里被称作终端,可以在Applications->Utilities里找到。好吧,现在打开终端(你也可以在Spotlight里搜索到)。为了妥善的使用终端,有几个基本命令你是应该要了解的。其中一个最重要的命令是cd,它代表”改变目录“的意思。也就是说这命令允许我们改变终端读取系统文件的目录。在我们告诉终端要编译的文件的地址之前,我们是无法让终端去编译我们的文件的。然而,为了切换到所需要的目录,你可以使用完整的路径,例如:

1. cd /Users/MyName/Desktop/Test

同样,你也可以用相对路径,在某些情况下先键入一个单个文件夹的名称。例如,当你选择了桌面的文件夹,你便可以输入:

1. cd Test 

来取得这个Test文件夹。

如果你想知道你当前的目录,这最近的文件夹名称是显示在光标之前的文件夹名称(即你要键入的光标处)。例如,你的提示是:Dan-Walkers-MacBook:Desktop iDemonix$ .这样我就可以预想到我在桌面这里。如果你没有确定,你也可以键入pwd,这样就可以显示出你当前位置的绝对路径了。

如果你想列出当前文件夹的文件和文件夹,要用列表命令ls。最后,如果你想跳跃到父目录的话,可以键入"cd.."。所以,当我们在Test文件夹(这文件夹在桌面),并且我们想转到桌面文件夹,这时可以键入cd.. 来转到父目录上。如果我们想转到根目录上,我们可以键入cd../.. ,这样就可以到达两者的平衡。然而作为另一种选择,我们可以在任何的目录下使用cd~转到根目录。

当使用终端程序,编译如下:

1. gcc inputfile.m -o outputfile  
 
  你很可能已经猜到它是怎样工作的了:inputfile.m包含着我们的代码(.m是Objective-C文件的扩展名),-O 告诉gcc我们想执行那些被我们指定下一步,就像上面例子中的outputfile。为了在编译后跑起来,我们可以简单的键入:
 
1. ./outputfile  
   
   在你编译时,编译器可能会报各种各样的错误,通知或涉及到你代码的语法的一些警告。编译时产生的错误可以被理解为“编译时”错误,而这往往是发生在你编写应用程序时(特别是当你的代码编译不过, 是因为你不小心把单个字符放在错误的地方或是忘了在语句结束的地方加上分号)。编译同样也比较耗时,特别是你你长长的代码是由多个文件组成的,呵呵,也许会让人觉得这是一个乏味的体验。事实上,经常看到一个普通的程序员和一个蓬头垢面的T恤男调侃:“我没有懈怠,只是我的代码正在编译。”

 

基础知识

   Objective-C这语言本身并不难学。一旦你掌握了这些基本规则,你就可以很轻松地学下去。你需要你对C语言基础知识有一个比较好的理解,接下来的教程会比较多的涉及到这方面的知识。

  好吧,让我们看看一个很基本的C语言程序吧:

1. #include <stdio.h>   
2. int main(){   
3.     printf("Hello World\n");   
4.     return 0;   
5. } 

当你运行上面程序的时候,你会看到"Hello World”,并退出。

附言:

  是不是对"return 0”的声明感到好奇?这是因为我们要告诉编译器Main()函数将会返回一个integer类型,也就是这里最后返回的整数常量'0’。按照习惯,返回’0’信号是为了告诉程序在没有任何错误的情况下停止执行。

  为了亲身体验一下,先启动Xcode并新建一个新的Objective-C类。删除所有Xcode默认生成的代码,然后把上面的代码粘贴到Xcode里。这样你就可以用终端去编程你的代码了。打开终端,更改本地文件的保存位置,如果你想保存在桌面,你只需要键入cd desktop ,这样终端就可以从你桌面上读取文件了。接着,键入下面的命令:

1. gcc program1.m -o program1  

 

你的程序应该顺利编译,好吧,运行它吧,只需要键入下面命令:

1. ./program1 

 

然后按回车。

  太棒了,但竟然发生了什么呢?嗯~,我们首先引入了一个管理标准i/o(输入输出)函数(如printf())的stdio库。接着,我们创建一个可以返回int 或integer(没能小数点的)的Main函数。然后我们使用printf()函数向终端输出“Hello World”。而这个 \n 是换行的意思。最后,我们返回0(严格的说是返回一个整型),它告诉系统一切正常。我们使用Main是为了告诉程序一个执行入口。

  到目前为止,看起来还是蛮简单吧:我们想写一些东西到终端,所以,我们就引入一个带文本输入的函数库,然后,我们从这个库里面使用一个写文本函数。试想一下,这就像是一个图书馆,而printf()就是里面的一本书籍。

变量

  我们继续,现在我们要讲变量了。我们应用程序需要的基础的东东之一是临时存储数据,我们是用变量实现的,它是一个可容纳多种可以用多种方式操作的数据的容器。我们用变量来存储各种数据,但我们要先告诉编程器存在里面的是什么类型的数据。以下是一些最常重要的变量,你应该要掌握的哟:

  • int ---用来存储整数的(就是没有小数点的数)
  • char---用来存储字符
  • float---用于存储带小数的数字
  • double---和float相似,但是双精度的

  当我们不使用变量的时候,我们经常使用常量。常量是不会改变的:我们总能预知它的值是什么。如果我们把两常数关联在一起,这样就得到一个常量表达式,这说明,这表达式的结果是我们知道的。例如:

1. 123 + 2 = 125  

 

大家都知道这个常量表达式:123+2是等于125 的,不管什么情况下都是。如果我们把一个常量换成一个变量,这新的表达式是这样的:

1. 123 + i = ?  

 

  因为 i  是一个动态的变量,所以我们并不能预知这个表达式的值。当我们改变 i 的值就可以得到不同的结果。呵呵,这应该让你知道变量是如何工作的了吧。

  还有一点,我们需要知道如何把变量(如"Hello World”)显示出来,我们仍然要用printf()函数,除此之外,这次还会有一点点小改动:

1. #include <stdio.h>   
2. int main(){   
3.     int someNumber = 123;   
4.     printf("My number is %i \n", someNumber);   
5.     return 0;   
6. }  
 
  上面,我们已经告诉了printf()函数我们整数显示的位置,然而它又是怎样找到这位置的呢?这和很多语言不同,例如PHP,你可以把变量放在文本里。
  然而我们并不仅仅限制只有一个变量出现在printf()函数里,它可以接受多个用逗号分隔的变量,所以呢,我们可以通过更多在规格化文本里的标记。如上,我们使用了 %i 作为一个转化标记,因为我们使用了一个整型。其他的变量也有它各自的格式说明符哟:
  • %i---integer
  • %f---float
  • %e---double
  • %c---char

   还有一点我想再谈谈的是char类型,一个char类型只能允许处理一个字符,这样的规定是有意思的,然而我们需要一个文件字符串时,是不能直接实现的。为了满足这样的需求,我们用字符数组来解决。

    假设现在有一条11个字符的句子(像"Hello World”---别忘了空格字符哟),一个字符串就像11个字符粘合在一起的串。这意思着,这字符串的整体代表"Hello World”,然而char[0]代表'H’。在方括号里的值代表下一个字符,因为我们是从0开始的。请记住了哟,在阵列之中,通常是以0开头的,而不是1。

条件

  当一个程序需要作出判断时,我们是以条件为前提的。在没有条件的情况下,每次你运行你的程序时,它就像播放电影一样,每次都一样。通过基于变量的判断,输入或别的什么,这样我们就可以让程序有所变化--这比用户输入一系列号码或是点击一按钮简单10倍。

    条件分为好几种,但现在我们要学习的是最普通最基础的:if 语句。顾名思义,if 语句是检查某样东西是否为真,然后执行不同的相对情况。例如:

1. #include <stdio.h>   
2. int main()   
3. {   
4.     if(1 == 1) { // This is always true   
5.         // Do some stuff here   
6.     }   
7.  
8.     return 0;   
9. } 
 
  如果1是等于1,这样就执行括号之间的。也许,你会为用两个等号(==)而感到不解。使用==是一种平等的操作符,以检查这两个东东是否一样。然而,我们使用一个等号(=),这样就意思着我们试图着给另一个赋值了。
  以上,既然1是等于1的,这无论如何都会执行括号里面的代码。但如果我们想在if为假的时候做点什么,这就需要 else 语句了,通过使用 else ,我们可以执行当 if 判断为假时的情况。如下:
1. int main(){   
2.     if(1==1){   
3.         // Do some stuff here.   
4.     }   
5.     else{   
6.         // The universe is broken!   
7.     }   
8.  
9.     return 0;   
10. } 

  当然了,在现实生活中,我们并不会去判断1是否等于1。但值得要说的是,假设一个程序当你点击三次关闭按钮时关闭,这你就应该要在括号里检查有多少次被点击了。如果是低于3,这样,你可以在else 号内的代码里告诉用户点击多少次按钮就会让程序退出。

  当我们使用条件语句的时候,我们会经常看到,这远比我们这系列里见到多得多。

循环

  现在,让我们研究一下循环吧。循环,顾名思义,就是让通过一段代码并执行多次。这给我们提供很多便利,例如在需要填充一个列表或是重复一段代码,直到返回true。

  有三种常见的循环方式,以最常见的为例: for  , while 还有 do  。每们都用循环执行代码块,但他们的功能是不相同的,有以下几个例子:

1. // if loop   
2. int main () {   
3.     int i = 9;   
4.     int x = 0;   
5.  
6.     for (x = 0; x < i; x++){   
7.          printf("Count is: %i\n", x);   
8.     }   
9.  
10.     return 0;   
11. } 
 
  第一次看可能有点复杂,但事实上并不是。在for( 后面的分别是初始值,条件,和操作。当循环开始时,先执行初始值,在以上例子中是设置x 为0 。每次循环(包括第一次)它都会去检查"x 是否小于i”这个条件。最后,在每次执行循环代码,这循环就让 x 加1 。简单的来说,既然x 每次增加一,x 很快不会比i 小,这样循环就结束了,程序继续跑下去。
1. // while loop   
2. int main () {   
3.     int x = 0;   
4.     while (x < 10){   
5.         printf("Count is: %i\n", x); //Watch OUT! Something is missing.   
6.     }    
7.  
8.     return 0;   
9. }  
   类似于for 循环,while 循环执行括号里的代码块直到条件为假时结束。既然x为0,然后我们也不去改变它的值,所以呢,上面的代码会一直执行,出现了一个死循环。如果你想让 x 增加,那么,你可以在括号之间这样做:
1. // while loop   
2. int main () {   
3.     int x = 0;   
4.     while (x < 10){   
5.         x++;   
6.         printf("Count is: %i\n", x);   
7.     }   
8.  
9.     return 0;   
10. } 
 
 do 循环是本质上也是while 循环,只是条件判断执行在代码块之后。当个体do循环的时候,这意味着循环只少执行一次。
1. // do loop   
2. int main () {   
3.     int x = 0;   
4.     do {   
5.         x++;   
6.         printf("Count is: %i\n", x);   
7.     } while(x < 10);   
8.  
9.     return 0;   
10. }  
 

指针

  指针往往会给编程新手或是C语言初学者带来困惑,不会被让人很快的掌握它的用法,但你可以慢慢学多几次。然而,什么是指外针呢?

    正如其所暗含的意思,指针指向一个地址。具体的来说,是指向计算机的内存地址。这样说吧,我们声明一个变量(一个叫foo的整型),然后给这变量赋值,就赋123吧。那么,现在我们设定这个指针为foo,这样我们就有了一个间接访问这个值的方式。也就是说,我们有一个整型类型的指针指向foo的值123,实现代码如下:

1. int foo = 123; // This is an integer variable   
2. int *ptr = &foo; // This is a pointer to an integer variable

 

 

 

 

还是难理解?不用担心。指针是比较难掌握的,往往被认为是学习C语言的难点。指针最终会成为第二大特性,这也将会有更多的在以后的Objective-C系列中提到。

结束语

  本文给出了快速回顾C语言基础的一节课,这环节的目的是为了让你对C语言有一个快速的准备,并且也为接下来的系列学习作一个准备。同时也为那些已经熟悉另外一种编程语言的人作一个简单的介绍,如果你是编程新手或是对C语言基础有困惑,请重要阅读,同时也可以留言提问。

  在下一次开始之前,请确保编译以上的所有代码。给自己一个小小的挑战吧,例如,写10次的循环,计算每次的循环,并且用printf输出。尝试和实践是没有害处的,如果过程中出错,这可能对你更有益处,然后根据自己的修改让它成功跑起来。

挑战

  这个星期里,我们会结束一个小小的挑战。你将要编写三个程序,分别用三种不同的循环方式实现10的计数。既然,我们经常在Objective-C里使用循环,那么,请认真实现它。这是很简单的,所以,尽量倒计从10到1(如果 ++ 代表加一,那么怎样让它自减1呢?)。

下一节

   在下一节里面,我将会介绍Objective-C是如何工作的。同时,我们也会看到面向对象编程,并且使用它。包括深入到类,实例,方法,继承等等。

    下一周,大家将会了解到是什么让Objective-C变得如此棒,还有,为什么它扩展了许多C语言的有用方法。

还有问题吗?

  如果你任何的问题,你可以留言,或是你可以在Twitter发消息给我(http://www.twitter.com/iDemonix),我会尽快回复你。

 

                                                                                                                           Learn Objective-C--第二天>>