天天看点

c指针

内存的编号:

一个字节(8个位)一个字节编号(即 8个1 或者 8个0)

一个字节一个编号:编号即地址。

地址(内存单元的编号)

指针:

指针的重要性

1、 表示一些复杂的数据结构

2、快速的传输数据

3、使函数返回一个以上的值

4、能够直接访问硬件

5、能够方便的处理字符串

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

总结:指针是c语言的灵魂

#include <stdio.h>

int main(void)

{

int * p;

//p是指针变量(地址变量)的名字,int * 表示p编量存放的int类型变量的地址;

// int * p 不应该定义了一个名字叫做 *p的变量;

// int * p 应该这样理解: p是变量名,p变量的数据类型的 int * 类型;

// 所谓int * 类型 实际就是存放 int变量地址的类型。

int i;

p = &i;

/*

1、p保存了i的地址,因此p指向i,

2、p不是i,i也不是p,更准确的说:修改p的值不影响i;

修改i也不影响p;

3、如果一个指针变量指向了某个普通变量,则*指针变量

就完全等同于 普通变量

例子:

如果p是个指针变量,并且p存放了普通变量i的地址

则p指向了普通变量i。

*p 就完全等同于 i;

即 在使用出现 *p的地方都可以替换成 i;

在所有出现 i 的地方都可以替换成 *p;

*/

return 0;

}

1、指针就是地址,地址就是指针;

2、地址就是内存单元的编号;

3、指针变量是存放地址的变量;

4、指针和指针变量的两个不同的概念;

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

实际它们含义并不一样;

6、指针的本质就是一个操作受限的非负整数(只能进行减运算)。

指针的基本类型:

1、

*号的用法:

1、乘法;

2、定义指针变量

//定义了一个名字叫p的变量,int * 表示只能存放int变量的地址;

3、指针运算符

该运算符放在已经定义好的指针变量的前面;

如果p是一个已经定义好的指针变量;

则*p表示 以p的内容为地址的变量;

指针和数组:

指针和一维数组

一维数组名是个 指针 常量

它存放的是一维数组的地址;

下标和指针的关系

如果p是个指针变量,则

p[i]永远等价于*(p+i)

确定一个一维数组需要几个参数

如果一个函数要处理一个一维数组,则需要接收该数组的那些信息。

需要两个参数:

数组第一个元素的地址,

数组的长度;

指针变量的运算

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

(如果两个指针变量指向的是同一块连续空间的不同的存储单元,

这两个指针变量才能相减。)

一个指针变量到底占几个字节;

知识:

sizeof(数据类型)

功能:返回值就是该数据类型所占的字节数;

例子:sizeof (int) = 4; sizeof(char)= 1;

sizeof(double) = 8;

sizeof(变量名)

功能:返回值是该变量所占的字节数;

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

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

假设r指向double类型变量(8个字节)

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

一样,本身所占字节数为4;(32个状态,即32跟线)

总结:一个指针变量,无论它指向的变量占几个字节;

该指针变量 本身 只占四个字节

一个变量的地址使用该变量 首字节的地址 来表示;

内存中一个字节(8bit)对应一个编号

指针和二维数组

printf("%#x\n",&a[0]); //a[0]地址的输出;

如何通过被调函数改变主调函数的值:

1、实参必须为该普通变量的值。

2、形参必须为指针变量。

3、在被调函数中通过

*形参名 = ....

的方式就可以修改主调函数相关变量的值。

专题: (非常重要)

动态内存控制:

传统数组的缺点:

1、数组长度必须事先制定,并且只能是常整数;不能说变量;

int a[5]; //ok

int len = 5; int a[len]; //error

2、传统形式定义的数组,该数组的内存程序员无法手动释放。

数组一旦定义,系统就会为该数字分配存储空间就会一直存在。

除非数组所在地函数运行结束。

在一个函数运行期间,系统为该函数中数组分配的

内存空间会一直存在,直到该函数运行完毕时,

数组的空间才会被系统释放。

3、数组的长度一旦定义,其长度就不能在更改。

数组的长度不能在函数运行的工程中动态的扩充或缩小。

4、传统方式定义的数组不能跨函数使用。

A函数定义的数组,在A函数运行期间可以被其他函数使用,

但A函数运行完毕之后,A函数中的数组将无法被其他函数使用。

原因是: 调用函数运行完毕,数组空间被释放了。。。

为什么需要动态分配内存:

动态数组很好的解决了传统数组的这4个缺陷。

传统数组也叫静态数组。

动态内存分配举例___动态数组的构造(难点)

静态内存和动态内存的比较

1、静态内存是由系统自动分配,由系统自动释放;

2、静态内存是在栈分配的,

3、动态内存是有程序员手动分配, 手动释放的;

4、动态内存是在堆分配的,

跨函数使用内存的问题:

地址:内存单元的编号;

继续阅读