【C】Re07 二级指针,指针与参数
一、二级指针:
变量 = 内存地址 + 存储值;
指针 = 内存地址 + 变量内存地址;
二级指针 = 内存地址 + 指针内存地址;
多级指针 = 内存地址 + 上一级内存地址;
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 二级指针,指针与参数的更多相关文章
- C语言指针系列 - 一级指针.一维数组,二级指针,二维数组,指针数组,数组指针,函数指针,指针函数
1. 数组名 C语言中的数组名是一个特殊的存在, 从本质上来讲, 数组名是一个地址, 我们可以打印一个指针的值,和打印一个数组的值来观察出这个本质: int nArray[10] ={ 0 }; in ...
- C++ 二维数组(双重指针作为函数参数)
本文的学习内容参考:http://blog.csdn.net/yunyun1886358/article/details/5659851 http://blog.csdn.net/xudongdong ...
- Day8 函数指针做函数参数
课堂笔记 课程回顾 多态 virtual关键字 纯虚函数 virtual func() = 0; 提前布局vptr指针 面向接口编程 延迟绑定 多态的析构函数的虚函数. ...
- go语言基础之数组指针做函数参数
1.数组指针做函数参数 示例: package main //必须有个main包 import "fmt" //p指向实现数组a,它是指向数组,它是数组指针 //*p代表指针所指向 ...
- go语言基础之指针做函数参数用地址传递
1.指针做函数参数 示例: package main //必须有个main包 import "fmt" func swap(p1, p2 *int) { *p1, *p2 = *p ...
- go语言基础之指针做函数参数
1.指针做函数参数 示例: package main //必须有个main包 import "fmt" func swap(a, b int) { a, b = b, a fmt. ...
- [编程] C语言结构体指针作为函数参数
结构体指针作为函数参数:结构体变量名代表的是整个集合本身,作为函数参数时传递的整个集合,也就是所有成员,而不是像数组一样被编译器转换成一个指针.如果结构体成员较多,尤其是成员为数组时,传送的时间和空间 ...
- c++中指针作为函数参数的详细理解
在C语言中,函数的参数不仅可以是整数.小数.字符等具体的数据,还可以是指向它们的指针.用指针变量作函数参数可以将函数外部的地址传递到函数内部,使得在函数内部可以操作函数外部的数据,并且这些数据不会随着 ...
- 深入理解指针—>指针函数与函数指针的区别
一. 在学习过程中发现这"指针函数"与"函数指针"容易搞错,所以今天,我自己想一次把它搞清楚,找了一些资料,首先它们之间的定义: 1.指针函数是指带指针的函数, ...
- C_C++指针指针应用详解
前言:复杂类型说明 要了解指针,多多少少会出现一些比较复杂的类型,所以我先介绍一下如何完全理解一个复杂类型,要理解复杂类型其实很简单,一个类型里会出现很多运算符,他们也像普通的表达式一样,有优先级,其 ...
随机推荐
- C#.NET Winform承载WCF RESTful API (硬编码配置)
1.新建一个名为"WindowsForms承载WCF"的WINFORM程序. 2.在解决方案里添加一个"WCF 服务库"的项目,名为"WcfYeah& ...
- 使用 OpenTelemetry 构建可观测性 05 - 传播和行李(Propagation & Baggage)
我们开发的应用程序可能具有不同的形态和架构:有些是单体应用,有些是微服务.为单体应用程序添加遥测数据相对来说简单,因为所有数据都在同一进程中.然而对于微服务应用程序,情况可能会更具挑战性. 通常,分布 ...
- Oracle使用序列和触发器设置自增字段
一.创建一张工作表 例: create table tv(ID NUMBER primary key,TVNAME VARCHAR(16),ISPASS NUMBER); 二.先创建一个序列 cr ...
- substr()函数用法
substr()函数: 定义和用法: substr()返回字符串的一部分 如果start参数是负数且length小于等于start,则length为0 语法: substr(starting,star ...
- Bike Sharing Analysis(二)- 假设检验方法
假设检验 假设检验是推论统计学(inferential statistics)的一个分支,也就是对一个较小的.有代表性的数据组(例如样本集合)进行分析与评估,并依此推断出一个大型的数据组(例如人口)的 ...
- arm linux 移植 e2fsprogs
背景 之前在zynq平台下处理系统分区,用到了SPI-FLASH以及EMMC. 根据ZYNQ平台的特性以及产品升级需要,规划了 SPI-FLASH放置BootLoader EMMC中分为2个区,一个F ...
- Linux 驱动需要考虑的同步问题
--- title: Linux 驱动需要考虑的同步问题 date: 2020-06-22 07:21:32 categories: tags: - ipc - linux - kernel - dr ...
- 在 VSCode 中编写 Markdown 的进阶指南
最新版的 Visual Studio Code 对 Markdown 的支持已显著提升,其在预览方面的体验甚至可以与 Markdown Preview Enhanced 插件相比.本文将介绍一些优化方 ...
- .net core 3.1 + 动态执行C#
1.使用 using Microsoft.CodeAnalysis.CSharp.Scripting;using Microsoft.CodeAnalysis.Scripting; 2.定义 Rosl ...
- CodeFormer一款既能图像修复、还能视频增强去码的AI软件(下载介绍)
CodeFormer是一款强大的人工智能工具,主要用于图像和视频的修复和增强.它基于深度学习技术,特别是人脸复原模型,可以轻松修复和增强面部图像,提升照片和视频的质量和视觉效果 工作原理 1.通过自动 ...