void
change2(
int
n)
{
n= 10 ;
}
void yunSun( int x, int y, int *add, int *sub, int *cheng, float *chu)
{
*add=x+y;
*sub=x-y;
*cheng=x*y;
*chu=x/( float )y;
}
int main( int argc, const char * argv[]) {
#pragma mark- 指针
/*
1. 内存中,如何存储数据,如何读取数据?
程序运行时,系统会为数据分配内存单元,存储数据
2. 内存是由多个连续的内存单元组成,
内存单元用于存储数据,每个内存单元占 1 个字节, 1 个字节 =8 个二进制位
内存单元地址:内存单元的编号,连续的,便于访问内存单元,就像门牌号一样。
3. 访问数据的两种方式:
( 1 ):直接访问,定义变量存储数据,通过变量名访问数据。
比如: int a=10;int b=a;
通过变量 a 访问内存中的数据。
( 2 ):间接访问:通过内存单元地址访问内存中的数据,任何数据都是存储在内存中的存储单元中。
4. 内存单元的地址,被称为指针。
指针变量:存储指针(地址)的变量。
定义指针变量:
int *p=NULL;
float *q=NULL;
char *r=NULL;
NULL 是空指针,相当于 0 , NULL 是给指针变量赋值。
指针变量的语法:
类型修饰符 * 指针变量名 = 初值 ( 地址 );
* :定义的变量是一个指针变量,存储的内容是地址。
类型修饰符:地址指向的存储单元中的类型(即通过地址找到的数据类型)
指针变量通常被称为指针
int *p=NULL; p 是整数指针
float *q=NULL; q 是浮点数指针
char *r=NULL; r 是字符型指针
-----------------------------------
通过指针访问存储单元,必须先获取单元的地址
取地址符 :& 获取变量的地址
输出地址: %p
// 定义一个指针变量 int *p
*/
// int *p;// ( *p 先读取 p 中的存储地址,根据地址访问存储单元)
// int a=90;
// 指针变量 p 指向了变量 a
// p=&a;
// printf("%p\n",p);
// printf("%d\n",*p);
// a=20;
// printf("%d",*p);
//(1) 间接传值 指针的应用场景
// int a=20;
// change(&a);
// printf("%d\n",a);
//
//
// int b=20;
// change2(b);
// printf("%d\n",b);
// ( 2 )可以操作多个值
// int add,sub,cheng;
// float chu;
// yunSun(8,12,&add,&sub,&cheng,&chu);
// printf("add=%d,sub=%d,cheng=%d,chu=%.2f\n",add,sub,cheng,chu);
#pragma mark- 内存
// int a=8;
// float c=1.2;
// double d=5.32;
// int *p=&a;
// float *p2=&c;
// double *p3=&d;
// printf("%lu %lu %lu",sizeof(p),sizeof(p2),sizeof(p3));
// 所有基本类型的指针字节都是根据计算机位数决定的,如果是 32 位,那么指针字节数则是 4 ,如果是 64 位,指针字节数则是 8 ,
#pragma mark- 错误的写法
/*
int *p 只能指向 int 类型的数据
int *p;
double d=10.0;
p=&d;
*/
/*
int *p=&a;
*p=a;
*/
// double d=10.5;
// double d2=10.5;
// double *p;
// p=&d;
// *p=5.6;
#pragma mark- 指针和数组
//1. 数组名是常量地址,不可以重新指向,而指针可以发生改变,可以重指向。
//2. 使用指针,可以计算出有结果表示的数组的长度,比如字符串,但是无法计算出普通数组的长度 .
// 数组元素的访问地址
// int ages[5];
// int *p;
// p=ages;
// printf("%p",p);
/*
1> 数组名 [ 下标 ] age[i]
2> 指针数组名 [ 下标 ] p[i]
3>*(p+i)
*/
// int ages[5]={10,45,12,43,41};
// int *p;
// p=&ages[0];// 指针变量 p 指向了数组的首地址
// printf("%p\n",p);
// p=ages;// 数组名就是数组的首地址,也是数组的首元素地址
// for (int i=0; i<5; i++) {
// printf("%3d",*(p+i));
// }
// printf("%p\n",p);
// printf("%d\n",ages[0]);
// *p=20;
// printf("%d\n",ages[0]);
// for (int i=0; i<5; i++) {
// printf("%d\n",ages[i]);
// }
// 指针变量 +1 ,地址式多少,取决于指针的类型
// int * 4
// char * 1
// double * 8
// double d=10.8;
// double *b;
// b=&d;
// printf("b=%p\n",b);
// printf("b+1=%p\n",b+1);
// int age[5]={18,8,8,67,56};
// 数组变量 p 指向了数组的首元素
//int *p;
//p=age;
// 数组名就是数组的地址,也是数组首元素的地址
//
// for (int i=0; i<5; i++) {
// printf("p[%d]=%d\n",i,*(p+i));
// }
// int a=1;
// int b=2;
// int c=3;
// int *p[3]={&a,&b,&c};
// for (int i=0;i<3; i++) {
// printf("%p ",p[i]);
// printf("%d\n",*p[i]);
// }
// printf("%p\n",p);
// printf("%p\n",&p);
// printf("%p\n",&p[0]);
#pragma mark- 指针与字符
// 定义字符数组存储字符串,常量字符串拷贝的副本存在字符数组中,数组中的元素是可以改变的。
//char str[]="hello";
// char *p=str;//str 所代表的是字符数组的首地址,所以说不用加 &
// *p='a';
// printf("%s\n",str);
// 使用指针访问数组元素
//for(int i=0;i<6;i++)
//printf("%c",*(p+i));
// 定义字符指针指向字符串
/*
常量字符串 , 存储在常量区,只能访问,不能修改
定义指针指向常量去的字符串常量的首地址,指针 p 中只是存储地址
*/
// char *p="hello";
// 可以访问字符和字符串
// printf("%s\n",p);
// printf("%c\n",*p);
// 总结:指针数组的指针可以访问和修改数组元素,指向常量字符串的指针只能访问数组元素。
// char a[]="hello";
// char b[]={0};
// char *c=NULL;
// c="lanou";// 指向新的字符串
// strcpy(b, a);
// printf("%s",b);
// 不能修改指针 c 的指向的内容。
//strcpy(c, a);
// 练习:
// 通过指针计算字符串的长度
char str[]= "iPhone" ;
char *p_1=str;
printf ( "%lu\n" , strlen (p_1));
{
n= 10 ;
}
void yunSun( int x, int y, int *add, int *sub, int *cheng, float *chu)
{
*add=x+y;
*sub=x-y;
*cheng=x*y;
*chu=x/( float )y;
}
int main( int argc, const char * argv[]) {
#pragma mark- 指针
/*
1. 内存中,如何存储数据,如何读取数据?
程序运行时,系统会为数据分配内存单元,存储数据
2. 内存是由多个连续的内存单元组成,
内存单元用于存储数据,每个内存单元占 1 个字节, 1 个字节 =8 个二进制位
内存单元地址:内存单元的编号,连续的,便于访问内存单元,就像门牌号一样。
3. 访问数据的两种方式:
( 1 ):直接访问,定义变量存储数据,通过变量名访问数据。
比如: int a=10;int b=a;
通过变量 a 访问内存中的数据。
( 2 ):间接访问:通过内存单元地址访问内存中的数据,任何数据都是存储在内存中的存储单元中。
4. 内存单元的地址,被称为指针。
指针变量:存储指针(地址)的变量。
定义指针变量:
int *p=NULL;
float *q=NULL;
char *r=NULL;
NULL 是空指针,相当于 0 , NULL 是给指针变量赋值。
指针变量的语法:
类型修饰符 * 指针变量名 = 初值 ( 地址 );
* :定义的变量是一个指针变量,存储的内容是地址。
类型修饰符:地址指向的存储单元中的类型(即通过地址找到的数据类型)
指针变量通常被称为指针
int *p=NULL; p 是整数指针
float *q=NULL; q 是浮点数指针
char *r=NULL; r 是字符型指针
-----------------------------------
通过指针访问存储单元,必须先获取单元的地址
取地址符 :& 获取变量的地址
输出地址: %p
// 定义一个指针变量 int *p
*/
// int *p;// ( *p 先读取 p 中的存储地址,根据地址访问存储单元)
// int a=90;
// 指针变量 p 指向了变量 a
// p=&a;
// printf("%p\n",p);
// printf("%d\n",*p);
// a=20;
// printf("%d",*p);
//(1) 间接传值 指针的应用场景
// int a=20;
// change(&a);
// printf("%d\n",a);
//
//
// int b=20;
// change2(b);
// printf("%d\n",b);
// ( 2 )可以操作多个值
// int add,sub,cheng;
// float chu;
// yunSun(8,12,&add,&sub,&cheng,&chu);
// printf("add=%d,sub=%d,cheng=%d,chu=%.2f\n",add,sub,cheng,chu);
#pragma mark- 内存
// int a=8;
// float c=1.2;
// double d=5.32;
// int *p=&a;
// float *p2=&c;
// double *p3=&d;
// printf("%lu %lu %lu",sizeof(p),sizeof(p2),sizeof(p3));
// 所有基本类型的指针字节都是根据计算机位数决定的,如果是 32 位,那么指针字节数则是 4 ,如果是 64 位,指针字节数则是 8 ,
#pragma mark- 错误的写法
/*
int *p 只能指向 int 类型的数据
int *p;
double d=10.0;
p=&d;
*/
/*
int *p=&a;
*p=a;
*/
// double d=10.5;
// double d2=10.5;
// double *p;
// p=&d;
// *p=5.6;
#pragma mark- 指针和数组
//1. 数组名是常量地址,不可以重新指向,而指针可以发生改变,可以重指向。
//2. 使用指针,可以计算出有结果表示的数组的长度,比如字符串,但是无法计算出普通数组的长度 .
// 数组元素的访问地址
// int ages[5];
// int *p;
// p=ages;
// printf("%p",p);
/*
1> 数组名 [ 下标 ] age[i]
2> 指针数组名 [ 下标 ] p[i]
3>*(p+i)
*/
// int ages[5]={10,45,12,43,41};
// int *p;
// p=&ages[0];// 指针变量 p 指向了数组的首地址
// printf("%p\n",p);
// p=ages;// 数组名就是数组的首地址,也是数组的首元素地址
// for (int i=0; i<5; i++) {
// printf("%3d",*(p+i));
// }
// printf("%p\n",p);
// printf("%d\n",ages[0]);
// *p=20;
// printf("%d\n",ages[0]);
// for (int i=0; i<5; i++) {
// printf("%d\n",ages[i]);
// }
// 指针变量 +1 ,地址式多少,取决于指针的类型
// int * 4
// char * 1
// double * 8
// double d=10.8;
// double *b;
// b=&d;
// printf("b=%p\n",b);
// printf("b+1=%p\n",b+1);
// int age[5]={18,8,8,67,56};
// 数组变量 p 指向了数组的首元素
//int *p;
//p=age;
// 数组名就是数组的地址,也是数组首元素的地址
//
// for (int i=0; i<5; i++) {
// printf("p[%d]=%d\n",i,*(p+i));
// }
// int a=1;
// int b=2;
// int c=3;
// int *p[3]={&a,&b,&c};
// for (int i=0;i<3; i++) {
// printf("%p ",p[i]);
// printf("%d\n",*p[i]);
// }
// printf("%p\n",p);
// printf("%p\n",&p);
// printf("%p\n",&p[0]);
#pragma mark- 指针与字符
// 定义字符数组存储字符串,常量字符串拷贝的副本存在字符数组中,数组中的元素是可以改变的。
//char str[]="hello";
// char *p=str;//str 所代表的是字符数组的首地址,所以说不用加 &
// *p='a';
// printf("%s\n",str);
// 使用指针访问数组元素
//for(int i=0;i<6;i++)
//printf("%c",*(p+i));
// 定义字符指针指向字符串
/*
常量字符串 , 存储在常量区,只能访问,不能修改
定义指针指向常量去的字符串常量的首地址,指针 p 中只是存储地址
*/
// char *p="hello";
// 可以访问字符和字符串
// printf("%s\n",p);
// printf("%c\n",*p);
// 总结:指针数组的指针可以访问和修改数组元素,指向常量字符串的指针只能访问数组元素。
// char a[]="hello";
// char b[]={0};
// char *c=NULL;
// c="lanou";// 指向新的字符串
// strcpy(b, a);
// printf("%s",b);
// 不能修改指针 c 的指向的内容。
//strcpy(c, a);
// 练习:
// 通过指针计算字符串的长度
char str[]= "iPhone" ;
char *p_1=str;
printf ( "%lu\n" , strlen (p_1));
printf("%lu\n",sizeof(str));