c语言指针练习题

发布时间:2026/8/23 19:11:23
c语言指针练习题 前面学了指针的一些运算和指针的类型所以写一些题来巩固一下。第一题定义函数实现交换两个变量的值 函数原型 void exchange(int *, int *)刚开始不用指针写我写的是这种但是写完运行发现num1和num2的值根本没有交换。核心原理C 语言默认是值传递把num1的值拷贝一份给形参a 把num2的值拷贝一份给形参b。a、b是exchange函数内部局部变量在函数自己的栈空间和 main 里面的num1、num2是完全独立两份内存。函数里面交换的只是拷贝出来的副本a和b。函数执行结束a、b直接销毁。完全碰不到 main 函数里面原始的 num1、num2。 所以 main 里面num1、num2保持原样。输出num1 123,num2 322没有交换。所以才用指针的形式传入两个变量的地址通过改变地址所对用的值从而实现值的交换#include stdio.h // 定义函数 void exchange(int *a, int *b) { int c *a; *a *b; *b c; } int main() { int num1 123; int num2 322; exchange(num1,num2); printf(num1 %d,num2 %d \n,num1,num2); return 0; }总结exchange 内部的局部变量函数调用结束栈回收就销毁。值传递只能操作副本。 传入 num1、num2 的地址函数内通过解引用*跨函数访问 main 中的原始内存交换原始变量的值。虽然指针形参 a、b 调用结束销毁但原始变量已经完成修改。第二题定义一个函数接收数组名或首元素指针 和 数组长度 作为参数计算数组的平均数函数原型 int get_avg(int *, int);#include stdio.h int get_avg(int *arr, int len) { int sum 0; for (int i 0; i len; i) { sum arr[i]; } return sum / len; } int main() { int num[] {10, 20, 30, 40, 50}; int len sizeof(num) / sizeof(num[0]); printf(avg %d \n, get_avg(num, len)); return 0; }这里平均数不会有小数但是换成其他值就可能会出现小数所以把自定义函数的类型改掉再把返回值转换为double的形式或者在sum前面乘个1.0第三题定义函数接收一个字符串和字符统计字符在字符串中出现的次数函数原型: int char_count(char *, char)#include stdio.h #include string.h int char_count(char *msg, char ch) { int count 0; int len strlen(msg); // for循环用法 /* for (int i 0; i len; i) { if (ch msg[i]) { count 1; } } */ //while用法 while(*msg!\0) { if (*msg ch) { count; } *msg; } return count; } int main() { char msg[] Shanghai; printf(count %d, char_count(msg, a)); return 0; }这里采用while循环的做法遍历到‘\0’就自动停止循环在循环中加上判断语句从而实现统计字母出现的次数。这里用for循环也可以但是要计算数组的长度。第四题定义函数返回某个字符在字符串中第一次出现的位置函数原型: int firstIndex(char *, char)#include stdio.h #include string.h /** * brief 返回某个字符在字符串中第一次出现的位置如果找不到返回-1 * * param str 要统计字符串 * param ch 要查找字符串 * return int 字符在字符串中第一次出现的位置 */ int firstIndex(char *str, char ch) { int len strlen(str); for (int i 0; i len; i) { if (str[i] ch) { return i; } } return -1; } int main() { char string[] hello world; char character o; int index firstIndex(string, character); printf(index %d,index); return 0; }这题就很简单了进行循环找到下标结束循环即可第五题定义函数返回某个字符在字符串中最后一次出现的位置函数原型: int lastIndex(char *, char)这题就上一题的题目变化一下这题是找到最后一个字符只要等循环进行完记录小标就好了int firstIndex(char *str, char ch) { size_t len strlen(str); int index -1; for (size_t i 0; i len; i) { if (str[i] ch) { index (int)i; } } return index; } int main() { char string[] hello world; printf(index %d\n, firstIndex(string, a)); printf(index %d\n, firstIndex(string, o)); printf(index %d\n, firstIndex(string, l)); return 0; }第六题6. 定义函数 实现字符串中小写字母转大写字母函数原型: char *upperCase(char *)#include stdio.h #include string.h char *upperCase(char *str) { while (*str ! \0) { if (*str a *str z) { *str - 32; } str; } return str; } int main() { char string[] Hello_World; printf(str %s,upperCase(string)); return 0; }运行完程序发现输出的值是一个空格这是为什么呢因为最后返回的值是str;就算循环正常跑完str指针已经走到末尾\0的地址。 返回字符串结束符的地址printf(%s)从\0开始打印输出空啥都看不到。解决循环一开始用一个临时指针记住原始开头地址。char *start str; //保存字符串最开始的首地址循环移动str最后return start;返回开头地址。还有另一种方法用for循环来写因为while循环中str改变了原来指针的用for循环原始的指针不会被改变#include stdio.h #include string.h char *upperCase(char *str) { size_t len strlen(str); for (size_t i 0; i len; i) { if (str[i]a str[i]z) { str[i]-32; } } return str; } int main() { char string[] Hello_World; printf(str %s,upperCase(string)); return 0; }核心总结for 循环用下标 i 遍历原始指针 str 不会被修改天然不会跑到末尾return str 直接就是开头地址。while 直接操作传入的str指针str会把原始指针往后推如果不提前备份首地址return 就返回末尾。但是呢用了for之后会把原来的值给覆盖掉。。。