// 需求: 编写一个函数 通过指针交换两个整型变量的值

//void exchange(int a,int b){

//

//    

//    

//         int *p = &a;

//         *p = 11;

//         int *p1 = &b;

//         *p1 = 10;

//         printf("%d\n",a);

//         printf("%d\n",b);

//

//}

int main(int argc, const char * argv[]) {

   // 字节是内存当中最小的存储单位

    // 1个字节是8个二进制位

    

    

    // 访问变量

    // 1 直接访问: 通过变量名直接访问

    // 2 间接访问: 通过变量的地址?(内存编号)访问变量

    // 指针变量:保存的是地址

    

//    int *p= NULL;

    //   声明 指针的时候 * 没有特殊意义 只是告诉编译器这是一个指针变量

    

    // int 表示 这个指针变量所指向的内存区域是一个整型存储区域  也就是说 指着变量P指向的内存区域里面 存储的值一个整型

//    

//    int a = 5;

//    // 声明一个指针变量

//    int *p =NULL;

//    // 指针变量指向 a 的存储区域(地址)

//    p  =  &a;

//    // & 取出变量a的地址

    

    // 打印地址的占位符

//    printf("%p\n",p);

//    printf("%p",&a);

//    // 取值符

//    printf("%d",a);

    // *表示指针变量P 所指向地址里面 保存的值

    

    //  通过指针变量P 来打印

//    printf("%d\n",*p);

    // 修改变量a的值

//    a = 3; // 直接访问

//    *p = 30; // 间接访问

//    printf("%d\n",*p);

//    

    

    

    // 打印指针变量占用的字节数

    // 指针变量 占用8个字节  不管你声明数据类型  值跟操作系统有关系

//    printf("%lu\n",sizeof(p));

    

    

    

    

    

    //  指针变量的赋值 相当于 指针的重指向

    

    

    // 指针的运算

    // 地址运算 只有 和减

    // 地址里面的值 可以加减乘除

    // 地址加1 要看指针变量的数据类型

    // 如果是int类型 +1 相当于加 4 个字节

    // 如果  char 类型  地址+1 相当于 1个字节

    

    

//    int a = 3;

//    int b = 5;

//    int *p =&a;

    //系统在分配变量内存得时候 不一定分配的是连续的

    // 数组在分配内存时 肯定分配是连续的内存区域

//    printf("%p\n",&a);

//    printf("%p\n",&b);

//    printf("%d\n",*p);

//    p--;

//    printf("%d\n",*p);

    

    

    

    // 需求: 编写一个函数 通过指针交换两个整型变量的值

 

    

    

    

    // 参数的传递  是实参向形参进行的传递 是一个拷贝的过程 是一个值得传递 地址是不一样的

    

    

    // 交换时本着一个原则  操作的变量的地址 应该是一致的

    

    // 指针与数组

//    int array[4] = {1, 3, 5, 7};

//    printf("%p\n",&array[0]);

//    printf("%p\n",array);

//    // 声明一个指针变量 指向数组(数组的首元素)

//    // 数组的名字 本身就是数组首元素的地址 不需要加取地址符了

//    int *p = array;

//    printf("*p = %d\n",*p);

    

    

    

    

    

    // 取出数组中的元素方法

    // array[下标]

    // *(array + 下标)

    // 利用指针变量p取出数组元素

    // p[下标]

    // *(p + 下标)

    

    

    

    

    

    

    // 计算数组中的元素个数

    

//    int count = sizeof(array) / sizeof(array)[0];

//    printf("%d",count);

    // 需求: 通过指针变量p 能不能求出元素个数

    // 指针变量占8字节  只跟操作系统有关

    // 所以不能求出元素个数

    // array 代表的是整个数组

    // P 代表是指针变量

    // 数组当函数参数是  传递不是整个数组

    // 传递就是数组元素的首地址 (就是传递了指针)

    

     // 指针与字符串

//    char str1[] = "iphone";

//    char str2[] = {'i','p','h','o','n','e'};

//    char *p = str1;

//    // 1 利用指针  打印字符串

//    printf("%s",str1);

//    printf("%s",p);

//    // 2 利用指针 打印字符 h

//    printf("%c",p[2]);

//    printf("%c",str1[2]);

//    printf("%c",*(p+2));

//    printf("%c",*(s tr1 + 2));

//    // 3 h 更改成w

//    strcpy(str1, "ipwone");

//    

//    

//    str[2] = 'l';

//    

    char *strings[3] = {"ios","android","winphone"};

    // 指针数组  数组当中保存的都同一个类型的数据  指针数组中保存都是指针类型 保存都是地址

    printf("%s\n",strings[0]);

    printf("%s\n",*strings);

    

    

    // 如果你声明时 直接声明常量字符串  那么你是不能更改的, 如果你声明时先声明一个字符串(这时这个字符串  是从常量区拷贝 拷贝栈区),这时候你可以对字符串 进行修改