#import <Foundation/Foundation.h>
#define NUM 10
int main(int argc, const char * argv[]) {
// int a = 5;
使用&可以取到a在内存中的首地址。
// printf("%p",&a);
// int a = 10;
定义一个指针变量,并且赋初值NULL
// int * p = NULL;
NULL恒等于0x0
// printf("%p\n",p);
把a的地址赋值给指针变量p,通过p可以找到a的存储单元。
// p = &a;
通过地址间接访问内存单元里的数据
// *p = 8;
// printf("a = %d",a);
/*
int a = 6;
// 此时的*代表定义一个指针变量
int *p = &a;
a = 8;
// 此时的*代表使用地址间接访问内存单元里面的数据,两个*出现的位置不一样,代表的含义也就不一样
// 区别:其面是否有类型修饰符
printf("%d",*p);
*/
// int a = 8;
// int b = 3;
// int *p = &a;
// int *q = &b;
// *p = 4;
// a = 6;
// b = 5;
// *q = 10;
// printf("%d %d",*p,*q);
// int a = 8,b = 9;
// int *m = &a;
// int *n = &b;
// m = n;//指针的重新赋值,意味着指针重指向。
// printf("%d %d",*m,*n);
// int a = 6;
// int b = 7;
// int *p = &a;
// int *q = &b;
// p = q;
// *p = 4;
// 内存单元地址偏低的一段存储空间操作系统在使用。
// 使用指针,必须要有明确的指向。
// int *p;
// *p = 5;
// printf("%d",*p);
// char * p = NULL;
// printf("%lu",sizeof(long *));
// 指针变量所占内存空间的大小和指针的类型没有关系,取决于操作系统的位数,
// int array[5] = {2,6,9};
// printf("%p\n",array);
数组名是这段连续空间的首地址。
// printf("%p\n",&array[0]);
// printf("%p\n",&array[2]);
// 指针运算:p+1相当于p的地址加四个地地之后的新地址,原来的p没有动,p++等价于p = p +1;相当于p的地址加四个字节之后的新地址重新给p赋值,p的指向改变。
// 指针每次加1的字节数跟指针的类型有关系,int*指针是加4个字节,char*指针是加1
// 个字节
// int *p=array;
// *(p+2) = 4;*p = 3;
// p++;
// *(p+1) = 5;
// printf("%d",array[0]);
// int array[3] = {3,5,6};
// int *p = array;
// printf("%d\n",array[1]);
// printf("%d\n",p[1]);
// printf("%d/n",*(p+1));
// printf("%d",*(array+1));
// 数组名不能重指向,是一个常量地址。,不允许重新改值。
// int a = 5;
// int array[3] = {3,4,5};
// /*array = &a;*/ //error数组名不能重指向,是一个常量地址。,不允许重新改值。
// int *p = array;
// p = &a;
// printf("%d",*p);
// int array[NUM] = {0};
// int *p = array;
// for (int i = 0; i<NUM; i++) {
// *(p + i) = arc4random()%101+10;
// printf("%d ",*(p+i));
// }
// for (int i = 0; i < NUM - 1; i++) {
// for (int j = 0; j < NUM - 1 - i; j++) {
// if (*(p + j) > *(p + j + 1)) {
// int temp = *(p + j);
// *(p + j) = *(p +j + 1);
// *(p + j + 1) = temp;
// }
// }
// }
// printf("\n");
// for (int i = 0; i < NUM; i ++) {
// printf("%d ",*(p+i));
// }
// for (int i = 0; i < 9; i++) {
// for (int j = i+1; j < 10; j++) {
// int min = i;
// if (*(p + min) > *(p + j)) {
// min = j;
// }
// if (min != i) {
// int temp = *(p + min);
// *(p + min) = *(p + i);
// *(p + i) = temp;
// }
// }
// }
// printf("\n");
// for (int i = 0; i < NUM; i ++) {
// printf("%d ",*(p+i));
// }
// 不同类型指针的区别
// 1.指针在做运算的时候,每次加1移动的字节数不一样
// 2.通过指针使用*来取值的时候,每次取得字节数不一样。
// short array[4] = {1,2,3,4};
// int *p = (int *)array;//(int float char *)是强制类型转化。
// printf("%d",*(p + 1));
//
// 数组名和一个指向数组首地址的指针变量的异同点
// 相同点:都可以当数组名用来取数组元素。
// 不同点:
//1.使用sizeof测算的时候,编译器会自动检查,如果传入的是一个数组名,则返回的是整个数组所占用的内存空间,如果传入的是一个指针变量,则返回的是一个指针变量所占用的内存空间
// 2.数组名是常量地址,不可以重新指向,指向数组首地址的指针变量是一个变量,允许重新赋值,重指向。
// int array[3] = {1,2,6};
// int *p = array;
// printf("%lu\n",sizeof(array));
// printf("%lu\n",sizeof(p));
// char str[10] = "iphone";
// printf("%s",str + 3);
// char str[10] = "iphone";
// char *p = str;
// *p++ = 'a';
// *(p + 2) = \0;
// printf("%s\n",str);
// printf("%s",p);
// char str[] = "i want an iphone6";
// *(str + 1) = '\0';
// *(str + 6) = '\0';
// *(str + 9) = '\0';
// printf("%s %s %s %s",str,str + 2,str + 7,str + 10);
// char str[10] = "iphone";
// printf("%s\n",str);
// char * string ="iphone";
// printf("%s\n",string);
// 两种形式定义的字符串,这种形式的定义的字符串是把常量区的iphone拷贝到栈区,数组名是常量地址,不能够重新指向,数组里的内容在栈区存储,可以直接修改,
// char str[] = "iphone";
str = "android"; 错误的写法,因为str为常量地址
// strcpy(str, "android");
// *(str +3)='m';
// printf("%s\n",str);
// 这种形式定义的字符串是把常量区的字符串地址直接赋值给一个指针变量,字符串中的内容不可以修改,因为在常量区存储
// 但是指针式一个变量,可以重新指向
// char str[] = "i want an iphone7";
// int count = 0;
// for (int i = 0; i < strlen(str); i++) {
// if (* (str + i) == ' ') {
// count ++;
// }
// }
// printf("空格数为:%d",count);
// char str[] = "i want an iphone7";
// char *p = str;
// int count = 0;
// while (*p != '\0') {
// if (* p ==' ' ) {
// count ++;
// }
// p++;
// }
// printf("空格数为:%d",count);
return 0;
}