指针----------指针就是地址
数据访问的两种形式:1直接访问2间接访问
地址:内存单元的编号 64位二进制
数据类型:基本数据类型 构造类型 指针类型 void类型
指针变量:指针在定义变量的过程中是一种数据类型,但在开发过程中指针是地址
指针变量 所占字节值与操作系统有关
int *中间虽然有空格 但他是整型指针类型
32位操作系统 指针变量都占4个字节
64位操作系统 指针变量都占8个字节//-fno-odjc-arc
指针可以跨作用域修改值
NULL 一般作为指针的初始值 恒等于零;
取址运算符:&取址运算符 可以取出变量的地址 用%p可以打印地址
取值运算符:*取值运算符 可以取出变量(地址)的值
int *或char *是一个整体 表示是整型的指针或char型的指针 也就是说前面有类型标识符 ,*就不是取值运算符
指针的算术运算:指针的算术运算只有加减,指针的类型决定他移动几个字节
1,加的话是往高位移动
2,减的话是往低位移动
偏移量
指针的重指向:指针变量可以赋值 赋值的话 指针就指向了另一块区域(相同类型,不同类型的话不匹配)
数组:用连续的内存空间 存储数据的构造类型
数组名:数组元素首地址
1 int *p = arr;
2 int *p1 = &arr[0];//1=2
*p + 1; 此时先取的arr[0]值 然后把值加1
*(p + 1); 此时取的是arr[1]
*(p+1)=6-------*(p+i) 等价于 p[i];
指针与数组的不同
1 所占内存空间不同,指针所占内存空间只与操作系统有关,而数组是由数组元素个数 和数组中的元素类型决定的
2 数组名是一个常量,指针是一个变量
字符数组元素的首地址 也恒等于数组名
指针数组 数组元素都是指针
数组的长度:
printf("%lu
",sizeof(arr));(注意 )
数组元素个数:
int count;
count = sizeof(arr)/sizeof(int);
1.printf(“%d
”,count);
char name[10] = "liubei";
printf("%p ",&name[0]);
printf("%p ",name);
//我们可以通过取值符操作单个字符
printf("%c ",*(name+1));
//*(name + i); 等价于 name[i];
printf("%lu ",sizeof(name));
int count = 0;
char *p = name;
while (*p != ' ') {
count++;
p++;
}
printf("%p ",&name[0]);
printf("%p ",name);
//我们可以通过取值符操作单个字符
printf("%c ",*(name+1));
//*(name + i); 等价于 name[i];
printf("%lu ",sizeof(name));
int count = 0;
char *p = name;
while (*p != ' ') {
count++;
p++;
}
printf("%d
",count);
2.
char *strings[3] = {"ios","android","win8"};
for (int i = 0; i < 3; i++) {
printf("%p ",(strings + i));
}
for (int i = 0; i < 3; i++) {
printf("%p ",(strings + i));
}
注意:(strings + i) 等价于 strings[i];
指针代码:
#import <Foundation/Foundation.h>
void swap(int *pa,int *pb);
void swap(int *pa,int *pb){
int temp = *pa;
*pa = *pb;
*pb = temp;
printf("%d %d ",*pa,*pb);
}
int Swap(int a,int b);
int Swap(int a,int b){
a = a ^ b;
b = a ^ b;
a = a ^ b;
return a;
return b;
*pa = *pb;
*pb = temp;
printf("%d %d ",*pa,*pb);
}
int Swap(int a,int b);
int Swap(int a,int b){
a = a ^ b;
b = a ^ b;
a = a ^ b;
return a;
return b;
}
int main(int argc, const char * argv[]) {
int a = 3;
int b = 4;
swap(&a, &b);
// void *p = NULL;
// int *p1 = NULL;
// int *p1 = NULL;
// printf("%p
",p1);
// int *pp = 3;
// printf("%lu
",sizeof(pp));
// printf("%p ",pp);
// char *p2 = NULL;
// float *p3 = NULL;
// printf("%p ",p1);
// printf("%p ",p2);
// printf("%p ",pp);
// char *p2 = NULL;
// float *p3 = NULL;
// printf("%p ",p1);
// printf("%p ",p2);
// printf("%p
",p3);
// 取址运算符&
// int a = 3;
// int *pa = &a;
// //地址是十六位的十六进制数
// printf("%p ",pa);//地址:0x7fff5fbff7bc
//
// int *pa = &a;
// //地址是十六位的十六进制数
// printf("%p ",pa);//地址:0x7fff5fbff7bc
//
// printf("%d
",*pa);//数值:3
// int b = 5;
// int *pb = &b;
// printf("%p ",pb);
// printf("%d ",*pb);
// char c = 7;
// char *pc = &c;
// printf("%p ",pc);
// printf("%d ",*pc);
// float d = 8;
// float *pd = &d;
// printf("%p ",pd);
// int *pb = &b;
// printf("%p ",pb);
// printf("%d ",*pb);
// char c = 7;
// char *pc = &c;
// printf("%p ",pc);
// printf("%d ",*pc);
// float d = 8;
// float *pd = &d;
// printf("%p ",pd);
// printf("%f
",*pd);
// int *pd = 0x7fff5fbff78c;不直接给指针变量赋值地址
// int a = 3;
// int *pa = &a;
// printf("%p ",pa++);//加4
// printf("%p ",pa--);//减4
// printf("%p ",pa);
// for (int i = 0; i < 5; i++) {
// printf("%p ",(pa + i));
// }
// float b = 6;
// float *pb = &b;
// printf("%p ",pb++);
// for (int i = 0; i < 6; i++) {
// printf("%p ",(pb + i));
// }
// char c = 7;
// char *pc = &c;
// printf("%p ",pc--);
// for (int i = 0; i < 6; i++) {
// printf("%p ",(pc - i));
// int *pa = &a;
// printf("%p ",pa++);//加4
// printf("%p ",pa--);//减4
// printf("%p ",pa);
// for (int i = 0; i < 5; i++) {
// printf("%p ",(pa + i));
// }
// float b = 6;
// float *pb = &b;
// printf("%p ",pb++);
// for (int i = 0; i < 6; i++) {
// printf("%p ",(pb + i));
// }
// char c = 7;
// char *pc = &c;
// printf("%p ",pc--);
// for (int i = 0; i < 6; i++) {
// printf("%p ",(pc - i));
// }
// int a = 3;
// int *pa = &a;
// char c = 'm';
// int *pa = &a;
// char c = 'm';
// pa = &c;//不建议,不匹配的类型
// printf("%d
",*pa);
// int b = 5;
// int *pb = &b;
// pa = &b;
// int *pb = &b;
// pa = &b;
// printf("%d
",*pa);
// int d = 8;
// int *pd = &d;
// pd = &d;
// printf("%d ",*pd);
// pd = &d;
// printf("%d ",*pd);
// printf("%p
",pd);
// int arr[3] = {2,5,0};
// for (int i = 0; i < 3; i++) {
// printf("%p ",&arr[i]);
// }
// for (int i = 0; i < 3; i++) {
// printf("%p ",&arr[i]);
// }
// printf("%p
",arr);
// printf("%p
",arr[0]);
// char name1[] = {'z','h','u'};
// count = sizeof(arr)/sizeof(int);
char name[10] = "liubei";
printf("%p ",&name[0]);
printf("%p ",name);
//我们可以通过取值符操作单个字符
printf("%c ",*(name+1));
//*(name + i); 等价于 name[i];
printf("%lu ",sizeof(name));
int count = 0;
char *p = name;
while (*p != ' ') {
count++;
p++;
}
// count = sizeof(arr)/sizeof(int);
char name[10] = "liubei";
printf("%p ",&name[0]);
printf("%p ",name);
//我们可以通过取值符操作单个字符
printf("%c ",*(name+1));
//*(name + i); 等价于 name[i];
printf("%lu ",sizeof(name));
int count = 0;
char *p = name;
while (*p != ' ') {
count++;
p++;
}
printf("%d
",count);
char *strings[3] = {"ios","android","win8"};
for (int i = 0; i < 3; i++) {
printf("%p ",(strings + i));
}
for (int i = 0; i < 3; i++) {
printf("%p ",(strings + i));
}
//(strings + i) 等价于 strings[i];
//xxxxxxxx int *number[5] = {1,2,3,4,5};xxxxxxxxx
// for (int i = 0; i < 5; i++) {xxxxxxxxxxxx
// for (int i = 0; i < 5; i++) {xxxxxxxxxxxx
// printf("%p
",(number + i));xxxxxxxxxxxxxxxxxxxxxx
// }//xxxxxxxxxxxxxxxx
// int x = 3;
// int y = 5;
// //函数运行过程中,形参是拷贝了实参的值 实参不会改变
// swap(x, y );
// int y = 5;
// //函数运行过程中,形参是拷贝了实参的值 实参不会改变
// swap(x, y );
// printf("%d %d
",x,y);
作业:
char arr[3][20] = {"liubei","zhangfei","guanyu"};
char *p[3] = {};
for (int i = 0; i < 3; i++) {
p[i] = arr[i];
}
for (int i = 0; i < 3 - 1; i++) {
for (int j = 0; j < 3 - 1 - i; j++) {
if (strcmp(p[j], p[j+1]) > 0) {
char *temp = p[j];
p[j] = p[j+1];
p[j+1] = temp;
}
}
}
for (int i = 0; i < 3; i++) {
printf("%s ",p[i]);
}