OC(C语言特性函数,指针)

一.函数

1.如果声明函数时指定的返回值类型与return语句实际返回的数据类型不匹配,那么此时将以声明函数时指定的返回值的类型为准,系统会自动转换.
2.Objective-C里函数的参数传递传递方式只有一种:值传递.所谓的值传递就是将参数的指针地址拷贝一份副本(指针)传入函数,这个副本也是指针,副本的指针指向的地址是存储内容的地址,貌似是指针传递,但是其本质是值传递
(参数有两个地址,一个是自己的存储地址,一个是存储内容的地址,拷贝的意思就是生成一个新的地址,但是存储内容的地址没改变,只不过之前只有一个指针指向,现在是两个指针指向存储的位置)

举例
@interface DataTest:NSObject
@property int a;
@property int b;
@end
@implementation DataTest
@end

int main(int argc,char *argv[]){
    @autorreleasepool{
        void swap(int ,int);
        void changeText(NSString *);
        int a = 6;
        int b = 9;
        swap(a,b);
        NSLog(@"%d,%d",a,b);//a = 6,b = 9;从此可以证明传递的是值

        //再举例指针类型,C语言中指针传递的也是一个副本,只不过传递的是当前str的指针的副本,
        //指针的地址改变了但是指向的数据的地址依旧是原始数据的地址,所以导致原始数据跟随改变,
        //C语言中值会改变也是有条件的,当直接改变参数指针的指向时是不会影响原始数据的

        //OC中传递的是值,指针类型传递的是指针的副本也是值,不会影响到原始数据(有条件的)
        (1).当改变的是传递的指针的指向时是不会影响原始数据的
        (2).当改变的是传递的指针指向的对象的其他属性时会影响原始数据

        NSString *str = @"123456789";
        //这个时候传递的是str副本的的指针地址,这个地址指向的是str的值@"123456789"的存储位置
        //假设指针地址为0x100000,数据的地址为0x1111111
        changeText(str);


        DataTest *test = [[DataTest alloc]init];
        test.a = 10;
        test.b = 20;
        NSLog(@"%d,%d",test.a,test.b);//a = 10,b = 20;
        testObject(test);
        NSLog(@"%d,%d",test.a,test.b);//a = 30,b = 40;
        //这个时候会变是由于使用.语法的时候使用的是test指向的对象,
        所以传参过去复制了一份地址,但是指向的内容还是test的对象.


        NSArray *arr = @[@"1",@"2",@"3"];
        NSMutableArray * arr1 = [NSMutableArray arrayWithArray:@[@"00",@"111",@"222"]];
        NSLog(@"%p,%p,%p",arr1,arr1[0],&arr1);
        NSLog(@"%p,%p,%p",arr,arr[0],&arr);
        /**
        0x28142d530,0x10069d840,0x16f7a38f0
        0x28142d650,0x10069d7e0,0x16f7a38f8
        */
        //C语言的数组的地址是数组元素的首地址,从上面的地址看出,
        //可变数组会影响原始数据是因为,可变数组在创建时会分配一片内存,当增删时只是操作的这一块的内存,所以原始数据会有影响,不可变数组是因为改变了指针的指向,所以原始数据不会受影响.

        [self testData:arr withMutableArr:arr1];
        NSLog(@"%p,%p,%p",arr1,arr1[0],&arr1);
        NSLog(@"%p,%p,%p",arr,arr[0],&arr);
        /**
        0x28142d530,0x10069d8e0,0x16f7a38f0
        0x28142d650,0x10069d7e0,0x16f7a38f8
        */
    }
}
- (void)testData:(NSArray*)arr withMutableArr:(NSMutableArray*)mutableArr{
    NSLog(@"%p,%p,%p",mutableArr,mutableArr[0],&mutableArr);
    NSLog(@"%p,%p,%p",arr,arr[0],&arr);
    /**
     0x28142d530,0x10069d840,0x16f7a37c0
     0x28142d650,0x10069d7e0,0x16f7a37c8
     */
    //从数据上可以看出传递过来的指针是复制了一份指针,指针不同了,但是依旧指向的原始数据存储的地址

    //数组这里是直接重新指向了一块内存
    arr = @[@"222",@"333",@"123123"];
    mutableArr[0] = @"333";
    [mutableArr setObject:@"00000" atIndexedSubscript:0];
    NSLog(@"%p,%p,%p",mutableArr,mutableArr[0],&mutableArr);
    NSLog(@"%p,%p,%p",arr,arr[0],&arr);
    /**
     0x28142d530,0x10069d8e0,0x16f7a37c0
     0x28142a010,0x10069d860,0x16f7a37c8
     */
     //对不可变数组重新赋值,相当于将arr指向的存储地址换了,arr的存储的指针地址与原始数据的不同,所以不会影响原始数据
     //对于可变数组mutableArr是一个对象,改变对象里面的数据原始数据会受到影响.如果将数组整体赋值,原始数据是不会受影响的
}
void swap(int a,int b){
    int tmp = a;
    a = b;
    b = tmp;
    NSLog(@"%d,%d",a,b);//a = 9,b = 6
}
void changeText(NSString *str){
    //打印str的指针地址不是0x100000,但是指针指向数据的地址还是之前的地址0x1111111
    NSLog(@"%p,%p",&str,str);
    //所以按理说修改str的同时修改的也是原始数据的值,但是事实证明并没有(在C语言中原始数据也会随着改变的,C语言中str指针是原始的指针)
    //str的值未改变是因为str指针是一个新的指针地址,给str赋值时相当于改变了str的指向,所以原始的数据不会受影响
    str = @"11111";
}
void testObject(DataTest *test){
    NSLog(@"%d,%d",test.a,test.b);//a = 30,b = 40;
    test.a = 30;
    test.b = 40;
}

3.C语言中数组当做参数传入函数中传递的是指针,该指针指向数组的首地址,操作的时候改变的是指针指向的存储数据,因此函数中改变数组元素会对数组本身有影响,但是在OC中这一理论不通用.
4.内部函数,定义函数时使用static修饰,该函数只能被当前源文件访问
5.外部函数,定义函数是使用extern修饰,或者不使用修饰符,该函数可以被任意的源文件使用

二.局部变量和外部变量

1.局部变量,在函数内定义的变量为局部变量.在函数内部可以使用extern修饰局部变量,让其变成全局变量,这个变量可以被任意的源程序文件访问
2.全局变量,在函数外定义的变量默认不需要使用修饰词或者使用extern修饰,如果希望全局变量的作用域限制在该源程序使用,即只能在本文件中使用则可以使用static修饰该全局变量.

三.宏

1.不带参宏定义 #define 宏名称 宏代表的内容

#define YES 1
#define定义宏 #undef,用完宏后不想让下面接着使用,可以提前结束宏定义

2.带参数的宏定义 #define 宏名称(参数列表) 字符串(需要操作的内容)

#define PI 3.1415926
#define GIRTH(r) PI * 2 * (r);
#define AREA(r) PI * (r) * (r)
//定义宏的时候参数需要带括号,避免出错

3.#ifdef,#ifndef,#else,#endif执行条件编译,这几种方式的条件只能是宏

#ifdef 宏名称
//任意语句1
#else
//任意语句2
#endif
//上面的宏定义为如果有这个宏就执行任意语句1 

#ifndef 宏名称
//任意语句1
#else
//任意语句2
#endif
//上面的宏定义为如果没有这个宏就执行任意语句1

4.#if,#elif,#else,#endif执行条件编译,这个判断条件不一定是宏,可以使指定的表达式

#if 表达式
//任意语句
#elif 表达式1
//任意语句
#else(这个else可以省略)
//任意语句
#endif

四.指针

1.指针的概念

(1).操作系统分为32位和64位,32位的最多只能支持4GB的内存,因为计算机底层并不使用十进制,
使用的是二进制,32位的二进制只能支持4G个编号,这意味着操作系统只能为4GB的内存单元编号,因此32位的
操作系统最多只能支持4GB的内存,多余的内存不会有编号,因此无法将数据存入这些内存单元中.
(2).变量的内存地址就是该变量的指针;而用于保存内存地址(指针)的变量就是指针变量,指针变量指向的地址就是存储的数据,指针变量也有自己的指针地址,因为他也要存储.
(3).&:取地址运算符,后面常跟变量,该运算符用于读取该变量所在的内存地址.
(4).*:取变量运算符,后面通常紧跟一个指针变量,该运算符用于读取该指针变量所指的变量
(5).指针运算符&和*是从右往左运算,他们的优先级相同
举例
void test(){
    int a = 200;
    int *p;
    p = &a;
    NSLog(@"%d",*p);//200
    而且a == *&a;
}
(6).C语言调用函数时的传参机制总是值传递,只是当使用指针作为参数时,由于指针变量本身保存的就是地址,
因此此时的传参机制也被称为地址传递

2.指针与数组

(1).数组中第一个元素的地址被称为数组的首地址,数组的首地址会被当做数组地址,
C语言规定:数组变量的本质就是一个指针常量,保存了指向第一个数组元素的指针;
OC中可不是,元素有自己的地址,数组对象也有自己的相应的地址
举例
void test(){
    int arr[] = {4,12,34,6,7,788};
    int *p = arr;//得到的是arr的地址
    int *m = &arr[0];//得到的是arr数组第一个元素的地址
    NSLog(@"%p,%p",p,m);//可以得出p和m是相等的
}
(2).指针变量的赋值方式
p = &a;将一个已有变量的内存地址赋给指针变量p
p = &arr[i];将某个数组元素的内存地址赋给指针变量p
p = arr;将arr数组的首地址赋给指针变量p
p = pt;将指针变量pt中保存的地址赋值给指针变量p
(3).指针可以进行加减运算,当指针指向同一个数组时两个指针相减返回两个指针所指数组之间的元素个数,
如果两个指针不指向同一个数组,那么两个指针变量相减没有任何意义
(4).指针变量加减一个整数,p(指针)(+/-)n(整数)计算方式为,指针地址 (+/-) n * 变量占有的字节数
(5).sizeof的用法
每种类型的数据在内存单元中占有的字节数是固定的,因此sizeof(arr)/sizeof(arr[0]) = 数组的元素的个数
sizeof(arr):获取的是数组总共占有多少字节
sizeof(arr[0]):获取的是数组中一个元素占有的字节数
C语言中的数组是静态的,不要尝试通过指针给数组元素重新赋值
(6).数组变量保存的是地址,但数组变量中保存的地址是不能改变的,注意说的是指针地址不能变,但是指针指向的值是可以变的,
因此数组变量应称为指针常量.可以改变数组中地址中存储的值
举例
int carr[] = {1,2,3,4,5};
*(carr+1) = 123;
或者这样(因为*(carr+i) 等于 carr[i])
carr[2] = 1234;

上面的内容是我修改了carr数组中第二个位置的值,指针没有发生变化的,发生变化的是指针指向区域存储的内容

3.指向指针变量的指针

指针变量也是变量,指针变量也需要保存到内存中,
那么指针变量也有自己的存储地址,如果再次定义变量来保存
指针变量的存储地址,这个地址就是指向指针变量的地址.
举例
void main(){

    int a = 20;
    int * p = &a;//p的指针地址指向&a
    int **pt = &p;//pt的指针指向&p
    //等号,不是说就是相等了,而是改变的指针的指向
    NSLog(@"%p",p);//输出的是指针变量p保存的地址
    NSLog(@"%p",pt);//输出的是指针变量pt保存的地址,即p的存储地址,不是p存储内容的地址
    NSLog(@"%p",*pt);//输出指针变量pt所指的变量中保存的地址,即&a的地址,
    NSLog(@"%d",**pt);//输出指针变量pt所指的变量,变量中保存的地址中的值,即a的值
}

有问题可以留言一起讨论

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容

  • 几种语言的特性 汇编程序:将汇编语言源程序翻译成目标程序编译程序:将高级语言源程序翻译成目标程序解释程序:将高级语...
    囊萤映雪的萤阅读 2,861评论 1 5
  • 重新系统学习下C++;但是还是少了好多知识点;socket;unix;stl;boost等; C++ 教程 | 菜...
    kakukeme阅读 19,784评论 0 50
  • ———————————————回答好下面的足够了---------------------------------...
    恒爱DE问候阅读 1,709评论 0 4
  • 注:这是第三遍读《C语言深度解剖》,想想好像自从大学开始就没读完过几本书,其中谭浩强的那本《C语言程序设计(第四版...
    HavenXie阅读 1,711评论 1 6
  • 吾本寒家,世以清白相承。吾性不喜华靡,自为乳儿,长者加以金银华美之服,辄羞赧弃去之。二十忝科名,闻喜宴独不戴花。同...
    苏白杞阅读 840评论 3 19