ostro-270s:~/code/c/pointer$ ./a.out
length = 10
指针差值类型 :
-- ptrdiff_t : 该类型定义在 stddef.h 头文件中, 表示两个指针之间的带符号的差值;
-- size_t : 该类型定义在 stdio.h 头文件中, size_t 可以作为 sizeof 返回的无符号整型;
指针运算一致性 : 指针运算会自动考虑其指向的元素的长度, p 指向一个类型元素 a, 不管 a 占多少字节, p++ 的下一个元素都指向下一个 同类型的元素;
指针之间的有效运算 : 除下面几种合法运算之外, 其它运算都是非法的, 但不会报错, 会警告;
-- 赋值 : 同类型指针之间的赋值运算;
-- 算数 : 指针与整数的加减运算;
-- 0相关 : 指针与0 的赋值运算, 比较运算;
2. 字符指针与函数示例
字符串常量 : 字符串常量是一个字符数组;
-- 字符串常量界定 : 字符数组以 '' 结束, 程序通过检查 NULL 字符找到字符串的结尾;
-- 长度大于1 : 字符串常量占据的存储单元 比 字符的个数 多1位, 这一位是 '';
常量字符串访问方式 : 通过指针进行访问, 指针指向常量字符串的第一个字符, 程序可以通过这个指针操作字符串常量;
字符串定义方式 :
-- 数组 : char array[] = fuck; array 存放 fuck 字符串 和 '', array 地址是字符串首地址;
-- 指针 : char *c = fuck; 将字符串的首地址赋值给指针c, 没有经过字符串复制;
-- 区别 : 数组 - array 指向的地址不能改变, 单个字符可以修改; 指针 - c 指向字符串常量, 可以被修改指向其它地址, 修改字符串内容没有意义, 这样会在创建一个字符串常量, 并将首地址赋值给指针;

示例代码 : 分别用数组 和 指针 用法 拷贝字符串, 字符串比较;
/*************************************************************************
> File Name: string.c
> Author: octopus
> Mail: octopus_work.163.com
> Created Time: Tue 18 Mar 2014 12:34:20 AM CST
************************************************************************/
#include
/*
* 字符串拷贝
* 将 source[i] 赋值给 density[i], 每次循环 i++
* 当density[i] == ''的时候停止循环
*/
void strcpy_array(char *density, char *source)
{
int i = 0;
while((density[i] = source[i]) != '')
i++;
}
/*
* 字符串拷贝
* *density++ 是对*density地址指向的值赋值, 然后地址进行自增操作
* *source++ 是先取出source 指向的地址的值, 然后地址进行自增操作
*/
void strcpy_pointer(char *density, char *source)
{
while(*density++ = *source++);
}
/*
* s[i] == t[i] 前提下 s[i] = ''
* 此时 返回 s[i] - t[i]
* 如果返回0
*/
int strcmp_array(char *s, char *t)
{
int i;
for(i = 0; s[i] == t[i]; i++)
if(s[i] == '')
return 0;
return s[i] - t[i];
}
int strcmp_pointer(char *s, char *t)
{
for(; *s == *t; s++, t++)
if(*s == '')
return 0;
return *s - *t;
}
int main(int argc, char **argv)
{
char *source = octopus;
char density[10];
printf(strcmp_array = %d
, strcmp_array(density, source));
printf(strcmp_pointer = %d
, strcmp_pointer(density, source));
strcpy_pointer(density, source);
//打印字符串, 使用 字符串首地址 替代 %s;
printf(source = %s
, source);
printf(density = %s
, density);
}
运行结果 :
[root@ip28 pointer]# gcc string.c
[root@ip28 pointer]# ./a.out
strcmp_array = -239
strcmp_pointer = -239
source = octopus
density = octopus
* 和 自增(减) 运算 :
-- *source++ : 上面的该表达式的意义是 执行 自增运算之前, source 指针指向的字符, 读取到该字符之后, 该指针指向的地址 +1;
-- *density++ = *source++ : source指针自增前, 现将其指向的字符 赋值给 density 之前指向的地址的字符, 然后将 source 指针 +1;
-- 入栈 : *p++ = val, 这是标准的入栈操作, 将val压入栈, 然后指针自增1, 注意, 这里最后一个栈多加了一个1, 然后出栈的时候要先减1 在取值;
-- 出栈 : val = *--p, 这是标准的出栈操作, 现将指针减一, 然后取出指针指向的数据, 因为指针总是指向首地址, 如果我们想要取出某一段的值, 先要将指针指向首地址才可以;
3. 指针数组 指向指针的指针 示例
案例需求 :
-- 实现功能 : 在单个运算中处理长度不一的文本, 处理可变文本行数据;
-- 实际功能 : 从标准输入流中输入多个字符串, 每个字符串都使用指针指向字符串的首地址, 然后将指针存放到数组中, 对字符串数组进行排序, 按照字典顺序输出;
引入指针数组 :
-- 比较操作 : 对两个字符串进行移动 比较的时候, 使用 指向它们的指针进行操作, 比较的时候直接使用下标逐一对比;
-- 拷贝操作 : 字符串拷贝的时候, 直接将指针赋值给另一个指针即可, 不用在对文本行进行操作;
-- 好处 : 消除了移动文本带来的内存管理 和 开销;
函数设计 :
-- 设置函数 : 读取输入行, 文本排序, 打印文本行, 设置上面三个函数, 在 main 函数中控制函数执行;
-- 声明函数 : 在文件开始先声明一下函数, 那么在整个文件中就可以使用这个函数了, 即使函数定义在 main 函数的后面, 也可以调用;
程序要点 :
-- 输入流读取字符串 : 在for循环中获取字符, 当获取到 EOF 或者 ' ' 的 或者 获取字符超过数组大小 的时候停止获取, 返回 获取的字符串 和 个数;
-- 创建字符指针数组 : 当获取到的字符串个数为0, 停止获取字符串, 然后统计字符串个数, 根据字符串个数分配字符指针数组大小;
-- 递归排序 :
-- 打印数组 : 遍历指针数组, 将指针指向的字符串打印出来;
C程序代码 :
/********************************************************************