嵌入式开发学习———Linux环境下C语言学习(九)
摘要:本文介绍了C语言中多级指针的概念与用法,重点讲解了二级指针在动态内存分配中的应用。同时分析了段错误的常见原因,包括空指针解引用和越界访问。文章详细阐述了C语言函数的基础知识,包括函数声明、定义、参数传递和分类,并通过mystrcpy、mystrcat和myatoi等自定义函数的实现示例,展示了如何模拟标准库函数的功能。最后提供了指针与函数结合的实践案例,帮助理解地址传递和返回值处理。
多级指针的概念与用法
多级指针是指指向指针的指针,常见的有二级指针(int **pp)、三级指针(int ***ppp)等。其核心是通过间接引用访问最终的数据。
二级指针示例
int a = 10;
int *p = &a; // 一级指针,指向a
int **pp = &p; // 二级指针,指向指针p
printf("%d", **pp); // 输出10
动态内存分配中的二级指针
int **matrix = (int **)malloc(3 * sizeof(int *));
for (int i = 0; i < 3; i++) {
matrix[i] = (int *)malloc(4 * sizeof(int));
}
// 释放内存时需反向操作
段错误(Segmentation Fault)的原因
段错误通常由非法内存访问引发,常见场景包括:
空指针解引用
int *ptr = NULL;
*ptr = 5; // 访问0地址导致段错误
越界访问
int arr[5];
arr[10] = 1; // 超出数组边界

C语言中的函数基础概念
函数是C语言中可重复使用的代码块,用于执行特定任务。每个函数有唯一的名称,通过参数接收输入,通过返回值输出结果。
函数声明(原型)告知编译器函数的存在:
返回类型 函数名(参数列表);
例如:
int add(int a, int b);
函数定义包含实际代码:
返回类型 函数名(参数列表) {
// 函数体
return 值;
}
示例:
int add(int a, int b) {
return a + b;
}
函数的组成部分
返回类型:指定函数返回的数据类型(如int、float、void)。
函数名:遵循标识符命名规则,需唯一且清晰表达功能。
参数列表:接收外部传入的变量,可为空(void)。参数传递分为值传递(副本)和指针传递(直接操作原数据)。
函数体:包含执行语句的逻辑代码块。
返回值:通过return语句返回结果(void函数可省略)。
函数的分类
库函数:C标准库提供的函数(如printf()、scanf()),需包含头文件(如<stdio.h>)。
用户自定义函数:由程序员根据需求编写,例如:
void greet() {
printf("Hello, World!\n");
}
函数的调用
通过函数名和实参列表调用函数:
int result = add(3, 5);
若函数无返回值,直接调用:
greet();
函数的作用域
局部变量:函数内定义的变量,仅在函数内有效。
全局变量:函数外定义的变量,整个程序可见(需谨慎使用)。
指针与函数
通过指针参数可修改实参的值(地址传递):
void swap(int *x, int *y) {
int temp = *x;
*x = *y;
*y = temp;
}
调用时传递地址:
swap(&a, &b);
注意事项
- 函数声明与定义需保持参数和返回类型一致。
- 避免函数过于复杂,遵循单一职责原则。
- 递归需谨慎处理栈溢出问题。

作业:
- 尝试实现自己的mystrcpy、mystrcat函数,要求和库函数的功能完全一致
mystrcpy:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
char *mystrcpy(char *p1,const char *p2);
int main(int argc, const char *argv[])
{
char str1[100]="wwwwwwwwwwwwwwwwwwwwwwww";
char str2[50]="";
char *p=NULL;
int i=0;
gets(str2);
mystrcpy(str1,str2);
puts(str1);
puts(str2);
mystrcpy(str1,"hello");
puts(str1);
p=mystrcpy(str1,"我爱中国!!!");
puts(p);
return 0;
}
char *mystrcpy(char *p1,const char *p2)
{
int i=0;
while(p2[i])
{
p1[i]=p2[i];
i++;
}
p1[i]=p2[i];
return p1;
}
运行结果:

mystrcat:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
char *mystrcat(char *p1,const char *p2);
int main(int argc, const char *argv[])
{
char str1[100]="";
char str2[100]="";
char *p=NULL;
gets(str1);
gets(str2);
mystrcat(str1,str2);
puts(str1);
mystrcat(str1,"祖国万岁!!!");
puts(str1);
p=mystrcat(str1,"我爱中国!!!");
puts(p);
return 0;
}
char *mystrcat(char *p1,const char *p2)
{
int i=0,j=0;
while(p1[i])
i++;
while(p2[j])
{
p1[i]=p2[j];
i++;
j++;
}
p1[i]=p2[j];
return p1;
}
运行结果:
2.尝试实现自己的myatoi函数,要求和库函数的功能完全一致
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
int myatoi(const char*);
int main(int argc, const char *argv[])
{
printf("%d\n",myatoi("0123456789"));
printf("%d\n",myatoi("1234abc1234"));
printf("%d\n",myatoi("abc1234"));
printf("%d\n",atoi("abc1234"));
return 0;
}
int myatoi(const char *p)
{
int num=0;
while(*p&&(*p>='0'&&*p<='9'))
{
num=num*10+(*p-'0');
p++;
}
return num;
}
运行结果:
更多推荐




所有评论(0)