您的位置:首页 > 移动开发 > IOS开发

ios学习之旅---指针也不难

2015-08-15 16:15 471 查看
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);

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

}

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

int main(int argc, const char * 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;

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

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

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

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

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

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

int num2 = 20;

int *p2 = &num2;

*p2 = 40;

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

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

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

p2 = #

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

char c = 'a';

int *pc = &c;

*pc = 10;

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

return 0;
}




3、多级指针

通过指针访问变量称为间接访问。由于指针变量直接指向变量,所以称为“一级指针”。而

如果通过指向指针的指针变量来访问变量则构成“二级指针”。

#include <stdio.h>

void test()
{
int num = 10;

int *p = #

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

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

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

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

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

//    char error[100];

char *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(int *));
printf("%lu\n",sizeof(char *));
printf("%lu\n",sizeof(double *));
printf("%lu\n",sizeof(float *));
printf("%lu\n",sizeof(float **));
}

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

int num = 10;

char *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;

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

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

int * pointer1 = nums;

int * 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};

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

p -= 1;

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

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

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

int *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 char * argv[]) {
int nums[] = {1,2,3,4,5};
int *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}};
int *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;

int *p = &a;

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

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

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

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

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

int main(int argc, const char * 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的数据

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

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: