目录
8.指针
8.1引入
一个变量有几种含义
- 空间
- 值
当我们顶一个一个变量之后,这个变量就可以代表这个空间本身,也可以表示空间中的值
在内存中,为了方便对内存的管理,计算机给每个字节都进行了编址。
对于整型数据,我们可以使用 int
、short
等类型进行保存,对于字符我们可以用 char
类型进行保存,但是我们要保存地址呢?
- 地址的本质就是数据,只不过这个数据有特殊的含义
- 保存这种特殊含义的数据,我们需要指针变量
8.2指针
如果一个指针类型的变量p
,保存了某个变量a
的地址,我们就称p
指向了a
int a;
int *p = &a;
语法
基类型 *指针变量名{=地址};
- 基类型:指针指向的类型
*
:指示这是一个指针变量- 指针变量名:符合C语言标识符命名规则即可
指针变量的字节数:
- 指针变量的字节数是固定的,不随着指向类型的变化而变化,字节数一般与
long
类型相同(取决于编译器)。 - 指针的字节数决定了寻址范围。
8.3*
的含义
*
运算符读作 指针运算符/解引用运算符(指向运算符)
-
指针运算符:
int *p;
表示这是一个指针 -
解引用运算符:
int a; int *p = &a; //&a 引用;*(&a) 解引用 //*p == a; p == &a;
写一个函数,交换两个变量的值:
void swap(int *a, int *b)
{
int t = *a;
*a = *b;
*b = t;
}
int main()
{
int a = 3;
int b = 4;
swap(&a, &b);
}
8.4指针的初始化
int a; //a 空间中的值是未知的
int *p; //p 空间中的值是未知的
int a = 10; //将10 放到a 空间中
int *p = &a; //将a的地址,存放在p所对应的空间中
int *p = 10; //合法但不合理
int *p = (int *)10; //(int *)10 代表一个地址,指针这么指其实没什么意义
空指针:
int *p = NULL; //p为空指针,NULL表示空,也就是说这个东西合法,但不可访问.
*p = 10; //访问会导致程序异常,段错误。
野指针:
int *p; //p 空间中的值是未知的
*p = 10; //访问大概率会导致程序异常,段错误。
- 建议指针变量进行定义时,如果没有具体的指向,请初始化为NULL;NULL是一种检测手段,可以检测这个指针是否被使用,可以通过
if(p == NULL)
判断指针是否被使用
8.5一维数组和指针
数组各个元素都有自己的地址,并且地址是连续的
int a[5] = {1, 2, 3, 4, };
//申请了五个整型元素的空间,并且将a和空间首地址绑定,并且可以用a来表示这个数组,也就是说我可以定义一个指针来指向这个数组
int *p = &a[0];
int *p = a;
//这两种方法都可以让p指向a[0],*p == a[0];
//将a[0]设置为1的方法
a[0] = 1;
*a = 1;
*p = 1;
p[0] = 1;
//将a[1]设置为1的方法
a[1] = 1;
*(a+1) = 1;
*(p+1) = 1;
p[1] = 1;
- 指针/地址与数值的加减,不再是数值的加减,而是加减基类型的字节数
- 指针/地址之间的加法/乘法/除法是毫无意义的。
- 指针/地址之间的减法(基类型相同的情况下),表示两个地址之间相差了多少个基类型
int a[5];
/*
数值上,a 和 &a[0] 和 &a 是相同的
a表示数组的首地址
&a[0]表示a[0]的地址
&a表示整个数组的地址
事实上,a的类型是int [5]
*/
int (*p)[5] = &a; //数组指针
8.6二维数组与指针
int a[3][4];
//二维数组可以看作3个一维数组,并且数组名为a[0] a[1] a[2]
//所以a[0]的类型是int [4]
int (*p)[4] = a; //此时p代表a
//设置a[0][0]为1
a[0][0] = 1;
p[0][0] = 1;
*(a[0] + 0) = 1;
*(*(p+0) + 0) = 1;
//设置a[2][0]为1
a[2][0] = 1;
p[2][0] = 1;
*(a[2] + 0) = 1;
*(*(p+2) + 0) = 1;
int a[3][4]
/*
&a a &a[0] &a[0][0] 在数值上是相同的,但含义不同
&a[0][0]:代表a[0][0]这个元素的地址
&a[0] :代表a[0]这个数组的地址
a :代表a[0]这个数组的地址
&a :代表a这个数组的地址
*/
二维数组作为函数参数
int a[3][4];
int waterPools(int (*a)[4], int row, int col)
int waterPools(int a[][4], int row, int col)
8.7指针数组与数组指针
int *a[4]; //指针数组
int (*a)[4]; //数组指针
int *a[4]
本质上是一个数组,这个数组内保存的都是地址int (*a)[4];
本质上是一个指针,可以指向一整个数组
指针数组的常见用法:
char *str[] = {"hello world", "123456", "abcdefg"};
//str[0] 存了"hello world"的地址
//str[1] 存了"123456"的地址
//str[2] 存了"abcdefg"的地址
作业:
1.输入一串小写字母,对小写字母按照"abcdefg"这种规则进行排序
#include <stdio.h>
void letSort(char *p)
{
int i = 0;
while(*(p+i) != '\0')
{
if(*p < 'a' || *p > 'z')
{
printf("please inpute letter\n");
return;
}
i++;
}
for(int j = 0; j < i-1; j++)
{
for(int k = j+1; k < i; k++)
{
if(*(p+j) > *(p+k))
{
char t = *(p+j);
*(p+j) = *(p+k);
*(p+k) = t;
}
}
}
}
int main()
{
char letter[100];
scanf("%s",letter);
printf("%s\n", letter);
letSort(letter);
printf("%s\n", letter);
}
2.输入一串字符,将其中重复的字符删除只剩一个
例如:输入 aaaaabbbbbddd1111ddd
输出 abd1
#include <stdio.h>
void delChar(char *str, char *result)
{
int i = 0;
int index = 0;
int state = 0;
while(*(str+i) != '\0')
{
i++;
}
for(int j = 0; j < i; j++)
{
for(int k = 0; k < i; k++)
{
if(*(str+j) == *(result+k))
{
state = 1;
break;
}
}
if(state == 0)
{
*(result+index) = *(str+j);
index++;
}
state = 0;
}
}
int main()
{
char str[100] = {'\0'};
char result[100] = {'\0'};
gets(str);
puts(str);
delChar(str, result);
puts(result);
}
标签:数组,int,C语言,char,地址,str,指针
From: https://www.cnblogs.com/aalynsah/p/17533222.html