C语言基础(五--1)

#include <stdio.h>

void swapValue(int x,int y);
void swapValue1(int *x,int *y);

int main(int argc, const char * argv[]) {
    
    /*
     为什么需要指针?
     1.可以使用指针处理数组中存储的数据,它的执行速度要比使用下标快很多.因为下标需要进行位移量偏转,而指针是直接使用内存地址
     2.对于基本数据类型来说,我们在函数中无法更改函数调用处之前的局部变量,使用指针就可以做到
     ...
     
     指针:
       一个变量的地址为该变量的"指针",它是个常量
     
     指针变量:
       指针变量是一个变量,用于存储地址的值
     
     指针变量的声明:
     
       数据类型 *指针变量名;
       int *p;
     
     上面的声明中的 *号表示后面的变量名 p 为一个指针变量,前面的 int 类型表示该指针变量所存储的地址指向的存储单元上是存放一个整型的数据
     
     简要的说,就是上面的格式定义了一个指向 "数据类型" 的 "指针变量"
     
     */
    
   //指针的使用
   //对指针赋值
    int i = 10;
    int *p1 ;    // 可以将int *看做是一个整体,然后p1中存储的是地址类型的数据
    p1 = &i;     //&是取值(地址)运算符
    
      //等价于
//    int *p1 = &i;
    
    /*
     int *p2;
     *p2 = &i;
     错误原因:
     *号运算符优先级大于 = ,首先 *p2进行运算,而 *p2运算是求出p2所存储地址指向的内存的值,而此时p2内没有数据,所以 *p2找不到相应的结果,所以这样是错误的
     注意: *号称为取值运算符
     
     */
   /*
    *号的用法:
    1.表达式中,*号两边都有表达式的话,*号是四则运算的乘法运算
    2.在声明语句中,*号表面后面的变量为一个指针形式的变量
    3.*号如果不在声明语句中,而只是在右边的表达式的话,表明取*号右边变量中所存地址对于内存中的数据(取值)
    */
   
    /*
    int *p3;
    p3 = &i;   //p3中就有了地址数据
//    *p3= &i;
      //等价于 i = &i   //数据类型的不兼容
     */
    
    //通过指针取值
    int i1 = 100;
    int *p4;
    p4 = &i1;
    printf("%d \n",*p4);
//    printf("%d \n",p4);   //打印的结果是十进制的
    //在C语言中提供了另一个控制字符串%p,专门用于打印指针的内存地址值,使得所打印的地址是十六进制的
    printf("%p\n",p4);
    
    //例子
    int m = 10;
    int n = 20;
    //声明两个指针变量
    int *p_i;
    int *p_j;
    p_i = &m;
    p_j = &n;
    printf("m = %d,n = %d\n",m,n);
    
    //通过变量改变数据
    m = 1000;
    n = 2000;
    printf("通过变量修改数据后的值:m = %d,n = %d\n",m,n);
    
    //通过指针修改数据
    *p_i = 100;
    *p_j = 200;
    printf("通过指针修改数据后的值:m = %d,n = %d\n",m,n);
    printf("通过指针修改数据后的值:*p_i = %d,*p_j = %d\n",*p_i,*p_j);
    
    //指针使用进阶
    int i2 = 10;
    int *p5;
    p5 = &i2;
    
//    &*p5;
    /*
     &*p5;
     表达式的含义?
     &和*运算符优先级相等,且是从右往左的顺序结合的
     *p5 = i2
     &*p5 = &i2
     */
    printf("&i2 = %p\n",&i2);
    printf("&*p5 = %p\n",&*p5);
    
    //
//    *&i2;  //实际上就是i2de值
    printf("*&i2 = %d\n",*&i2);
    
    //
    (*p5)++;
    //先找出p5所存储地址指向的存储单元的值,把值进行自加,p5的地址不变
    
    *p5++;
    //++ 与 * 同一优先级,结合方向是从右向左,所以先找出p5所存储地址的值,然后把该值加一,那么现在p5就不再指向变量i2了
    
    //值传递
    int a1 = 10;
    int b1 = 20;
    printf("函数外,交换前:a1 = %d,b1 = %d\n",a1,b1);
    swapValue(a1,b1);
    printf("函数外,交换后:a1 = %d,b1 = %d\n",a1,b1);
    
    /*
     如果想像数组作为函数参数那样,在函数内改变传入局部变量的值后,在函数外部的局部变量的值对应改变,那么应该怎么做?
     我们可以通过指针来作参数,因为指针存放的同样是地址.在C语言中,地址传递也是称为引用传递
     */
    
    //指针作为函数参数
    int a2 = 10;
    int b2 = 20;
    int *p_a2 = &a2;
    int *P_b2 = &b2;
    printf("函数外,交换前:*p_a2 = %d,*p_b2 = %d\n",*p_a2,*P_b2);
    swapValue1(p_a2, P_b2);
    printf("函数外,交换后:*p_a2 = %d,*p_b2 = %d\n",*p_a2,*P_b2);
   
    /*
     理解课本p168页的话
     */
    
    
    
    
    return 0;
}

void swapValue(int x,int y)
{
    int tmp;
    printf("函数内,交换前:x = %d,y = %d\n",x,y);
    tmp = x;
    x= y;
    y = tmp;
    printf("函数内,交换后:x = %d,y = %d\n",x,y);
    
    
}

void swapValue1(int *x,int *y)
{
    int tmp1;
    printf("函数内,交换前:*x = %d,*y = %d\n",*x,*y);
    tmp1 = *x;
    *x = *y;
    *y = tmp1;
    printf("函数内,交换后:*x = %d,*y = %d\n",*x,*y);

}

你可能感兴趣的:(C语言基础(五--1))