练习(含指针数组与数组指针的学习)
数组指针是一个指向数组的指针,而指针数组是一个存储指针的数组。
数组指针:是一个指针,指向一个数组的首地址,它用于指向整个数组,而不是数组中的某个元素。例如,int (*p)表示 p 是一个指向包含 5 个整数的数组的指针。数组指针声明时使用括号明确优先级,如 int (*p)[10],其中()的优先级高于[ ],因此p首先被定义为一个指针,然后指向一个大小为10的数组。
指针数组:是一个数组,其元素都是指针,它用于存储多个指针,每个指针可以指向不同的数据。例如,int *p 表示 p 是一个包含 5 个整型指针的数组。指针数组声明时 [ ] 优先级高于 *,如 int *p[10],表示 p 首先被定义为一个数组,然后数组的元素是指针类型。
内存占有:
数组指针:在 32 位系统中,数组指针占 4 字节,指向的数组大小由数组本身决定。
指针数组:数组的大小由元素数量和指针大小决定。例如,int *p 在 32 位系统中占 20 字节(5 个指针,每个 4 字节)。
使用场景:
数组指针:常用于传递数组的首地址,避免复制整个数组,适合处理二维数组的行指针。
指针数组:用于存储多个指针,适合动态分配内存或管理多个对象的指针。
操作方式:
数组指针:通过解引用访问数组元素,如 *(*p + i) 访问第 i 个元素。
指针数组:通过数组索引访问指针,如 *p[i] 访问第 i 个指针指向的值。
优先级与结合性:
数组指针:() 优先级高于 [ ],因此 int (*p) 明确表示 p 是指针。
指针数组:[ ] 优先级高于 *,因此 int *p 明确表示 p 是数组。
---------------------------------------------------------------------------------------------------------------------------------
一、
在以下的代码中,struct student - 是一个类型,而Stu - 是这个类型所创建的变量
struct student
{
int num;
char name[32];
float score;
}Stu;
//Stu - 是结构体变量
int main()
{
return 0;
}
而如果在此类型的前面加上 typedef ,就可以创建新的类型,例如以下的代码,Stu是新的类型,可以用这个类型创建新的变量s1
typedef struct student
{
int num;
char name[32];
float score;
}Stu;
//Stu - 是类型
int main()
{
Stu s1;
return 0;
}
二、喝汽水
一瓶汽水1元,2个空瓶可以换一瓶汽水,给20元,可以喝多少汽水
int main()
{
int money = 0;
int total = 0;
int empty = 0;
scanf("%d",&money);//20
total += money;//买
empty = money;
//置换
while(empty >= 2)
{
total += empty / 2;
empty = empty / 2 + empty % 2;
}
printf("%d\n",total);
return 0;
}
还有更高效的方式:
int main()
{
int money = 0;
int total = 0;
scanf("%d",&money);//20
if(money > 0)
total = 2 * money - 1;
printf("%d\n",total);
return 0;
}
三、上三角矩阵判断
上三角矩阵即主对角线以下的元素都为0的矩阵,主对角线为从矩阵的左上角至右下角的连线
输入:第一行包含一个整数n,表示一个方阵包含n行n列,用空格分隔。从2到n+1行,每行输入n个整数,用空格分隔,共输入n*n个数。
输出:一行,如果输入方阵是上三角矩阵输出"YES"并换行,否则输出“NO"并换行。
示例:
3
1 2 3
0 4 5
0 0 6
YES
2
2 3
4 5
NO
int main()
{
int n = 0;
scanf("%d",&n);
//int arr[n][n];//C99 变长数组
int arr[10][10];
//输入
int i = 0;
for(i = 0;i < n; i++)
{
int j = 0;
for(j = 0;j < n; j++)
{
scanf("%d",&arr[i][j]);
}
}
//判断
return 0;
}
接下来的部分是如何判断:
在主对角线以下的部分,我们可以发现 i > j,主对角线上 i = j,主对角线以上的部分,i < j
那么我们就可以这样写:
int main()
{
int n = 0;
scanf("%d",&n);
//int arr[n][n];//C99 变长数组
int arr[10][10];
//输入
int i = 0;
for(i = 0;i < n; i++)
{
int j = 0;
for(j = 0;j < n; j++)
{
scanf("%d",&arr[i][j]);
}
}
//判断
int flag = 1;//默认是上三角矩阵
for(i = 0;i < n; i++)
{
int j = 0;
for(j =0;j < i; j++)
{
if(arr[i][j] != 0)
{
flag = 0;
goto end;
}
}
}
end:
if(flag == 1)
printf("YES\n");
else
printf("NO\n");
return 0;
}
四、矩阵相等判断
有两个n行m列的矩阵,想知道两个矩阵是否相等。(当两个矩阵对应数组元素都相等时两个矩阵相等)。
输入:两个n行m列的矩阵
输出:如果两个矩阵相等输出"Yes"并换行,否则输出"No“并换行。
int main()
{
int n = 0;
int m = 0;
scanf("%d %d",&n,&m);
int arr1[n][m];
int arr2[n][m];//C99 变成数组
//输入数据
//第一个数组
int i = 0;
int j = 0;
for(i = 0;i < n; i++)
{
for(j = 0;j < m; j++)
{
scanf("%d",&arr1[i][j]);
}
}
//第二个数组
for(i = 0;i < n; i++)
{
for(j = 0;j < m; j++)
{
scanf("%d",&arr2[i][j]);
}
}
//比较
int flag = 1;//默认2个矩阵相等
for(i = 0;i < n; i++)
{
for(j = 0;j < m; j++)
{
if(arr1[i][j] != arr2[i][j])
{
flag = 0;
goto end;
}
}
}
end:
if(flag == 1)
printf("YES\n");
else
printf("NO\n");
return 0;
}
另一种方法:第二个数组每输入一个就与第一个数组判断
int main()
{
int n = 0;
int m = 0;
scanf("%d %d",&n,&m);
//int arr1[n][m];
//int arr2[n][m];//C99 变成数组
int arr1[100][100];
int arr2[100][100];
//输入数据
//第一个数组
int i = 0;
int j = 0;
for(i = 0;i < n; i++)
{
for(j = 0;j < m; j++)
{
scanf("%d",&arr1[i][j]);
}
}
//第二个数组
int flag = 1;//默认2个矩阵相等
for(i = 0;i < n; i++)
{
for(j = 0;j < m; j++)
{
scanf("%d",&arr2[i][j]);
if(arr1[i][j] != arr2[i][j])
{
flag = 0;
goto end;
}
}
}
end:
if(flag == 1)
printf("YES\n");
else
printf("NO\n");
return 0;
}
五、调整奇数偶数顺序
输入一个数组,实现一个函数,来调整该数组中数字的顺序使得数组中所有的奇数位于偶数的前面,即位于数组的前半部分
void move(int arr[],int sz)
{
int left = 0;
int right = sz - 1;
while(left < right)
{
//找偶数的过程
while(left < right && arr[left] % 2 ==1)
{
left++;
}
//找奇数
while(left < right && arr[right] % 2 == 0)
{
right--;
}
if(left < right)
{
int tmp = 0;
arr[left] = arr[right];
arr[right] = tmp;
left++;
right--;
}
}
}
int main()
{
int arr[10] = {0};
int sz = sizeof(arr) / sizeof(arr[0]);
//输入
int i = 0;
for(i = 0;i < sz, i++)
{
scanf("%d",&arr[i]);
}
//调整
move(arr,sz);
//输出
for(i = 0;i < sz; i++)
{
printf("%d ",arr[i]);
}
return 0;
}
六、有序序列合并
输入两个升序排序的序列,将两个序列合并为一个有序序列并输出
输入:两个整数n、m,表示升序序列中数据的个数
输出:输出长度为n+m的升序序列,即长度为n的升序序列和长度为m的升序序列中的元素重新进行升序序列排列并合并
示例:
输入:5 6
1 3 7 9 22
2 8 10 17 33 44
输出:1 2 3 7 8 9 10 17 22 33 44
int main()
{
int n = 0;
int m = 0;
//输入
scanf("%d %d",&n,&m);
int arr1[n];//1000
int arr2[m];//1000
int arr3[n+m];//2000
//arr1的输入
int i = 0;
for(i = 0;i < n; i++)
{
scanf("%d",&arr1[i]);
}
//arr2的输入
for(i = 0;i < m; i++)
{
scanf("%d",&arr2[i]);
}
i = 0;
int j = 0;
int k = 0;
while(i < n && j < m)
{
if(arr1[i] < arr2[j])
{
arr3[k] = arr1[i];
i++;
k++;
}
else //如果是大于等于走这条代码
{
arr3[k] = arr2[j];
j++;
k++;
}
}
if(i == n)//数组arr1中元素比arr2少
{
//把arr2中剩余的元素放在arr3中
while(j < m)
{
arr3[k] = arr2[j];
j++;
k++;
}
}
else //比arr2多(j == m)
{
//把arr1中剩余的元素放在arr3中
while(i < n)
{
arr3[k] = arr1[i];
i++;
k++;
}
}
//输出
for(k = 0;k < n+m; k++)
{
printf("%d ",arr3[k]);
}
return 0;
}
或者还可以这样(投巧):
int main()
{
int n = 0;
int m = 0;
//输入
scanf("%d %d",&n,&m);
int arr1[n];//1000
int arr2[m];//1000
int arr3[n+m];//2000
//arr1的输入
int i = 0;
for(i = 0;i < n; i++)
{
scanf("%d",&arr1[i]);
}
//arr2的输入
for(i = 0;i < m; i++)
{
scanf("%d",&arr2[i]);
}
i = 0;
int j = 0;
int k = 0;
while(i < n && j < m)
{
if(arr1[i] < arr2[j])
{
printf("%d ",arr1[i]);
i++;
}
else
{
printf("%d ",arr2[j]);
j++;
}
}
if(i == n)
{
//把arr2中剩余的元素放在arr3中
while(j < m)
{
printf("%d ",arr2[j]);
j++;
}
}
else
{
//把arr1中剩余的元素放在arr3中
while(i < n)
{
printf("%d ",arr1[i]);
i++;
}
}
return 0;
}
七、有序序列判断
输入一个整数序列,判断是否是有序序列,有序,指序列中的整数从小到大排序或者从大到小排序(相同元素也视为有序)
输入:第一行输入一个整数N;第二行输入N个整数
输出:如果是有序序列输出sorted,否则输出unsorted
示例1:
输入:5
1 6 9 22 30
输出:sorted
示例2:
输入:5
3 4 7 2 10
输出:unsorted
示例3:
输入:5
1 1 1 1 1
输出:sorted
int main()
{
int n = 0;
scanf("%d",&n);
int arr[n];
int i = 0;
for(i = 0;i < n; i++)
{
scanf("%d",&arr[i]);
}
int flag1 = 0;//标记升序
int flag2 = 0;//标记降序
for(i = 1;i < n; i++)
{
if(arr[i-1] < arr[i])
{
flag1 = 1;
}
else
{
flag2 = 1;
}
}
if(flag1 + flag2 == 2)
{
printf("unsorted\n");
}
else
{
printf("sorted\n");
}
retrun 0;
}
或者:
int main()
{
int n = 0;
scanf("%d",&n);
int arr[n];
int i = 0;
int flag1 = 0;//标记升序
int flag2 = 0;//标记降序
for(i = 0;i < n; i++)
{
scanf("%d",&arr[i]);
if(i > 0)
{
if(arr[i-1] < arr[i])
{
flag1 = 1;
}
else
{
flag2 = 1;
}
}
}
if(flag1 + flag2 == 2)
{
printf("unsorted\n");
}
else
{
printf("sorted\n");
}
retrun 0;
}