今天是重点是指针&结构体题题目。🆗🆗🆗
初阶指针_指针的概念
1.使用指针打印数组内容
题目1 使用指针打印数组内容 写一个函数打印arr数组的内容,不使用数组下标,使用指针。 arr是一个整形一维数组。
//方法1 #include<stdio.h> void print(int arr[],int sz) { int* p = arr; int i = 0; for (i = 0; i < sz; i++) { //❌printf("%d ", *p + i);万一数组不是+1增长 printf("%d ", *(p + i)); //数组在内存中连续存放,所以产生连续的地址 } } int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int sz = sizeof(arr) / sizeof(arr[0]); print(arr,sz); return 0; }
//方法2 #include<stdio.h> void print(int arr[], int sz) { int* p = arr; int i = 0; for (i = 0; i < sz; i++) { printf("%d ", *p); p++; } } int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int sz = sizeof(arr) / sizeof(arr[0]); print(arr, sz); return 0; } //或者 #include <stdio.h> int main() { int arr[] = {1,2,3,4,5,6,7,8,9,10}; //在这里完成代码 // 分析:因为数组中存储的元素类型是int类型的,因此只要给一个int的指针, // 依次取索引数组中的每个元素即可 int* p = arr; // 数组名代表数组首元素的地址 for(int i = 0; i < sizeof(arr)/sizeof(arr[0]); ++i) { printf("%d ", *p); // *p: 取到p所指向位置的元素 ++p; // 获取p的下一个位置 } return 0; }
2.字符串逆序
题目2 字符串逆序 写一个函数,可以逆序一个字符串的内容 //前面博文我们讲解过思想,这里我们回顾一下以及其他方法
//方法1_指针 #include<stdio.h> #include<string.h> void Reverse(char arr[],int sz) { char* left = arr; char* right = arr+(sz-1);//sz-2(sizeof) while(left<right) { int tmp = 0; tmp = *left; *left =*right;//交换元素 //left=right交换地址是❌不可以 *right = tmp; left++; right--;//地址++ } } int main() { char arr[] = "abcdef"; int sz = strlen(arr); //int sz=sizeof(arr)/sizeof(arr[0]); Reverse(arr,sz);//逆置函数 //打印逆置数组 printf("%s", arr); return 0; }
//方法2_数组下标 #include<stdio.h> #include<string.h> void Reverse(char arr[], int sz) { int left = 0; int right = sz - 1;//sz-2(sizeof) while (left < right) { int tmp = 0; tmp = arr[left];//元素——指针 arr[left]= arr[right]; arr[right] = tmp; left++; right--;//元素下标++ } } int main() { char arr[] = "abcdef"; int sz = strlen(arr); //int sz=sizeof(arr)/sizeof(arr[0]); Reverse(arr, sz);//逆置函数 //打印逆置数组 int i = 0; for (i = 0; i <= sz; i++) { printf("%c", arr[i]); } //printf("%s", arr); return 0; }
///_数组下标_无论在不在函数都不能产生逆置的效果 //#include<stdio.h> //#include<string.h> //int main() //{ // char arr[] = "abcdef"; // int sz = strlen(arr); // //int sz=sizeof(arr)/sizeof(arr[0]); // char left = arr[0]; // char right =arr[sz - 1];//sz-2(sizeof) // while (left < right) // { // int tmp = 0; // tmp = left;//元素——指针 // left = right; // right = tmp; // left++;❌ // right--;❌//元素+1 // } // printf("%s", arr); // return 0; //} //void reverse(int arr[], int sz) //{ // int left =arr[0];//1 // int right = arr[sz - 1];//5 // while (left < right) // { // int tmp = 0; // tmp = left; // left = right; // right= tmp; // left++;❌ // right--;❌ // } //} //因为一艘进行逆置的时数组里面的元素,两两进行交换实现逆置 //这里的right和left是新的变量,新在栈区创建的空间,交换的是这两个变量。(或许试试指针) //并不会对数组元素产生什么影响 //要进行逆置的是数组里面的元素,两两进行交换实现逆置的 //这里的left right是新的变量,交换的是这两个变量,并不会对数组元素产生什么影响 //字符串数组可以使用下标_%c 不能+-计算。 只是把数组里面的元素值赋值给了left和right这两个局部变量 但是left和right并不代表数组里面的元素,你改变left和right也不会影响数组里面的元素值 会发现地址都是不一样的,这就说明它们存储在内存中的位置是不一样的, 改变left和right自然不会改变数组啦 int a=1; int b=a; b=3; //a和b完全是两个变量 改变b不会影响a的值 这和上面是一个道理哦
3.整形数组和字符串数组
分别写出 整形数组和字符串数组的输入和逆置和打印
整形 数组
//整形输入 #include<stdio.h> int main() { int m = 0; scanf("%d", &m);//输入整形数组的个数 int arr[1000]; int i = 0; for (i = 0; i < m; i++) { scanf("%d", &arr[i]); } return 0; } //或者 #include<stdio.h> int main() { int m = 0; scanf("%d", &m);//输入整形数组的个数 int arr[1000]; int i = 0; for (i = 0; i < m; i++) { scanf("%d", arr+i); } return 0; }
//逆置_数组 #include<stdio.h> int main() { int arr[5] = { 1,2,3,4,5 }; //逆置 int sz = sizeof(arr)/sizeof(arr[0]); //strlen不能计算整形 int left = 0; int right = sz - 1; while (left < right) { int tmp = 0; tmp = arr[left]; arr[left] = arr[right]; arr[right] = tmp; left++; right--; } //打印 int i=0; for (i = 0; i < sz; i++) { printf("%d ", arr[i]); } return 0; } //逆置_指针 #include<stdio.h> void reverse(int arr[],int sz) { int* left = arr; int* right = arr+(sz - 1); while (left < right) { int tmp = 0; tmp = *left; *left=*right; *right= tmp; left++; right--; } } int main() { int arr[5] = { 1,2,3,4,5 }; //逆置 int sz = sizeof(arr) / sizeof(arr[0]); //strlen不能计算整形 reverse(arr, sz); //打印 int i = 0; for (i = 0; i < sz; i++) { printf("%d ", arr[i]); } return 0; }
//打印 #include<stdio.h> int main() { int arr[] = { 1,2,3,4,5 }; int i = 0; int* p = arr; for (i = 0; i < 5; i++) { printf("%d ", arr[i]); } printf("\n"); int j = 0; for (j = 0; j < 5; j++) { printf("%d ", *(arr + j)); //printf("%d ", *(p + j)); } }
字符串数组
//输入 #include<stdio.h> int main() { char arr[1000] = { 0 }; gets(arr); printf("%s", arr); }
关于字符串数组逆置上文有也是下标和指针同时可用。 注意一定是char
//打印 #include<stdio.h> int main() { char arr[] = "tsqxgd"; printf("%s ", arr); printf("\n"); int i = 0; for (i = 0; i < (sizeof(arr) / sizeof(arr[0]) - 1); i++) { printf("%c", arr[i]); } return 0; }
4.打印菱形
题目3 用C语言在屏幕上输出以下图案 //找规律" "和'*" /* 思路: 仔细观察图形,可以发现,此图形中是由空格和*按照不同个数的输出组成的。 上三角:先输出空格,后输出*,每行中 空格:从上往下,一行减少一个 *:2*i+1的方式递增 下三角:先输出空格,后输出*,每行中 空格:从上往下,每行多一个空格 *: 从上往下,按照2*(line-1-i)-1的方式减少,其中:line表示总共有多少行 按照上述方式,将上三角和下三角中的空格和*分别输出即可。 */
#include<stdio.h> int main() { int line = 0; scanf("%d", &line);//输入想要的行数 int i = 0; //注意从0开始到line-1行 //上半行 for (i = 0; i < line; i++)//上半行数循环 { //每一行的打印 int j = 0; //line-1是第一行-i循环第二三等行 for (j = 0; j < line - 1 - i; j++) { printf(" "); } for (j = 0; j < 2 * i + 1; j++) { printf("*"); } printf("\n"); } //下半行 for (i = 0; i < line-1; i++) { int j = 0; for (j = 0; j <= i; j++) { printf(" "); } for (j = 0; j < 2 * (line - 1 - i) - 1; j++) { printf("*"); } printf("\n"); } return 0; }