20170419

指针:
所有类型的指针在内存中都占4个字节。
指针变量的类型在转换过程中不会导致地址数据受影响。
影响的是和指针配对的普通存储位置。
  1 #include <stdio.h>
  2 int main() {
  3     int num = 300;
  4     int *p_num = &num;
  5     printf("p_num是%p,*p_num是%d ", p_num, *p_num);
  6     printf("(char*)p_num是%p, *(char*)p_num是%d ", (char*)p_num    , *(char*)p_num);
  7     return 0;
  8 }
  结果:p_num是0xbfce7188,*p_num是300
(char*)p_num是0xbfce7188, *(char*)p_num是44
p_num强制转换成char*类型,字节数由4个变成1个,虽然它自身地址数据没有影响,
但是它配对的普通存储位置的值发生了变化。
void*也是一种指针类型
这种类型的指针只表示其中记录了一个地址数据但没有告诉我们可以根据它找到什么类型的存储位置。
这种类型的指针不可以直接加*使用,必须首先进行强制类型转换
这种指针通常用来记录来源不明的地址数据。
指针变量也可以作为函数的形参使用
void*类型的指针经常会作为函数的形参使用
  例子:
  1 #include <stdio.h>
  2 //type为1表示char类型,2表示int类型,规定一下
  3 void print(void *p_val, int type) {
  4     if(type == 1) {
  5         printf("%c ", *(char*)p_val);
  6     }
  7     else if(type == 2) {
  8         printf("%d ", *(int*)p_val);
  9     }
 10     else {
 11         printf("%g ", *(float*)p_val);
 12     }
 13 }
 14
 15 int main() {
 16     char ch = 'g';
 17     int num = 10;
 18     float fnum = 4.6f;
 19     print(&ch, 1);
 20     print(&num, 2);
 21     print(&fnum, 0);
 22     return 0;
 23 }
指针类型作为返回值
例子:
  1 #include <stdio.h>
  2 //找到比较大的数
  3 int max(int num, int num1) {
  4     return num > num1 ? num : num1;
  5 }
  6 //找到比较大的数的存储位置
  7 int *max1(int *p_num, int *p_num1) {
  8     return *p_num > *p_num1 ? p_num : p_num1;
  9 }
 10 int main() {
 11     int num = 3, num1 = 7;
 12     printf("3的地址是%p ", &num);
 13     printf("7的地址是%p ", &num1);
 14     printf("比较大的数是%d ",max(num, num1));
 15     printf("比较大的数的地址是%p ", max1(&num, &num1));
 16     return 0;
 17 }
 
指针类型的返回值可以用来表示一个存储位置
绝不可以把局部变量的地址赋值给指针类型的返回值变量(局部变量的生命周期决定的)

地址数据所能参与的四则计算
地址 + 整数, 地址 - 整数, 地址 - 地址
以上计算中的整数都是由单位的,单位由地址数据的类型决定
  1 #include <stdio.h>
  2 int main() {
  3     int num = 0, num1 = 0;
  4     int *p_num = &num, *p_num1 = &num1;
  5     printf("p_num是%p, p_num + 3是%p ", p_num, p_num + 3);
  6     return 0;
  7 }
结果:p_num是0xbff8ae20, p_num + 3是0xbff8ae2c
整数类型指针,+3加3个整数存储位置大小,12个字节
例如:
  1 #include <stdio.h>
  2 int main() {
  3     int num = 0, num1 = 0;
  4     int *p_num = &num, *p_num1 = &num1;
  5     printf("p_num是%p, p_num + 3是%p ", p_num, p_num + 3);
  6     printf("p_num1是%p, (char*)p_num1 + 3是%p ", p_num1, (char*    )p_num1 + 3);
  7     return 0;
  8 }
  结果:
  p_num是0xbfc86f30, p_num + 3是0xbfc86f3c
  p_num1是0xbfc86f34, (char*)p_num1 + 3是0xbfc86f37差3是由于char类型+3加3个字节
 例子:
  1 #include <stdio.h>
  2 int main() {
  3     int num = 0, num1 = 0;
  4     int *p_num = &num, *p_num1 = &num1;
  5     printf("p_num是%p ", p_num);
  6     printf("p_num1是%p ", p_num1);
  7
  8     printf("p_num1 - p_num是%d ", p_num1 - p_num);
  9     return 0;
 10 }
 结果:
    p_num是0xbfce6cf0
    p_num1是0xbfce6cf4
    p_num1 - p_num是1 两者地址相差4位,位1个int存储位置大小。
    地址数据相减的结果是整数,这个整数也是有单位的,单位由地址数据的类型决定。
    
数组名称和指针的差异:
1.数组名称不可以被赋值,指针变量可以被赋值
2.进行sizeof计算以后结果不同(数组名称做sizeof计算是整个数组大小,指针变量做sizeof计算是指针变量本身大小,为4)
3.对他们分别取地址结果不同

可以利用指针变量作为循环变量处理数组中的每个存储位置
例子:  
  1 #include <stdio.h>
  2 int main() {
  3     int arr[] = {1, 2, 3};
  4     int *p_num = arr;
  5
  6     for(p_num = arr; p_num <= arr + 2; p_num++) {
  7         printf("%d ", *p_num);
  8     }
  9     printf(" ");
 10     return 0;
 11 }
 
 指针变量声明时也可以使用const关键字
 const int *p_num
 上面的指针自己的存储位置可以被赋值,但配对的普通存储位置不可以被赋值
 int * const p_num
 上面的指针自己的存储位置不可以赋值,但配对的普通存储位置可以被赋值

原文地址:https://www.cnblogs.com/dongjian16/p/6735325.html