iOS 变量指针记录

转自:http://blog.csdn.net/sdzh2012/article/details/47682681

1.认识指针
#include <stdio.h>  
//基本数据类型作为函数参数传递是值传递  
//void moveFront(int x ,int y)  
//{  
//    x  = x + 2;  
//}  
void test()  
{  
    //  确定当前坐标  
    int x = 20;  
    int y = 150;  
    printf("%p\n",&x);  
    printf("%lu\n",&x);  

    *((intint *)(0x7fff5fbff76c)) = 22;  
    printf("(%d,%d)\n",x,y);  
    //    moveFront(x, y);  
    //    printf("(%d,%d)\n",x,y);  

}  

//如果你想访问指针所指向存储空间,就必须使用访问指针所指向的存储空间的操作符  
void moveFront(intint *x ,intint *y)  
{  
//  x  = x + 2;//此时是改变指针的指向,而不是访问指针所指向的存储空间  
    *x  = *x + 2;  
}  

int main(int argc, const charchar * argv[]) {  

    //  确定当前坐标  
    int x = 20;  
    int y = 150;  
    printf("(%d,%d)\n",x,y);  
    moveFront(&x, &y);  
    printf("(%d,%d)\n",x,y);  

    return 0;  
}  

这里写图片描述

2、指针的定义与初始化(重点掌握)

内存中最小的存储单元:字节,每一个字节在内存中都有一个编号,这编号就是指针

指针:内存地址
有了指针你就有了打开这块内存钥匙,就可以操作这一块内存

指针变量:存放内存地址的变量
定义指针:指针所指向数据类型 * 指针变量名称;
在的定义变量时候,*是一个类型说明符,说明定义这个变量是一个指针变量
在不是定义的变量的时候,*是一个操作符,访问(读、写)指针所指向的那块存储空
指针的初始化:

注意点:
1、只有定义没有初始化指针里面是一个垃圾值,这时候我们成为这个指针为野指针
2、如果操作一个野指针
   2.1 程序崩溃
   2.2 访问不该你访问存储,操作潜在逻辑错误
3、不可以使用整形常量赋值一个指针变量
   因为内存是操作系统分配我们的,不是我们随便取的
4、什么类型的指针,只指向什么类型的变量
5、多个指针可以指向同一变量
6、指针的指向是可以改变的
#include <stdio.h>  


//指针的定义  
void test()  
{  
    int num = 10;  

    //  定义一个指针变量  
    intint *p;  
    p = #  

    *p = 20;  
    printf("num = %d\n",num);  
}  

int main(int argc, const charchar * argv[]) {  


// 先定义在进行初始化  
    int num = 10;  
//  定义一个指针变量p  
    intint * p;  

//    *p = # // p 还有进行初始,不能够访问它所指向存储空间  
    p = #//p 指向 num  
    *p = 20;  


//  定义指针变量的同时进行初始  

    int num2 = 20;  

    intint *p2 = &num2;  

    *p2 = 40;  

    printf("%d,%d\n",num2,*p2);  

// 不可以使用整形常量赋值一个指针变量  
// 因为内存是操作系统分配我们的,不是我们随便取的  

//    int *p3 = 100000;//此处是错误的  
//      
//    *p3 = 10;  

    p2 = #  

    printf("%p\n",p2);  

    char c = 'a';  

    intint *pc = &c;  

    *pc = 10;  

    printf("%p\n",p2);  


    return 0;  
}  

这里写图片描述

3、多级指针

通过指针访问变量称为间接访问。由于指针变量直接指向变量,所以称为“一级指针”。而
如果通过指向指针的指针变量来访问变量则构成“二级指针”。

#include <stdio.h>  

void test()  
{  
    int num = 10;  

    intint *p = #  

    //  定义一个指针来指向变量p  
    //  pp就是一个二级指针  
    intint **pp = &p;  

    **pp = 30;  
    printf("%d\n",num);  

    intint ***ppp = &pp;  
    ***ppp = 50;  
    printf("%d\n",num);  

    //  四级指针  
    intint ****pppp = &ppp;  
    ****pppp = 100;  
    printf("%d\n",num);     
}  
void readFile(charchar **error)  
{  
    *error = "读取错误";     
}  

int main(int argc, const charchar * argv[]) {  

//    char error[100];  

    charchar *error;  

    readFile(&error);  

    printf("%s",error);  

    return 0;  
}  

4、指针为什么要区分类型

1、变量的地址是变量所在占存储空间的首地址
2、指针变量仅仅可以存储一个地址编号,如果没有类型,当通过指针就不知道要访问多少个字节的存储空间
3、指针区分类型是为了在通过指针访问它所指向的存储空间的时候,能够正确访问
4、如果通过一个char类型的指针操作一个int的变量,如果值的二进制数据超过1字节,那么就造成数据错误
5、如果通过一个int 类型的指针操作一个char变量,那么你就会修改了你不该修改的内存,造成程序逻辑错误

#include <stdio.h>  
/* 
   所有指针类型都是占用八个字节的存储空间 


 */  
void testEveryPointerIs8B()  
{  
    printf("%lu\n",sizeof(intint *));  
    printf("%lu\n",sizeof(charchar *));  
    printf("%lu\n",sizeof(doubledouble *));  
    printf("%lu\n",sizeof(floatfloat *));  
    printf("%lu\n",sizeof(floatfloat **));  
}  



int main(int argc, const charchar * argv[]) {  

    int num = 10;  

    charchar *cp = #  


    printf("%d\n",num);  

    return 0;  
}  

5、指针运算概述
指针变量:存放是内存字节的地址编号(无符号的整形数)
指针:是运算受限的无符号的整形数
运算运算:
指针 + 整形数 === 指针变量中值 + sizeof(其所指向数据类型)
指针 - 整数数 === 指针变量中值 - sizeof(其所指向数据类型)
pointer1 - pointer2 = (pointer1中值 - pointer2中值) / sizeof(其指向数据类型)
赋值运算:
=
+= 必须是一个整形数
-= 必须是一个整形数
比较运算
==
!=
>
<

=
<=
自增自减
p++; p = p + 1;
++p; p = p + 1;
–p;
p–;

#include <stdio.h>  


//算术运算  
void test()  
{  
    int a = 10;  

    intint *p = &a;  
    //  指针+1  
    p = p + 1;  


    int nums[5] = {1,2,3,4,5};  

    intint * pointer1 = nums;  

    intint * pointer2 = &nums[4];  

    size_t size  = pointer2 - pointer1;      
    printf("%lu\n",size);          
    //  pointer1 + pointer2;  
    //    pointer2 * pointer1;  
    //    pointer1 / pointer2;  
    //    pointer1 / 2;  
}  
//赋值运算  
void test1()  
{  
    int a = 10;  

    //    int *p = &a;  

    int nums[] = {1,2,3,4,5};  

    intint *p = nums;  
    intint *p2 = nums;  
    p += 2;  
    p = p + 2;  

    p -= 1;  

    printf("%d\n",*p);     
}  

//关系运算  
int main(int argc, const charchar * argv[]) {  

    int nums[] = {1,2,3,4,5};  

    intint *p = nums;  
    p++;  
    int result =  nums == p;  
    result = p > nums;  
    p--;  
    result = p < nums;     
    result = p >= nums;  
    result = p <= nums;     
    printf("%d\n",result);     
    return 0;  
}  

6、指针与一维数组(理解)

数组像一个指针:访问数组中元素,使用数组与使用指向这个数组的指针是等价

nums[1] ==== p[1]
nums+1 ==== p + 1;

nums[1] 的本质 *(nums + 1)
指针 + 整数 ===== 指针中的值 + sizeof(所指向的数据类型) * 整数
// int nums[] = {1,2,3,4,5};
//
// int *p = nums;
double nums[] = {1.0,2.0,3,4,5};
double * p = nums;
// printf(“%d,%d,%d,%d,%d,%d\n”,nums[1],p[1],(nums + 1),(p + 1),*(++p),。);
printf(“%p\n”,nums);
printf(“%p\n”,nums+2);
printf(“%p\n”,p);
printf(“%p\n”,p+2);
数组不是一个指针
1、sizeof(array) != sizeof(pointer):当一个数组赋值一个指针变量的时候,那么数组中有些信息就丢失了,比如数组长度,这种现象指针信息遗失
2、指针的指向是可以改变的,数组的指向是不可以改变
3、array == &array 数组名就是数组地址,pointer != &pointer : 指针所指向地址不是指针本身地址

#include <stdio.h>  
int main(int argc, const charchar * argv[]) {  
    int nums[] = {1,2,3,4,5};  
    intint *p = nums;  
    p = nums;  
//    nums = nums + 1;      
     printf("%lu,%lu\n",sizeof(nums),sizeof(p));         
    printf("%p\n",nums);  
    printf("%p\n",&nums);        
    printf("%p\n",p);  
    printf("%p\n",&p);          
    return 0;  
}  

7、指针与二维数组
指针数组与二维数组指针变量的区别
应该注意指针数组和二维数组指针变量的区别。这两者虽然都可用来表示二维数组,但是其表示方法和意义是
不同的。
二维数组指针变量是单个的变量,其一般形式中”(*指针变量名)”两边的括号不可少。而指针数组类型表示的
是多个指针(一组有序指针)在一般形式中”*指针数组名”两边不能有括号。例如:
int (*p)[3];
表示一个指向二维数组的指针变量。该二维数组的列数为3或分解为一维数组的长度为3。
int *p[3]
表示p是一个指针数组,有三个下标变量p[0],p[1],p[2]均为指针变量。

#include <stdio.h>  

void test()  
{  

    int nums[3][2] = {{1,2},{3,4},{5,6}};     
    intint *p = nums[0];      
    printf("%p\n",p);  
    printf("%p\n",nums);      
    for (int i = 1; i < 6; i++) {  
        printf("%d ",*(p + i));  
    }  

}  
/* 
  定义指针数组的格式: 
  数据类型 * 指针变量名称[指针个数] 
 */  
void test2()  
{  
    int nums[3][2] = {{1,2},{3,4},{5,6}};  

    //    int * p[2] = {nums[0],nums[1]};  
    //        p = nums;  
    //  
    //    printf("%d\n",p[0][1]);  

    int a = 10;  
    int b = 20;  
    int c = 30;  

    intint *p = &a;  

    //    *p === p[1]; 没有这么写的  

    intint *ps[3] = {&a,&b,&c};  

    printf("%d,%d,%d",*ps[0],*ps[1],*ps[2]);  

}  
/* 
  定义一个指向一维数组的指针 
  数据类型 (*指针名称)[所指向的一维数组的元素个数] 

  指针 + 整数 === 指针中的值 + 所指向数据类型的长度 * 整数 
 */  

int main(int argc, const charchar * argv[]) {  

    int nums[3][2] = {{1,2},{3,4},{5,6}};  

    int (*ps)[2];  

    ps = nums;//可以认为ps 与 nums是等价的   
    int num = ps[0][1];  
    printf("%d\n",num);     
    printf("%p\n",nums);  
    printf("%p\n",nums+1);      
    printf("%p\n",ps);  
    printf("%p\n",ps+1);      
    for (int i =0 ; i < 3; i++) {  

        for (int j = 0; j < 2 ; j++) {  
            printf("%d ",ps[i][j]);  
        }  
        printf("\n");  
    }  

//    nums   nums[0]  

//    相同点:对应地址都是一样的  
//    不同点:指针类型是不同  
//    nums + 1 = nums + sizeof(nums[0])  
//    nums[0] + 1 = nums + sizeof(int)  

//   sizeof(nums) 二维数组所用占用存储空间字节数  
//   sizeof(nums) / sizeof(int) 二维数组中一共有多少个int的数据  

    intint *p = nums[0];  
    for (int i = 0; i < sizeof(nums) / sizeof(int); i++) {  
        printf("%d ",p[i]);  
    }  


    return 0;  
}  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值