多级指针的概念与用法

多级指针是指指向指针的指针,常见的有二级指针(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;  
}  

函数的组成部分

返回类型:指定函数返回的数据类型(如intfloatvoid)。

函数名:遵循标识符命名规则,需唯一且清晰表达功能。

参数列表:接收外部传入的变量,可为空(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);  
注意事项
  • 函数声明与定义需保持参数和返回类型一致。
  • 避免函数过于复杂,遵循单一职责原则。
  • 递归需谨慎处理栈溢出问题。

作业:

  1. 尝试实现自己的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;
}


运行结果:

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐