一、二级指针:

变量 = 内存地址 + 存储值;

指针 = 内存地址 + 变量内存地址;

二级指针 = 内存地址 + 指针内存地址;

多级指针 = 内存地址 + 上一级内存地址;

void morePointer() {
int n = 190;
int * pointer = &n;
int ** pointerL2 = &pointer; printf("n -> %d\n", n);
printf("pointer -> %p\n", pointer);
printf("pointerL2 -> %p\n", pointerL2); printf("*pointerL2 == pointer == &n ? -> %d (1 true 0 false), *pointerL2 -> %p\n", *pointerL2 == pointer, *pointerL2);
printf("**pointerL2 == *pointer == n ? -> %d (1 true 0 false), **pointerL2 -> %d\n", **pointerL2 == n, **pointerL2);
} int main() {
morePointer();
return 0;
}

二、参数传递

数据传递方式:

1、值传递

2、地址传递

// 使用值传递
void valueSwap(int n1, int n2) {
int temp = n1;
n1 = n2;
n2 = temp; printf("in function valueSwap n1 = %d, n2 = %d\n", n1, n2);
} // 使用地址传递
void addrSwap (int * n1, int * n2) {
int temp = *n1;
*n1 = *n2;
*n2 = temp;
printf("in function addrSwap a = %d, b = %d\n", *n1, *n2);
} void testForSwap() {
int a = 200;
int b = 100;
valueSwap(a, b);
printf("in function testForSwap a = %d, b = %d\n", a, b); addrSwap(&a, &b);
printf("in function testForSwap a = %d, b = %d\n", a, b);
} int main() {
testForSwap();
return 0;
}

三、数组名作为函数参数

一个需求,定义一个函数用来遍历传递进来的数组

void printArray(int * arr, int size) { // 使用指针,允许是变量地址,但也可以是数组名称
for (int i = 0; i < size; ++i) {
printf("element -> (%d), and mem-addr -> %p\n", arr[i], &arr[i]);
} printf("sizeof is pointer or array itself ? -> %d\n", sizeof(arr));
} // 为了明确参数传递的是什么数据,建议是数组就传递数组
void printArrayV2(int array[], int length) {
for (int i = 0; i < length; ++i) {
printf("element -> (%d), and mem-addr -> %p\n", array[i], &array[i]);
} printf("sizeof is pointer or array itself ? -> %d\n", sizeof(array));
} // 封装获取数组长度的方法
int getSize(int array[]) {
return sizeof(array) / sizeof(int);
} // 封装数组遍历的方法:
void printArrayV3(int array[]) {
for (int i = 0; i < getSize(array) ; ++i) {
printf("el -> %d, mem-addr -> %p\n", array[i], &array[i]);
}
printf("sizeof is pointer or array itself ? -> %d\n", sizeof(array));
} int main() {
int array[10] = {2, 4, 6, 8, 10, 12, 14, 16, 18, 20};
printArray(array, 10); printf("sizeof is pointer or array itself ? -> %d\n", sizeof(array)); int array2[9] = { 2 };
printArrayV2(array2, sizeof(array2) / sizeof(int));
printf("sizeof is pointer or array itself ? -> %d\n", sizeof(array2)); int array3[3] = { 100 };
printArrayV3(array3);
printf("sizeof is pointer or array itself ? -> %d\n", sizeof(array3));
return 0;
}

四、指针做函数的返回类型

// 定义一个全局变量
int g_a = 100; int * returnTypeUsage() {
int a = 100; // 定义局部变量 {
int a = 100; // 代码块中的局部变量 {
int a = 100; // 块中块的局部变量
}
}
} // 封装一个获取地址的函数
int* getMemAddr() {
return &g_a;
} int main() {
int *p = getMemAddr(); *p = 33000; printf("g_a -> %d\n", g_a);
return 0;
}

【C】Re07 二级指针,指针与参数的更多相关文章

  1. C语言指针系列 - 一级指针.一维数组,二级指针,二维数组,指针数组,数组指针,函数指针,指针函数

    1. 数组名 C语言中的数组名是一个特殊的存在, 从本质上来讲, 数组名是一个地址, 我们可以打印一个指针的值,和打印一个数组的值来观察出这个本质: int nArray[10] ={ 0 }; in ...

  2. C++ 二维数组(双重指针作为函数参数)

    本文的学习内容参考:http://blog.csdn.net/yunyun1886358/article/details/5659851 http://blog.csdn.net/xudongdong ...

  3. Day8 函数指针做函数参数

    课堂笔记 课程回顾         多态 virtual关键字 纯虚函数 virtual func() = 0;         提前布局vptr指针 面向接口编程 延迟绑定 多态的析构函数的虚函数. ...

  4. go语言基础之数组指针做函数参数

    1.数组指针做函数参数 示例: package main //必须有个main包 import "fmt" //p指向实现数组a,它是指向数组,它是数组指针 //*p代表指针所指向 ...

  5. go语言基础之指针做函数参数用地址传递

    1.指针做函数参数 示例: package main //必须有个main包 import "fmt" func swap(p1, p2 *int) { *p1, *p2 = *p ...

  6. go语言基础之指针做函数参数

    1.指针做函数参数 示例: package main //必须有个main包 import "fmt" func swap(a, b int) { a, b = b, a fmt. ...

  7. [编程] C语言结构体指针作为函数参数

    结构体指针作为函数参数:结构体变量名代表的是整个集合本身,作为函数参数时传递的整个集合,也就是所有成员,而不是像数组一样被编译器转换成一个指针.如果结构体成员较多,尤其是成员为数组时,传送的时间和空间 ...

  8. c++中指针作为函数参数的详细理解

    在C语言中,函数的参数不仅可以是整数.小数.字符等具体的数据,还可以是指向它们的指针.用指针变量作函数参数可以将函数外部的地址传递到函数内部,使得在函数内部可以操作函数外部的数据,并且这些数据不会随着 ...

  9. 深入理解指针—>指针函数与函数指针的区别

    一. 在学习过程中发现这"指针函数"与"函数指针"容易搞错,所以今天,我自己想一次把它搞清楚,找了一些资料,首先它们之间的定义: 1.指针函数是指带指针的函数, ...

  10. C_C++指针指针应用详解

    前言:复杂类型说明 要了解指针,多多少少会出现一些比较复杂的类型,所以我先介绍一下如何完全理解一个复杂类型,要理解复杂类型其实很简单,一个类型里会出现很多运算符,他们也像普通的表达式一样,有优先级,其 ...

随机推荐

  1. Wakeup Source框架设计与实现

    Wakeup Source 为系统组件提供了投票机制,以便低功耗子系统判断当前是否可以进入休眠. Wakeup Source(后简称:WS) 模块可与内核中的其他模块或者上层服务交互,并最终体现在对睡 ...

  2. monaco-editor 实现SQL编辑器

    原文链接:https://www.yuque.com/sxd_panda/antv/editor 安装 yarn add monaco-editor 或 npm install monaco-edit ...

  3. Linux扩展篇-shell编程(三)-shell运算符

    基本语法: 格式一 expr +. -. \*./. %(加.减.乘.除.求余) 格式二 "$((运算式))"或者"$[运算式]" 基本运算符 Shell 和其 ...

  4. Vue学习:12.生命周期实例

    两个小例子,巩固一下生命周期钩子函数. 实例1:初始化渲染 实现功能: 在 Vue 实例数据为空的情况下,用户在一进入页面就向服务器发送请求获取数据,并在数据返回后进行动态渲染. 思路: 创建一个 V ...

  5. 计算机网络实验一:vlan的创建与划分

    这个是 pkt文件 有两道题 所以我是两个文件 https://pan.quark.cn/s/d4170897cb59 https://pan.quark.cn/s/da48878c77f5 发现 复 ...

  6. es语法 rest api 模拟query 根据中文姓名搜索demo

    es语法 rest api 模拟query 根据中文姓名搜索demo order_info_es/_doc/40094182abc GET order_info_es/_settings?pretty ...

  7. OFBiz RCE漏洞复现(CVE-2023-51467)

    漏洞名称 Apache OFBiz 鉴权绕过导致命令执行 漏洞描述 Apache OFBiz是一个非常著名的电子商务平台,是一个非常著名的开源项目,提供了创建基于最新J2EE/XML规范和技术标准,构 ...

  8. 使用Kubesec检查YAML文件安全

    目录 一.系统环境 二.前言 三.Kubesec简介 四.使用Kubesec检查YAML文件安全 五.总结 一.系统环境 本文主要基于Kubernetes1.22.2和Linux操作系统Ubuntu ...

  9. 一款开源、免费、现代化风格的WPF UI控件库 - ModernWpf

    前言 今天大姚给大家分享一款开源(MIT License).免费.现代化风格的WPF UI控件库:ModernWpf. 项目介绍 ModernWpf是一个开源项目,它为 WPF 提供了一组现代化的控件 ...

  10. 嵌入式编程的 4 种模型:轮询、中断、DMA、通道

    轮询方式 对I/O设备的程序轮询的方式,是早期的计算机系统对I/O设备的一种管理方式.它定时对各种设备轮流询问一遍有无处理要求.轮流询问之后,有要求的,则加以处理.在处理I/O设备的要求之后,处理机返 ...