指针
1.指针定义,即简单用法.
<span style="font-size:14px;"> //指针变量:专门用来存储地址的变量.
int *p = NULL;//NULL == 0
/**
* 变量定义时:
* (int *):指针类型
* p: 变量名 NULL:初始值.
* NULL(指向了一个无效的区域)
* *的作用: 告诉编译器,后面变量是指针变量,用来存储地址.
* int作用: 1.当通过指针变量取数据时,一次性读取几个字节的数据. 2.当指针变量+1时,一次性增加几个字节.
* 指针变量的空间大小和操作系统有关,32为4个字节,64位8个字节.
*/
int a = 10;
p = &a; //p存储a的地址 指针p指向a
//间接访问,找到变量的地址.
printf("%d\n",*p);//此时*的作用:根据p中的地址,找到对应的地址的空间.如果*p在等号的左边,则是赋值操作,</span><pre name="code" class="cpp"><span style="font-size:14px;"> 否则是取值操作.</span>
*p = 20;//将20赋值给指针p所指向的存储空间.即修改p指向的内存空间的数据.
2.1指针的简单练习
<span style="font-size:14px;">//用指针操作交换a,b的值</span><span style="font-size:14px;"> int a = 10 , b = 5;
int *p1 = &a;//指向a,指针变量,用来存储地址.
int *p2 = &b;//指向b
//通过指针变量交换a,b的值
int temp = 0;
temp = *p1;
*p1 = *p2;
*p2 = temp;
printf("a = %d, b = %d \n",a, b);
//通过P2访问a.</span><span style="font-size:14px;">当指针变量+1时,一次性增加几个字节.</span><span style="font-size:14px;">
printf("a = %d \n",*(p2 + 1));
//通过p1访问b;</span><span style="font-size:14px;">当指针变量-1时,一次性减少几个字节.</span><span style="font-size:14px;">根据地址.
printf("b = %d ",*(p1 - 1));</span>
/*
<span style="font-size:14px;"> //这样只交换了指针指向的地址,而a,b的值没变.
//通过指针变量交换a,b的值
int *temp = p1;
p1 = p2;
p2 = temp;</span>
*/
2.2通过指针地址获取元素
int a = 10, b = 20, c = 30;
int *p = &b;//指针指向b的地址
printf("b = %d\n", *p);
printf("a = %d\n", *(p + 1));//通过地址获取到a
//访问到a
printf("a = %d\n", a);
printf("a = %d\n", *(&a));//通过a的地址
printf("a = %d\n", *(p + 1));//当指针变量+1时,一次性增加几个字节.
printf("a = %d\n", *(&b + 1));
printf("a = %d\n", *(&c + 2));
p = &c;//指针变量重新赋值的过程就叫做指针重定向.
2.3 指针对数组的应用
int a[5] = {1, 2, 3, 4, 5};
int *p = a; //存储数组的首地址,a本身是地址,所以不用取地址符
printf("%d\n",*p);
printf("%d\n",*(p + 2));//a[2] 或者 p[2]
printf("%d\n", 3[a]);// 3[a] *(3 + a) 相当于 a[3] ---- *(a + 3) .. * (p + 3)
printf("%d\n", 4[a]);
//遍历输出元素
for (int i = 0; i < 5; i++) {
printf("%d ", *(p + i));//p[i]
}
printf("\n");
for (int i = 4; i >= 0 ; i--) {
printf("%d ", *(p + i));
}
2.4通过指针,进行数组的冒泡排序.
int b[10] = {0};
int *p = b;
//通过指针操作
//赋值20 -40
for (int i = 0; i < 10; i++) {
*(p + i) = arc4random() % (40 - 20 + 1) + 20;
printf("%d ", *(p + i));
}
//升序
for (int i = 0; i < 10 - 1; i++) {
for (int j = 0; j < 10 - 1 - i; j++) {
if (*(p + j) > * (p + j + 1)) {
int temp = 0;
temp = *(p + j);
*(p + j) = *(p + j + 1);
*(p + j + 1) = temp;
}
}
}
printf("\n");
//输出
for (int i = 0; i < 10; i++) {
printf("%d ", *(p + i));
}
2.5运用指针,求出数组中的最大值,最小值.第二大值.和的操作.
int m[10] = {0};
int *p = m;
//赋值10 - 50
for (int i = 0; i < 10; i++) {
*(p + i) = arc4random() % (50 - 10 + 1) + 10;
printf("%d ", *(p + i));
}
printf("\n");
//求所有元素的最大值
int max = 0;
for (int i = 0; i < 10; i++) {
if (*(p + i) > max) {
max = *(p + i);
}
}
printf("最大值为:%d\n", max);
//求所有元素的最小值
int min = 0;
for (int i = 0; i < 10; i++) {
if (i == 0) {
min = *(p + i);
} else if (min > *(p + i)){
min = *(p + i);
}
}
printf("最小值为:%d\n", min);
//求所有元素的第二大值
int sexMax = 0;
for (int i = 0; i < 10; i++) {
if (max < *(p + i)) {
sexMax = max;
max = *(p + i);
} else if(*(p + i) > sexMax && *(p + i) != max) {
sexMax = *(p + i);
}
}
printf("第二大值为:%d\n", sexMax);
//求所有元素的和
int sum = 0;
for (int i = 0; i < 10; i++) {
sum += *(p + i);
}
printf("sum = %d\n", sum);
2.6 数组和指针变量的比较.
<span style="font-size:14px;"> /**
* 比较 数组 和指针变量
* 1.空间大小
* 数组所占存储空间 = 数组元素个数 * 单个元素所占存储空间的大小.
* 指针变量所占存储空间大小和操作系统位数有关,32位操作系统4个字节,64位操作系统8个字节.
* 2.可变性
* 数组名代表数组的首地址,是一个常量地址,不可改变.
* 指针变量本质上就是一个变量,可以重新赋值,指针赋值的过程叫做指针重定向.
*/</span>
2.7指针变量和字符数组(字符串)
char str[] = {"ac is big company , yao shang shi"};
char *p = str;
printf("%c\n", *(p+6));
//%s的工作原理:给定一个开始地址,一个字符一个字符的输出,知道遇到\0结束.
printf("%s\n", p);// printf("%s", str);
printf("%s\n", p + 23);//yao shang shi
*(p + 5) = '\0';
printf("%s\n", p);
*(p + 20) = '\0';
printf("%s\n", p + 13);
//1.字符串长度
//strlen的工作原理:给定一个开始地址,一个字符一个字符的输出,知道遇到\0结束
unsigned long length = strlen(p + 22);//p相当于str
printf("%ld \n", length);
//2.字符串拷贝
//strcpy的工作原理:给定一个开始地址,一个字符一个字符的输出,知道遇到\0结束
//strcpy 返回目的字符串的地址.
printf("%s\n",strcpy(p + 5,"Frank"));//Frank
strcpy(p + 5,"Frank");
printf("%s\n",p);//LanouFrank
//3.字符串比较(从首字母比较,首字母相等,比较下一个.)
printf("%d\n", strcmp(p, "bb"));//-1
printf("%d\n", strcmp(p + 1, "bb"));//1
2.8指针字符串应用
//求字符串中个空格的个数,有指针操作
char str[] = "I LOVE IOS";
char *p = str;
int i = 0;
int num = 0;
while (*(p + i) != '\0') {
if (*(p + i) == ' ') {
num++;
}
i++;
}
printf("%d", num);
//方法2
char str[] = "I L O V E I O S";
char *p = str;
int num = 0;
while (*p) {
if (*p == ' ') {
num++;
}
p++;//地址++
}
printf("%d", num);
2.9基本概念
//1.指向要有明确的指向,即有效的区域.2.要指向一个可控的区域.
//char *p = NULL;//null,即让指针p指向一个无效的地址.//address = 0x0,即指向一个无效的区域
//char *p = 0xfffff01;
//strcpy(p, "aaa");
//指针数组,常量区,值不能修改,
char *str[] = {"xiaozhang", "xiaoqiang", "xiaoli"};//地址
char *p1 = "Frank";// *p1指向的是常量字符串的首地址.P1是指针变量,存储的是地址.
// *P1指向的是常量字符串的首地址,处在常量区,常量区的内容不可以更改,即只能读,不能写.
strcpy(p1, "DUCK");
3.0对指针数组进行排序.
//指针数组,常量区,值不能修改,
char *str[] = {"xiaozhang", "xiaoqiang", "xiaoli"};//地址
printf("%s", str[1]);//xiaoqiang
printf("%s", str[0]);//xiaozhang%s的工作原理:给定一个开始地址,一个字符一个字符的输出,知道遇到\0结束
//strcpy(str[0], "lanou");
//升序排列
printf("\n");
printf("%c", *str[2]);//取到一个字符
for (int i = 0; i < 3 - 1; i++) {
for (int j = 0; j < 3 - 1 - i ; j++) {
if (strcmp(str[j], str[j + 1]) > 0) {
char *temp = str[j]; //将地址赋值给指针变量.
str[j] = str[j + 1]; //交换的是地址.
str[j + 1] = temp;
}
}
}
for (int i = 0; i < 3; i++) {
printf("%s ", str[i]);
}