设为首页 加入收藏

TOP

C语言 指针 地址算数运算 字符指针 指针数组 多维数组 函数指针(一)
2014-11-23 19:55:51 来源: 作者: 【 】 浏览:53
Tags:语言 指针 地址 算数 运算 字符 多维 函数

.

1. 地址算数运算示例

指针算数运算 : int *p, array[5]; p = array; p 指向一个 int 数组元素, p + i 的地址时数组中第 i 个元素的地址, 即 p + i 指向 第 i 个元素;

存储分配示例函数 :

-- char *alloc(int n) 函数 : 传入分配的字符个数, 返回连续字符存储单元指针, 这个指针可以存储 n 个字符元素;

-- int afree(char *p) 函数 : 释放分配的内存空间;

-- 缺陷 : 分配内存的时候, 有一个偏移量, 偏移量的大小代表已经分配了多少内存, 释放内存必须按照分配内存的顺序释放, 否则偏移量就会乱;

-- 内存分配原理 : 设置一个大数组, 内存分配就分配这个数组的中的空间, alloc 和 afree 函数操作的是指针, 不是数组, 因此这个数组可以隐藏, 将数组定义为static 类型, 那么在其它文件中, 不能访问该数组, 设置一个偏移量, 当分配 n 个元素, 偏移量就加上 n, 当偏移量 等于 数组大小, 说明内存全部分配完毕;

-- 偏移量设计 : 设置一个偏移量, 偏移量始终指向大数组的下一个空闲的元素地址, 当分配内存的时候, 通过计算 数组首地址 + 数组长度 - 偏移量 >= 分配大小 , 成立的话就可以分配内存, 分配内存就是将偏移量 加上 分配大小; 释放内存的时候, 就将偏移量 指向 释放内存的指针的首地址, 因此 要保持后进先出的次序;

代码 :

/*************************************************************************
    > File Name: alloc_afree.c
    > Author: octopus
    > Mail: octopus_work.163.com 
    > Created Time: 2014年03月17日 星期一 19时34分08秒
 ************************************************************************/

#include
  
   

//用于内存分配载体的大数组大小
#define ALLOCSIZE 1000
/*
 * 该数组就是用于内存分配的主体, 
 * 设置为static , 意味着只能在本文件中访问, 在其它文件中不能访问
 */
static char alloc_buf[ALLOCSIZE];
/*
 * 将alloc_buf 数组的首地址赋值给allocp字符指针
 * 对allocp 进行算数运算, 每次加减都是 char * 运算数
 * allocp的值就可以代表所分配内存的首地址
 */
static char *allocp = alloc_buf;

/*
 * 分配n个char类型数组的内存, 
 * 如果分配成功, 返回分配的内存的指针,
 * 如果分配失败, 返回0
 */
char *alloc(int n)
{
	//如果大数组剩余的空间可以分配, 那么就进行分配
	if(alloc_buf + ALLOCSIZE - allocp >= n)
	{
		//分配空间, allocp 指向下一个空间的内存首地址
		allocp += n;
		//返回分配的空间首地址
		return allocp - n;
	}else //如果数组剩余空间不足, 返回0
	{
		return 0;
	}
}

/*
 * 释放分配的内存
 * 释放内存就是将allocp 指针地址指向 要释放的内存指针首地址
 */
void afree(char *p)
{
	//释放内存的前提是 内存必须是大于数组首地址, 小于数组尾地址
	if(p >= alloc_buf && p < alloc_buf + ALLOCSIZE)
	{
		allocp = p;
		printf(allocp = %p 
, allocp);
	}
}

int main(int argc, char **argv)
{
	char *p1;
	char *p2;
	char *p3;
	char *p4;

	//打印数组首地址
	printf(alloc_buf = %p 
, alloc_buf);

	//分配300个字符内存
	p1 = alloc(300);
	printf(char *p1 = alloc(300), p1 = %p 
, p1);

	p2 = alloc(300);
	printf(char *p2 = alloc(300), p2 = %p 
, p2);

	p3 = alloc(300);
	printf(char *p3 = alloc(300), p3 = %p 
, p3);

	//上面已经分配了900了, 在分配就溢出了, 这里alloc()函数返回0
	p4 = alloc(300);
	printf(char *p4 = alloc(300), p4 = %p 
, p4);

	afree(p4);
	afree(p3);
	afree(p2);
	afree(p1);
}

  

执行结果 :

octopus@octopus-Vostro-270s:~/code/c/pointer$ gcc alloc_afree.c 
octopus@octopus-Vostro-270s:~/code/c/pointer$ ./a.out 
alloc_buf = 0x804a060 
char *p1 = alloc(300), p1 = 0x804a060 
char *p2 = alloc(300), p2 = 0x804a18c 
char *p3 = alloc(300), p3 = 0x804a2b8 
char *p4 = alloc(300), p4 = (nil) 
allocp = 0x804a2b8 
allocp = 0x804a18c 
allocp = 0x804a060 


函数执行示例图 :

-- alloc()函数示例图 :

/

-- afree()函数示例图 :

/

指针初始化 : static char *allocp = alloc_buf, 将char数组的首地址赋值给char类型指针;

-- 初始化内容 : 0 或者 地址;

-- 地址限定 : 对指针初始化的地址, 该地址存储的数据的类型必须是该指针类型;

内存可用判断 : alloc_buf + ALLOCSIZE - allocp >= n;

-- 意义 : alloc_buf 是数组首地址, ALLOCSIZE 是数组大小, allocp是可用内存偏移量, alloc_buf + ALLOCSIZE -allocp 结果是可用的内存量, 如果可用内存大于n, 则可以赋值;

-- 如果内存不足 : 内存不足, 将0作为地址返回, C语言中设定 0 不是有效的数据地址, 0地址的数据为NULL, 返回0表示发生了异常事件;

指针整数转换特例 : 指针 和 整数 不能相互转换;

-- 通常情况 : 指针 和 整型 之间不能相互转换, 0 除外;

-- 特例 : 常量 0 可以赋值给指针, 指针 可以和 常量 0 进行比较, 这里注意是常量;

-- 0的特殊性 : NULL 可以代替 常量0, 常量0 是一个特殊值;

指针运算 :

-- 比较运算 : 两个指针都指向同一个数组中的元素, 那么两个指针之间的比较是有意义的, 指向两个不同数组元素的指针之间比较无意义;

-- 加减运算 : 指向数组元素的指针, 进行加减运算, 地址的计算按照 运算数 * 指针指向元素的大小 进行计算;

计算字符串长度示例 :

-- 代码 :

/*************************************************************************
    > File Name: strlen_pointer.c
    > Author: octopus
    > Mail: octopus_work.163.com 
    > Created Time: 2014年03月17日 星期一 21时38分52秒
 ************************************************************************/

#include
  
   

//计算字符串长度
int strlen(char *s)
{
	//指针 p 记录首地址
	char *p = s;
	//循环获取字符串最后的字符首地址
	while(*p != '')
		p++;
	//字符串占用的内存地址个数
	return p - s;
}

int main(int argc, char **argv)
{
	char *c = fuck you!!;

	printf(length = %d 
, strlen(c));

	return 0;
}

  

-- 执行效果 :

octopus@octopus-Vostro-270s:~/code/c/pointer$ gcc strlen_pointer.c 
octopus@octopus-V
首页 上一页 1 2 3 4 5 下一页 尾页 1/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇深入理解 C 指针阅读笔记 -- 第一.. 下一篇深入理解C语言-08 库函数

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: