今天来学习数组名的理解(指针与数组的联系)
文章目录
1.理解数组名
数组名就是数组首元素(第一个元素)地址。
两个例外:
- sizeof(数组名),sizeof中单独放数组名,这里的数组名表示整个数组,计算的是整个数组的大小,单位是字节
- &数组名,这里的数组名表示整个数组,取出的是整个数组的地址(整个数组的地址和数组首元素的地址是有区别的)
- 除此之外,任何地方使用数组名,数组名都表示首元素的地址。
- &arr是数组的地址,+1 操作是跳过整个数组的。
2.使用指针访问数组
本质上p[i] 是等价于 * (p+i)
arr[i] 应该等价于 * (arr+i)
3.一维数组传参数
本质上数组传参传递的是数组首元素的地址
⼀维数组传参,形参的部分可以写成数组的形式,也可以写成指针的形式
3.二级指针
指针变量也是变量,是变量就有地址,指针变量的地址存放在⼆级指针
4.指针数组
存放指针的数组
指针数组每个元素都用来存放地址(指针)
指针数组的每个元素是地址,又可以指向一块区域
练习
1.冒泡排序
代码
#include<stdio.h>
void bubble_sort(int arr[],int sz)
{
int i = 0;
int tmp = 0;
int flag = 1;
for (i = 0; i < sz - 1; i++)
{
int j = 0;
for (j = 0; j < sz - i - 1; j++)
{
if (arr[j] > arr[j + 1])
{
tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
flag = 0;
}
}
if (flag == 1)
{
break;
}
}
}
int main()
{
int arr[10] = { 0 };
printf("请输入十个数\n");
int sz = sizeof(arr) / sizeof(arr[0]);
for (int i = 0; i < sz ; i++)
{
scanf("%d ", &arr[i]);
}
bubble_sort(arr, sz);
printf("打印排序后的数组\n");
for (int i = 0; i < sz ; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
运行结果
2.指针数组模拟二维数组
2.1代码
#include<stdio.h>
int main()
{
int arr1[3] = { 1,3,4 };
int arr2[3] = { 1,2,9 };
int arr3[3] = { 4,5,6 };
int* parr[3] = { arr1,arr2,arr3 };
for (int i = 0; i < 3; i++)
{
for (int j = 0; j<3; j++)
{
printf("%d ", parr[i][j]);
}
printf("\n");
}
return 0;
}
2.2运行结果
3.字符串旋转结果
写一个函数,
判断一个字符串是否为另外一个字符串旋转之后的字符串。
例如:给定s1 =AABCD和s2 = BCDAA,返回1
给定s1=abcd和s2=ACBD,返回0.
AABCD左旋一个字符得到ABCDA
AABCD左旋两个字符得到BCDAA
AABCD右旋一个字符得到DAABC
//当一个数组里面有两倍的原字符串就可以保证
// 旋转后的数组都是这个两倍原字符串的子集
int findRound(char* str,char* sub)
{
char tmp[256] = { 0 };//创建临时数组
strcpy(tmp, str);//拷贝进这个临时数组
strcat(tmp, str);//再链接一次
return strstr(tmp,sub)!=NULL;//在临时数组里查找旋转后的字符串
//如果找到了结果为真,反之为假
}
int main()
{
char* str = "abcde";//原字符串
char* sub = "ABCDE";//示范不是原字符串旋转得到的
char* sub = "deabc";//示范是原字符串旋转得到的
bool flag = findRound(str, sub);
if (flag)
{
printf("TURE\n");
}
else
{
printf("FALSE\n");
}
return 0;
}
运行结果
4.杨氏矩阵
有一个数字矩阵,
矩阵的每行从左到右是递增的,
矩阵从上到下是递增的,
请编写程序在这样的矩阵中查找某个数字是否存在。
要求:时间复杂度小于O(N);
代码
#include<stdio.h>
int FindNum(int a[][5], int x, int y, int f)
{
//x:列 y:行 f:要找的数字
int i = 0;
int j = y - 1;
while ((i<x) && (y>0))
{
if (f > a[i][j])
{
i++;//从右上角开始查找的时候,右上角的元素比我们要查找元素小,
//我们就可以去掉右上角元素所在的这一行
}
else if (f < a[i][j])
{
j--;//右上角的元素比我们要查找的元素大,
//我们就可以去掉右上角元素所在的这一列
}
else
return 1;
}
return 0;
}
int main()
{
int arr[3][3] = { {1,2,3},
{4,5,6},
{7,8,9} };//从上到下递增
//从左到右递增
int ret = FindNum(arr, 3, 3, 8);//8能找到
int ret = FindNum(arr, 3, 3, 10);//10不能找到
if (ret != 0)
{
printf("has been find!\n");
}
else
printf("has't been find!\n");
return 0;
}
运行结果
5.猜凶手
日本某地发生了一件谋杀案,
警察通过排查确定杀人凶手必为4个嫌疑犯的一个。
以下为4个嫌疑犯的供词:
A说:不是我。
B说:是C。
C说:是D。
D说:C在胡说
已知3个人说了真话,1个人说的是假话。
现在请根据这些信息,写一个程序来确定到底谁是凶手。
代码
#include<stdio.h>
int main()
{
int killer = 0;
for (killer = 'a'; killer <= 'd'; killer++)
{
if ((killer != 'a') + (killer == 'c') + (killer == 'd') + (killer != 'd') == 3)
{
printf("killer is %c\n", killer);
}
}
return 0;
}
运行结果
6.杨辉三角
在屏幕上打印杨辉三角。
1
1 1
1 2 1
1 3 3 1
……
代码
#include<stdio.h>
int main()
{
int n;
scanf("%d", &n);//输入要打印多少行
printf("1\n");
int arr[30] = { 1 };//最多30,可以自己调整
//不完全初始化,arr[0]为1,后面全为0
int i = 0;
int j = 0;
for (i = 1; i < n; i++)
{
for (j = i; j > 0; j--)
{
arr[j] += arr[j - 1];
}
for (j = 0; j <= i; j++)
{
printf("%-5d ", arr[j]);//左对齐5位,不够在后面补空格
}
printf("\n");
}
return 0;
}
运行结果
7.使用指针打印数组内容
写一个函数打印arr数组的内容,不使用数组下标,使用指针。
arr是一个整形一维数组。
代码
#include<stdio.h>
void PrintArr(int* arr, int sz)
{
int i = 0;
int* p = arr;
for (i = 0; i < sz; i++)
{
printf("%d ", *p);
p++;
}
printf("\n");
}
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int sz = sizeof(arr) / sizeof(arr[0]);
PrintArr(arr, sz);
return 0;
}
运行结果
总结
数组名的理解(数组名一般等价于首元素地址,有两个特例sizeof、&arr),
使用指针访问数组(在指针里传数组首元素地址),指针数组。
对指针与数组的联系的分享就到这里了,如果感觉不错,希望可以给博主点个赞或者关注,感谢大家的支持,成为我继续分享的动力,还有什么问题和建议可以在评论区评论,拜拜。