OC学习3——C语言特性之指针
1、指针是C语言中的一个非常重要的概念,实际上,OC系统类的变量、自定义类的变量等都是指针。定义指针变量的语法格式如下,其中*代表一个指针变量,整个语法代表定义一个指向特定类型的变量的指针变量。注意:指针变量不能保存普通的数值,它只能保存指针(也就是变量或对象的地址)。函数的形参传递方式有值传递和地址传递两种,其中地址传递就是传递的指针。
类型* 变量名 ; float* ft ;
int* a ;
2、关于指针,还有两个最基本的运算符,取地址运算符(&)和取变量运算符(*)。
&:取地址运算符,单目运算符,后面通常紧跟一个变量,该运算符用于读取该变量所在的内存地址。
*:取变量运算符,单目运算符,后面通常紧跟一个指针变量,该运算符用于读取该指针变量所指向的内存中的变量。
3、数组变量的本质就说指针常量,该指针常量指向第一个数组元素。下面两种赋值方式的本质是一样的,而且大部分时候都会采用第二种方式来获取数组的首地址。所以,将数组变量作为参数传递到函数中实际上是一种地址传递。
int arr[] = {, , , , } ; int* p1 = &arr[] ; //将第一个数组元素的地址赋值给指针变量p1
int* p2 = arr ; //将数组变量保存的地址赋值给指针变量p2
需要指出的是,虽然数组变量保存的是数组第一个元素的地址,但是数组中保存的地址是不能改变的,因此,数组变量应称为指针常量。所以,执行arr++,arr += 2这种语句都是试图对arr数组变量进行重新赋值,这都是错误的。
4、指向多维数组的指针变量,例如int arr[3][4] ;实际上是相当于定义了如下的三个数组变量:
arr[0]:该数组中再次包含了arr[0][0]、arr[0][1]、arr[0][2]、arr[0][3]四个元素,其中arr[0]表示指向arr[0][0]元素的地址的指针变量。
arr[1]:该数组中再次包含了arr[1][0]、arr[1][1]、arr[1][2]、arr[1][3]四个元素,其中arr[1]表示指向arr[1][0]元素的地址的指针变量。
arr[2]:该数组中再次包含了arr[2][0]、arr[2][1]、arr[2][2]、arr[2][3]四个元素,其中arr[2]表示指向arr[2][0]元素的地址的指针变量。
注意,arr[1][2]与 *(arr[1]+2) 、*(*(arr+1)+2)表示的意义是一样的,都是表示取arr[1][2]的值
5、指针的运算除了取地址、取变量和赋值之外,还有一些其他的运算需要注意,具体介绍如下:
指针变量加(减)一个整数:当指针变量加或减n时,代表将该指针的地址加或减n*变量大小个字节。举例来说,对于int* p;类型的变量,假如当前p变量中保存的地址为0x00010004,p+2则代表的地址是0x0001000C,因为一个int类型的数据占据4个四节,所以p+2实际上是往后移两个int类型的数据,相当于移8个字节。而对于char* p1;类型,若p1保存的地址是0x00020003,则p1+4则表示的地址是0x00020007。
当两个指针变量指向同一个数组的元素时,两个指针变量可以相减:两个指针变量相减,返回两个指针所指数组之间元素的个数。如果两个指针不指向同一个数组的元素,那么这两个指针变量相减没有任何意义。
当两个指针变量指向同一个数组的元素时,两个指针变量可以比较大小:指向前面的数组元素的指针小于指向后面的数组元素的指针。需要指出的是,如果两个指针不指向同一个数组的元素,那么这两个指针变量比较大小没有任何意义。
6、C语言的底层没有对字符串进行定义,一般都是通过字符数组进行保存字符串。此外,还可以通过字符指针来表示字符串,即定义一个字符指针变量,然后将C格式的字符串赋给该指针变量。
char* str = "I love IOS" ;
C语言的自字符串在底层依然是才用字符数组进行保存的,而str则是一个char*型的指针变量,它指向该字符数组的第一个元素,也就是指向该字符数组的首地址。
7、指针变量除了可以指向普通的int变量、float变量和数组之外,还可以指向函数的入口。当定义函数之后,C语言允许定义一个指针变量来指向该函数,然后就可以通过该指针变量来调用函数了,使用函数指针变量的语法格式步骤如下:
- 定义函数指针变量:函数返回值类型 (*指针变量名)();
- 将任何已有的函数赋值给函数指针变量:指针变量名 = 函数名 ;
- 使用函数指针变量来调用函数:(*函数指针变量名)(参数);
#import <Foundation/Foundation.h> int max(int * data, int len)
{
int max = *data ;
//采用指针遍历data数组的元素
for(int *p = data; p < data+len; p++)
{
//保证max始终存储较大的值
if(*p > max)
{
max = *p ;
}
}
return max ;
} int main(int argc, char* argv[])
{
int data[] = {,,,};
//定义函数指针变量fnPt,并将max函数赋值给fnPt
int (*fnPt) () = max ;
//通过函数指针变量调用函数
NSLog(@"最大值 max = %d", (*fnPt) (data , )) ;
}
函数指针的主要作用就是(1)把指针函数当作形参传递给某些具有一定通用功能的模块。并封装成接口来提高代码的灵活性和后期维护的便捷性;(2)有些地方必须使用函数函数指针才能完成给定的任务,如linux系统中的异步信号中断处理,当发生某一触发信号时,需要调用相应的处理函数,此时需要使用函数指针来实现。
void (*signal(int signum,void(* handler)(int)))(int);
参数一为信号条件,第二个参数为一个函数指针,它所指向的函数需要一个整型参数,无返回值。该函数的返回值也是一个函数指针,返回的指针所指向的函数有一个整型参数(一般不用)
8、函数既可以返回普通的int、float等类型,也可以返回一个指针。但是当函数返回一个指针的时候需要注意,由于函数返回的指针只保存了一个地址值,如果该指针指向的是被调用函数中的局部变量,这就非常危险了,因为函数中的局部变量在函数调用结束之后会被自动释放,这样会导致该内存中所保存的数据是不确定的。所以,为哦了保证函数返回的指针是有效的,有三种方式:
- 如果函数返回的指针是指向函数中的局部变量,该局部变量应该使用static修饰。
- 让函数返回的指针指向暂时不会被释放的数据,如指向main()函数中的变量。
- 让函数返回的指针指向全局变量。
9、指针数组是值数组中的每个元素都是一个指针变量,常见的main()函数的形参第二个参数定义是char* argv[]就是一个指针数组。详情可以参见数组指针和指针数组的区别
//指针数组的定义语法
类型* 变量名[长度]; char* arr[] ;
arr[] = "hello world!";
arr[] = "I love IOS";
arr[] = "how are you ?"; //注意区分上面的指针数组与下面的区别
类型 (*变量名)[长度]; //第二种写法中(*变量名)先形成一个整体,代表一个指针变量,该指针指向一位数组,因此表示定义一个指向一位数组的指针变量
int a[][];
int (*p)[]; //该语句是定义一个数组指针,指向含4个元素的一维数组。
p=a; //将该二维数组的首地址赋给p,也就是a[0]或&a[0][0]
p++; //该语句执行过后,也就是p=p+1;p跨过行a[0][]指向了行a[1][]
10、指向指针变量的指针:也称指针的指针。指针变量也是变量,也需要保存在内存中,因此指针变量也有自己的存储地址,如果再次定一个一个指针变量来保存这个地址,则这个指针变量就说指向指针变量的指针。
类型** 变量名;
OC学习3——C语言特性之指针的更多相关文章
- OC学习2——C语言特性之函数
1.OC是在C语言的基础上进行扩展的,在OC中直接用C语言进行coding也是可以通过编译的.因此,函数定义的语法格式如下: 函数返回值类型 函数名(形参列表) { //由零条或多条可执行性语句组成的 ...
- GO学习-(10) Go语言基础之指针
Go语言基础之指针 区别于C/C++中的指针,Go语言中的指针不能进行偏移和运算,是安全指针. 要搞明白Go语言中的指针需要先知道3个概念:指针地址.指针类型和指针取值. Go语言中的指针 任何程序数 ...
- ndk学习之C语言基础复习----指针、函数、预处理器
指针: 指针乃C.C++的灵魂之所在,所以有必要好好的复习复习.什么是指针?一句话来概括:“指针是一个变量,它的值是一个地址.”,其中指针变量的声明有如下三种形式: 其中第一种是被推荐的写法. 其中还 ...
- 【转】浅思OC的语言特性
算了算,学习IOS已经有一段时间了.今天花了点时间思考一下OC的语言特性,让自己的心不要那么浮躁,注重基础,回归本源. OC做为一门面向对象语言,自然具有面向对象的语言特性,如封装.继承.多态.他具有 ...
- 浅思OC的语言特性
算了算,学习IOS已经有一段时间了.今天花了点时间思考一下OC的语言特性,让自己的心不要那么浮躁,注重基础,回归本源. OC做为一门面向对象语言,自然具有面向对象的语言特性,如封装.继承.多态.他具有 ...
- OC学习6——面相对象的三大特性
我们在学习Java的时候都知道,类有三大特性:继承,封装,多态,这也是面向对象的三大特征.OC学习篇之---类的三大特性(封装,继承,多态) 1.封装(Encapsulation)是指将对象的状态信息 ...
- 学习小程序第三天 WXML语言特性
WXML语言特性 1.数据绑定 Musstache 语法 获取json中指定键值:变量名加双括号的绑定语法 如下: (1)绑定文本 注意所有组件和属性 都要小写 (2)绑定属性 ( ...
- OC学习5——类和对象
1.OC是在C语言基础上进行扩展得到的一门面向对象的程序设计语言,它也提供了定义类.成员变量和方法的基本功能.类可以被认为是一种自定义的数据类型,使用它可以定义变量,所有使用类定义的变量都是指针类型的 ...
- (转载)OC学习篇之---第一个程序HelloWorld
之前的一片文章简单的介绍了OC的相关概述,从这篇开始我们就开始学习OC的相关知识了,在学习之前,个人感觉需要了解的其他的两门语言:一个是C/C++,一个是面向对象的语言(当然C++就是面向对象,不过这 ...
随机推荐
- SpringCloud Feign context-path踩到的坑
最近在使用SpringCloud的context-path时,遇到了一些坑,记录一下. server.context-path(上下文) 服务提供者的application配置文件中有一个属性叫ser ...
- CO-产地证--需要的国家以及操作流程。
需要产地证的国家一般是与中国有合作的亚非拉国家,比如: 巴基斯坦.智利.以色列.韩国.土耳其.越南.澳大利亚. 流程: 1.在海关官网上填报信息. 2.提交,客户在他国家的官网上确认. 3.确认无误后 ...
- http://ctf.bugku.com/challenges#love:bugku--love
做了一道逆向题目,主要关联到base64编码的知识点.下面做一分析. 题目如下: 通过测试,可知它没有加壳.尝试使用IDA进行分析. 1.IDA分析文件 打开文件后,按[shift+F12 ...
- java基础 ------- 多重循环 and break与continue
----- 什么是多重循环 ---- 打印数列 public class ForEx { public static void main(String[] args){ for(int i = ...
- 考研部分概念和流程(若不全和错误可提示我补充,另考研帮app推荐)
上大学必须经过全国统一高考,而就读硕士研究生的途径相对而言要多一些,也更灵活一些.已经工作的人,除了放弃工作报考研究生以外,还可以不脱产申请攻读学位,或申请单独考试.不脱产申请攻读学位,通俗的讲,就是 ...
- MQ消息队列在软件开发中的作中
MQ的作用是非常之大的. 1.解耦. 当一个大型的系统.比如,商城系统.包括以下的功能: 1.发邮件 2.发短信 3.抽奖 4.搜索等 如果你都用一台服务器,做到一个程序里,代码会非常庞大,不利于维护 ...
- Scatter 散点图
散点图 首先,先引入matplotlib.pyplot简写作plt,再引入模块numpy用来产生一些随机数据.生成1024个呈标准正态分布的二维数据组 (平均数是0,方差为1) 作为一个数据集,并图像 ...
- web安全之机器学习入门——1.环境搭建
前置知识 算法和数据的辩证关系:算法和数据是机器学习解决实际问题不可或缺的两大因素.早期机器学习十分依赖特征提取,随着发展,人们发现通过增加训练数据量,让机器从大量基础特征中可以自动关联出潜在关系,自 ...
- 数据库mysql之慢查询优化
今天项目遇到一个问题:就是在公司test环境中执行sql查询语句很快,也就几百毫秒,但是放到sit环境中测试就要延迟至少1分钟左右. 网上找了很多原因,大多数都是说索引问题,我看了索引没问题,又重新建 ...
- python_day11
一.简介 1.什么是数据库? 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库,每个数据库都有一个或多个不同的API用于创建,访问,管理,搜索和复制所保存的数据. 2.关系型数据库 ...