C语言4个整数用4个指针变量,C语言专题-指针

指针重要性:

表示一些复杂的数据结构

快速的传递数据

使函数返回一个以上的值

能直接访问硬件

能方便的处理字符串

是理解面向对象语言中引用的基础

c语言的灵魂

指针的定义

地址:

内存单元的编号

从零开始的非负整数

范围:

指针:

指针就是地址,地址就是指针

指针变量就是存放内存单元编号的地址,活着说指针变量就是存放地址的变量

指针和指针变量是两个不同的概念

但是要注意的是:通常我们叙述会把指针变量简称为指针

指针的本质就是操作受限的非负整数(为什么这么说,因为非负整数可以加减乘除,而指针不能加乘除,只能相减)

指针的分类:

1基本类型的指针

int * p;//p是变量名字, int* 表示存放的存放的是int类型的数据

int i =3;

p=&i;//p是指针变量,并且p存放了普通变量i的地址,所以说p指向了普通变量i ,所以*p=i;或者说所有出现*p的地方都可以替代成i,所有出现i的地方都可以替代成 *p,*p就是以p的内容为地址的变量

常见的错误写法

错误写法1:

int * p;

int i =5;

*p=i;//错误:因为*p就是以p的内容为地址的变量,但是p没有赋值,就是垃圾值,所以这里*p就是以这个垃圾值为地址的这个一个单元,这个地址我们并不知道,那么你要把i的值给这个我们不知道的单元,那么就会奔溃

错误写法2:

int i =5;

int*p;

int *q;

p=&i;

*q=p;//同上的一个原因是q是没有赋值,*q是垃圾值,原因二是*q和p的数据类型不一致

错误写法2:

int i =5;

int*p;

int *q;

p=&i;

q=q;//这个没错,q是垃圾值,q赋值给p,p也变成垃圾值

printf(@"%d",*q);//这个就是错的,q的空间数据本程序,所以本程序可以读写,但是如果q内部是垃圾值,则本程序不能读写*q的内容,因此此时 *q所代表的内存单元的控制权限并没有分配给本程序,所以本程序运行到此行就会出错

附注:* 的含义

1 乘法

2 定义指针变量: int * p;//定义了一个名字叫p的变量,int表示p只能存放数据类型为int类型的地址

3 指针运算符,该运算符放在已经定义好的指针变量前面,如果p是一个定义定义好的指针变量,则*p表示以p的内容为地址的变量

2.指针和数组

1.指针和一维数组

#####数组名:

一维数组名是个指针常量,存放的是数组首个元素的地址,因为它是常量,所以不能被改变

#####下标和指针的关系

如果p是个指针变量,则p[i] 永远等价于 *(p+i)

确定一个一维数组需要几个参数[如果一个函数要处理一个一维数组,则需要接受该数组的哪些信息],答案是需要两个参数:第一个是数组第一个元素的地址,第二个是数组的长度

#####指针变量的运算

指针变量不能相加不能相乘也不能相除,只能减

如果两个指针变量指向的是同一块连续空间中的不同储存单元,则这两个指针变量才可以相减,一般只能是数组

int i =5;

int j=10;

int a[5];

p=&a[1];

q=&a[4];

printf("相差几个单元:%d",q-p);//3

#####一个指针到底占几个字节

假设p指向char类型变量(char占一个字节)

假设q指向int类型变量(int占四个字节)

假设r指向doubel类型变量(doubel占八个字节)

那么p q r本身所占的字节数是否一样

答案是:q p r本身所占字节数都是一样的,四个字节

总结:

1.一个指针变量,无论他指向的变量占几个字节,该指针本身只占四个字节,

2.一个变量的地址使用该变量的首字节的地址表示

原理是这样,比如q指向int类型变量,其他p只保存了int所在四个字节内存的第一个字节,至于只保存了第一个字节但是却能储存四个字节的数据,这是由数据类型int决定,就是从p保存的第一个字节开始往后计算四个字节,对于doubel float也是一样的,但是为什么p本身占四个字节,这是因为,机器是32位的,也就说地址总线有32跟,那么最大地址的表示为2的32次方,也就是4个字节的表示方式,p表示其实都是内存单元,既然内存的最大单元为2的32次方法,那么它本身的最大值也应该为2的32次方

2.指针和二维数组

3.指针和函数

4.指针和结构体

结构体定义

为什么需要结构体:为了表示一些复杂的事物,而普通的基本类型无法满足实际需求

什么叫结构体:就是把一些基本类型组合在一起的形成的新的数据类型叫做结构体

```

//定义一个结构体的数据类型

struct Student{

int age;

float score;

char sex;

};

struct student stu={12,"edison"};

NSLog(@"age =%d name=%s",stu.age,stu.name);

定义结构体的方式

方式1:

struct Student{

int age;

float score;

char sex;

};

方式2:

struct Student{

int age;

float score;

char sex;

}stu;//在定义的同时直接定义变量名,这样不好,因为只能定义一次

方法3:

struct{

int age;

float score;

char sex;

}stu;//也不好

* ######结构体的初始化

初始化方法

方法1

struct student st ={12,"edison"};

方法2;

struct student st ;

st.age=12;

st.name="edison";

如何取出结构体的每个成员

/*

结构体变量名.成员名

指针变量名->成员名

/

struct student st={12,"edison"};

st.age=12;

st.name="name";

struct student * pst=&st;

pst->age=34;

pst->name="edison"//pst->age 在计算机内部会转化成(pst).age,

//所以 pst->age 等价于st.age,也等价于(*pst).age

* ######结构体运算

结构体变量可以相互赋值

struct student st={12,"edison"};

st.age=12;

st.name="name";

struct student st2=st;//是可以的

#####5.多级指针

* ####专题

#####1.动态内存分配

* ######传统数组的缺点:

1.数组长度必须事先指定,且只能是常整数,不能是变量

2.传统形势定义的数组,该数组的内存程序员无法手动释放,只能等本函数运行完毕由系统释放

3.数组的长度一旦定义,其长度就不能更改,数组的长度不能在函数运行的过程中动态的扩充或者缩小

4.a函数定好的数组,在a函数运行期间可以被其他函数调用,但是a函数运行完毕之后,a函数中数组将无法给其他函数使用

* ######为什么需要动态分配内存

就是因为动态数组很好的解决了传统数组的四个缺陷

int * p =(int )malloc(100);

/

malloc函数只有一个形参,就是需要分配的字节数

malloc函数其实只能返回分配好的内存的第一个字节的地址,所以在malloc前加入(int *)强制转化,就是为了表示把第一个字节的地址强制转化成整形变量的地址,那么就说明这100个字节得按照4个字节一一划分,

p本身所占的内存是静态分配的,p所指向的内存是动态分配的

free(p);//把p指向的内存给释放掉,p本身的内存是静态的,不能由程序员手动释放,把p指向的内存释放掉后就不能读写这块内存上的值了

*/

######1

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值