1...
- 交换a b的值
- a = a ^ b;
- b = b ^ a;
- a = a ^ b;
2...理解-----指针可以通过函数改变函数外的值
指针所占字节数 只与操作系统有关, 8位或者4位
地址的表示方式为16进制
打印地址用%p
指针变量存储的只是整型变量的首地址(第一个字节的地址)
* 取值运算符, 根据指针变量里存储的地址, 找到并取出对应内存空间的值
&取址运算符, 取到到变量的地址z
指针变量的类型,要与你所要取址的变量的类型相同
指针++, 意味着指针向高地址一次移动其对应的数据类型所占的字节数
指针- -, 意味着指针向低地址依次移动其对应的数据类型所占的字节数
int array[4] = {1, 3, 4, 3}
array 恒等于&array[1]
int
array[
4
] = {
1
,
3
,
4
,
3
};
int *p = array;
printf ( "%d" ,*(p + 1 )); // 结果是 3, 实际上就是打印 array[1];
int *p = array;
printf ( "%d" ,*(p + 1 )); // 结果是 3, 实际上就是打印 array[1];
printf("%d", *(p + 2));//
结果是
4,
实际上就是打印
array[2];
通过指针,用一个for循环打印出所有的数字
for
(
int
i =
0
; i <
4
; i++) {
printf ( "%d " , *(p + i));
printf ( "%d " , *(p + i));
}
// 数组在用指针读取数据的时候 , 如果指针类型与数组元素类型不匹配 , 指针会根据自身数据类型选择一次性读取几个字节 , 导致读取数据错误
short a[ 4 ] = { 2 , 2 , 0 , 3 };
int *p = a;
printf("%d", *p);
//
输出
131074
//
用指针随机产生一个有五个元素的数组
,
并排序
u
int arr[ 5 ] = { 0 };
int *p = arr;
for ( int i = 0 ; i < 5 ; i++) {
*(p + i) = arc4random ()% 11 + 10 ;
printf ( "%d " , *(p + i));
}
for ( int i = 0 ; i < 5 - 1 ; i++) {
for ( int j = 0 ; j < 5 - 1 - i; j++) {
// if (*(p + j) > *(p + j + 1)) {
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 < 5 ; i++) {
printf ( "%d " ,*(p + i));
int arr[ 5 ] = { 0 };
int *p = arr;
for ( int i = 0 ; i < 5 ; i++) {
*(p + i) = arc4random ()% 11 + 10 ;
printf ( "%d " , *(p + i));
}
for ( int i = 0 ; i < 5 - 1 ; i++) {
for ( int j = 0 ; j < 5 - 1 - i; j++) {
// if (*(p + j) > *(p + j + 1)) {
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 < 5 ; i++) {
printf ( "%d " ,*(p + i));
}
char
a[] =
"abcdefg"
;
char *p = a;
// 输出 c 以及后面的数
printf ( "\n%s " , (p + 2 ));
// 输出 c
char *p = a;
// 输出 c 以及后面的数
printf ( "\n%s " , (p + 2 ));
// 输出 c
printf("\n%c", p[2]);
char
*string[
3
] = {
"iOS"
,
"Android"
,
"Win8"
};
//string[3] 里面存储的是字符串 "iOS", "Android", "Win8" 的首地址 .
// printf("%s",*string);
// *string[0];
// *string 获取数组中首个元素的值
// *string[0] 通过 string 数组中收个元素的值找到常量区对应的字符串
// string[0] 代表数组中首个元素的值
//string[3] 里面存储的是字符串 "iOS", "Android", "Win8" 的首地址 .
// printf("%s",*string);
// *string[0];
// *string 获取数组中首个元素的值
// *string[0] 通过 string 数组中收个元素的值找到常量区对应的字符串
// string[0] 代表数组中首个元素的值
*string = "ISO";//
这里是指针重指向
,
这里的
"ISO"
和
"iOS", "Android", "Win8"
都处在常量区
,
地址不相同
.
这里把
"ISO"
的地址赋值给了
string
*string[
0
] =
"ISO"
;
//
错误
!!!
这里
*string[0]
的值处于常量区
,
无法改变
间接访问内存: 通过内存单元编号(地址) 以及数据所占字节数访问内存中的数据
int
a =
20
;
int *p = &a; //& 取地址符 此时 * 与 int 是一个整体 , 告诉编译器 p 是一个存放地址的变量
printf ( "%p\n" , p);
printf ( "%d\n" , *p); // 使用 p 间接访问 , 如果用 a 则可以直接访问
// 对地址的内容直接进行操作
*p = 40 ;
int *p = &a; //& 取地址符 此时 * 与 int 是一个整体 , 告诉编译器 p 是一个存放地址的变量
printf ( "%p\n" , p);
printf ( "%d\n" , *p); // 使用 p 间接访问 , 如果用 a 则可以直接访问
// 对地址的内容直接进行操作
*p = 40 ;
printf("%d\n", a);
//
给指针变量赋值
,
意味着指针重指向
int a = 5 , b = 8 ;
int *p = &a;
printf ( "%d\n" ,*p);
// 指针类型决定了指针读连续几个字节 指针占用多少字节取决于操作系统的位数 .32 位系统 4 字节 ,64 位系统 8 字节 .
int a = 5 , b = 8 ;
int *p = &a;
printf ( "%d\n" ,*p);
// 指针类型决定了指针读连续几个字节 指针占用多少字节取决于操作系统的位数 .32 位系统 4 字节 ,64 位系统 8 字节 .
return 0;
//
通过指针变量改变变量的值
.
int a = 30 ;
char b = 20 ;
float c = 20 ;
int *q = &a;
char *w = &b;
float *e = &c;
*q = 40 ;
*w = 50 ;
*e = 60 ;
int a = 30 ;
char b = 20 ;
float c = 20 ;
int *q = &a;
char *w = &b;
float *e = &c;
*q = 40 ;
*w = 50 ;
*e = 60 ;
printf("a = %d, b = %c, c = %.2f", a, b, c);
指针作为函数参数,可以改变函数外部改变函数外部变量的值
注意 如果出现*的地方,前面有类型修饰符, 此时*仅仅起到标识作用, 告诉编译器, 我是一个指针
如果出现* 的地方, 前面没有类型修饰符, 此时* 代表取值操作符, 它会把指针指向的区域中的内容取出来或者赋值.
比如: int *a = &b; 这里应该把int * 看做一个整体,指针变量b则是一个内存地址
结构体指针
可以用 (*p).sex 这种形式来访问结构体里面的内容
p -> sex这种方式也可以. 推荐使用后一种方式;
数组名代表数组的首地址 即: 数组首元素地址
上图和下图的输出结果是相同的.