学习Objective-C--第一天
2011-06-10 14:49 Paul Wong 阅读(73545) 评论(33) 编辑 收藏 举报前言:
在这里,翻译Dan Walker的Learn 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
1. ./outputfile
基础知识
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. 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. }
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),我会尽快回复你。