【C语言】进阶指针(一)

news2024/11/18 20:15:11

目录

前言: 

一、字符指针

二、指针数组与数组指针

(一)指针数组

(二)数组指针

三、数组传参与指针传参

(一)数组传参

(二)指针传参


前言: 

进阶指针我打算分三篇文章进行讲解,第一篇主要围绕数组与指针进行,第二篇主要围绕函数指针进行,最后一篇会引入面试题讲解。

指针的基本概念:

1、指针就是个变量,用来存放地址,地址唯一标识一块内存空间。

2、指针的大小是固定的4/8个字节(32位/64位)

3、指针是有类型,指针的类型决定的指针+-整数的步长,指针解引用操作的权限。

一、字符指针

字符指针就是指针类型为字符的指针:char*。

可以这样定义:

int main()
{
	char ch = 'w';
	char* pc = &ch;
	*pc = 'w';
	return 0;
}

 如果是字符串呢?

int main()
{
	char* pstr = "hello world.";
	printf("%s\n", pstr);
	return 0;
}

 注意这里指针变量pstr中存放的是字符串中首字符的地址

一道面试题:

int main()
{
    char str1[] = "hello world.";
    char str2[] = "hello world.";
    const char* str3 = "hello world.";
    const char* str4 = "hello world.";
    if (str1 == str2)
        printf("str1 and str2 are same\n");
    else
        printf("str1 and str2 are not same\n");
    if (str3 == str4)
        printf("str3 and str4 are same\n");
    else
        printf("str3 and str4 are not same\n");
    return 0;
}

 输出结果:

str1 and str2 are not same

str3 and str4 are same

分析:str1与str2为两个数组,而数组名代表首元素地址,所以str1与str2不相同。而str3与str4指向的是同一个字符串常量,当几个指针指向同一个字符串的时候,他们实际会指向同一块内存

二、指针数组与数组指针

(一)指针数组

指针数组是数组,数组存放的内容是指针,那么很简单定义数组的时候,数组类型定义为XXX*即可,如:

int* arr1[10]; //整型指针的数组
char* arr2[4]; //一级字符指针的数组
char** arr3[5];//二级字符指针的数组

(二)数组指针

数组指针是指针,指针指向的内容为数组。

观察下面的代码,哪个是数组指针?

int* p1[10];
int (*p2)[10];

注:[]操作符的优先级高于*。

分析:p1为指针数组。p2先于*结合,即p2为指针变量,指针变量的类型为int [10]整型数组,所以p2为数组指针。

我们知道数组名arr表示首元素的地址,那么&arr 取出的是不是首元素的地址呢?

其实数组名表示数组首元素的地址有两个例外:

1、sizeof(arr),sizeof计算的是整个数组大小,单位为字节。

2、&arr,此时取出的是整个数组的地址。

 我们利用下面的代码进行验证:

int main()
{
	int arr[10] = { 0 };
	printf("arr = %p\n", arr);
	printf("&arr= %p\n", &arr);
	printf("arr+1 = %p\n", arr + 1);
	printf("&arr+1= %p\n", &arr + 1);
	return 0;
}

 结果为:

 我们发现&arr+1跳过的是整个数组的大小。

数组指针一般用于二维数组中。如:

void print_arr1(int arr[3][5], int row, int col)
{
    int i = 0;
    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
        {
            printf("%d ", arr[i][j]);
        }
        printf("\n");
    }
}

void print_arr2(int(*arr)[5], int row, int col)
{
    int i = 0;
    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
        {
            printf("%d ", arr[i][j]);
        }
        printf("\n");
    }
}

int main()
{
    int arr[3][5] = { 1,2,3,4,5,6,7,8,9,10 };
    print_arr1(arr, 3, 5);
    //数组名arr,表示首元素的地址
    //但是二维数组的首元素是二维数组的第一行
    //所以这里传递的arr,其实相当于第一行的地址,是一维数组的地址
    //可以数组指针来接收
    print_arr2(arr, 3, 5);
    return 0;
}

三、数组传参与指针传参

如何将【数组】或【指针】作为参数传给函数呢?

(一)数组传参

正确设计:

void test1(int arr[])
{}
void test1(int arr[10])
{}
void test1(int* arr)
{}
void test2(int* arr[20])
{}
void test2(int** arr)
{}
void test3(int arr[3][5])
{}
void test3(int arr[][5])
{}
void test3(int (*arr)[5])
{}
int main()
{
	int arr1[10] = { 0 };
	int* arr2[20] = { 0 };
	int arr3[3][5] = { 0 };
	test1(arr1);
	test2(arr2);
	test3(arr3);
}

错误设计:

void test3(int arr[][])//err
{}
void test3(int* arr)//err
{}
void test3(int* arr[5])//err
{}
void test3(int** arr)//err
{}
int main()
{
	int arr1[10] = { 0 };
	int* arr2[20] = { 0 };
	int arr3[3][5] = { 0 };
	test1(arr1);
	test2(arr2);
	test3(arr3);
}

 错误分析:

首先要搞清楚函数参数的类型,test3(arr3)中明显传入的是arr3数组的首元素地址,又arr3为二维数组,所以该函数实际传入参数为arr3首行元素的地址,本质是指针

然后我们看函数定义中设计的参数:

void test3(int arr[][])二维数组可以省略行,但是不能省略列,所以该函数设计错误。
void test3(int* arr)此函数设计参数类型为指针数组,本质是数组,与传入参数不符,所以该函数设计错误。
void test3(int* arr[5])同上。
void test3(int** arr)此函数设计参数类型为二级指针数组,本质是数组,与传入参数不符,所以该函数设计错误。

(二)指针传参

void print(int* p, int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d\n", *(p + i));
	}
}

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9 };
	int* p = arr;
	int sz = sizeof(arr) / sizeof(arr[0]);
	//一级指针p,传给函数
	print(p, sz);
	return 0;
}

当函数的参数部分为一级指针时,该函数能接收什么参数呢?

比如:void test(char* p)

以下供参考: 

void test(char* p)
{}

int main()
{
	char ch = 'w';
	char ptr = &ch;
	char arr[] = "abcdef";
	test(&ch);
	test(ptr);
	test(arr);
}

 当函数的参数部分为二级指针时,该函数又能接收什么参数呢?比如:

void test1(int** p1)

void test2(char** p2)

以下供参考: 

void test1(int** p)
{}
void test2(char** p)
{}
int main()
{
	int n = 10;
	int* p1 = &n;
	int** pp = &p1;
	test1(pp);
	test1(&p1);
	char c = 'b';
	char* pc = &c;
	char** ppc = &pc;
	char* arr[10];
	test2(&pc);
	test2(ppc);
	test2(arr);
	return 0;
}

今天的内容就分享到这,接下来博主还会继续跟进进阶指针的更新,关注博主不迷路🔥🔥🔥

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/726821.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Python】面向对象 ③ ( 构造函数 | 成员变量赋值问题 | 构造方法引入 | 构造函数可以同时定义成员变量 )

文章目录 一、构造函数1、成员变量赋值问题2、构造方法引入3、代码示例 - 构造方法3、构造函数可以同时定义成员变量 一、构造函数 1、成员变量赋值问题 在之前的博客中 , 定义的 Python 类 Student : class Student:name None # 姓名age None # 年龄def info(self):print…

AIGC:文生图模型Stable Diffusion

1 Stable Diffusion介绍 Stable Diffusion 是由CompVis、Stability AI和LAION共同开发的一个文本转图像模型&#xff0c;它通过LAION-5B子集大量的 512x512 图文模型进行训练&#xff0c;我们只要简单的输入一段文本&#xff0c;Stable Diffusion 就可以迅速将其转换为图像&am…

飞行动力学 - 第5节-part2-喷气式飞机的爬升性能 之 基础点摘要

飞行动力学 - 第5节-part2-喷气式飞机的爬升性能 之 基础点摘要 1. 最大爬升角2. 最大爬升率3. 一些历史记录4. 参考资料 1. 最大爬升角 喷气式飞机由于推力稳定输出&#xff0c;其最大爬升角相对容易计算&#xff1a; 2. 最大爬升率 爬升率相对复杂&#xff0c;使用无量纲数据…

【原生HTML】表格

1、一个表格合并后多选 我这里的表格是在elementUI的tabs页里的&#xff0c;所以数据格式多了一层 数据格式 html原生代码&#xff1a; <tableclass"multi-table"style"width: 100%; border-color: #ebeef5"border"1px"cellspacing"0&qu…

使用IDEA时关于Tomcat处理HTML请求乱码的问题(通过访问服务器的静态页面F12后响应头里的编码格式都是utf-8了,还是乱码)

解决方法在文末&#xff0c;大家可以下滑到底部直接浏览 今天在使用Tomcat访问静态页面时&#xff0c;页面出现乱码问题&#xff0c;各种办法的试了&#xff0c;内心一度处于奔溃的边缘&#xff0c;在外出跑步冷静了一下之后&#xff0c;思路渐渐清晰。 出现乱码后的第一步&a…

C数据结构与算法——顺序表 应用

实验任务 (1) 掌握顺序表结构及其 C 语言实现&#xff1b; (2) 掌握插入、删除等基本算法&#xff1b; (3) 掌握顺序表的基本应用&#xff08;将两个有序线性表合并为一个有序表&#xff09;。 实验内容 使用 C 语言实现顺序表的类型定义与算法函数&#xff1b;编写 main()函…

Verilog parameter的用法

parameter简介 parameter”是Verilog HDL中的一个关键字&#xff0c;代表着参数型常量&#xff0c;即用parameter来定义一个标识符代表一个常量&#xff0c;这样可以提高程序的可读性与可维护性。 parameter应用场景 #&#xff08;parameter number500&#xff09; 表示定义一…

零代码开发平台免费,未来企业数字化转型常用工具

什么是零代码开发平台 零代码开发平台指的是一种软件开发工具&#xff0c;能够使开发人员在不编写代码的情况下构建应用程序或快速应用程序。它们一般是通过拖放的方式创建用户界面&#xff0c;配置业务逻辑&#xff0c;集成数据库等操作&#xff0c;节省开发周期和人力成本。…

安森美-深力科NC7SV08P5X能成为极高速、高驱动和低功耗应用的理想选择吗?

描述&#xff1a; 关于安森美-深力科NC7SV08P5X是飞兆超低功率 (ULP-A) TinyLogic 系列的一个 2 输入“与”门。 ULP-A 是要求极高速、高驱动和低功耗应用的理想选择。 用于宽低电压工作范围&#xff08;0.9 V 到 3.6 V VCC&#xff09;&#xff0c;适合驱动和速度要求高于 Ti…

需求分析的概念和原则

概念和原则 需求分析是指在软件开发和项目管理中&#xff0c;通过收集、理解、分析和记录用户和系统对系统或产品的需求&#xff0c;以确定其详细的特征和功能。它是一个关键的过程&#xff0c;旨在确保项目成功地满足用户的需求和期望。 在进行需求分析时&#xff0c;有一些…

常用数据聚类算法总结记录

本文的主要目的是总结记录日常学习工作中常用到的一些数据聚类算法&#xff0c;对其原理简单总结记录&#xff0c;同时分析对应的优缺点&#xff0c;以后需要的时候可以直接翻看&#xff0c;避免每次都要查询浪费时间&#xff0c;欢迎补充。 聚类算法是一种无监督学习的方法&am…

Docker安装 Nginx

相关文章&#xff1a; Docker容器之间的连接和通信(四)_做测试的喵酱的博客-CSDN博客 一、 Docker安装 Nginx 1.1、查看可用的 Nginx 版本 docker search nginx 1.2、安装最新 Nginx 版本 docker pull nginx:latest 1.3 查看本地镜像 docker images 1.4 运行容器 运行…

架构-新教材补充内容

系统工程 两分&#xff0c;需要计算的选择题 #mermaid-svg-opoH5AvD05BTqVHp {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-opoH5AvD05BTqVHp .error-icon{fill:#552222;}#mermaid-svg-opoH5AvD05BTqVHp .error-te…

关系型数据库全栈入选唯一厂商!GBASE南大通用的“可信”时刻

作为国产数据库的领军企业&#xff0c;业界公认的“可信”力量&#xff0c;GBASE南大通用深度参与大会&#xff0c;与各协会领导、学术大咖、技术领军共同论道我国数据库自立自强之路。 现在让我们一起盘点为期两天的议程中GBASE南大通用的“高光”时刻&#xff0c;且看GBASE是…

7.7工作总结

一、前言&#xff1a;这周三领导让我修改一个入库接口&#xff0c;需要加入三个参数&#xff0c;我直接把相应的数据加进去了忽略了这个参数是放在一个List中的同时还需要转成json的形式。因此我又修改了一遍。 二、错误的形式&#xff1a; 在接口文档中是这样的形式&#xff…

最新版Flink CDC MySQL同步Elasticsearch(一)

1.环境准备 首先我们要基于Flink CDC MySQL同步MySQL的环境基础上&#xff08;flink-1.17.1、Java8、MySQL8&#xff09;搭建Elasticsearch7-17-10和Kibana 7.17.10。笔者已经搭建好环境&#xff0c;这里不做具体演示了&#xff0c;如果需要Es的搭建教程情况笔者其他博客 注意…

【案例教程】GPT模型支持下的Python-GEE遥感云大数据分析、管理与可视化技术及多领域案例实践实践技术

随着航空、航天、近地空间等多个遥感平台的不断发展&#xff0c;近年来遥感技术突飞猛进。由此&#xff0c;遥感数据的空间、时间、光谱分辨率不断提高&#xff0c;数据量也大幅增长&#xff0c;使其越来越具有大数据特征。对于相关研究而言&#xff0c;遥感大数据的出现为其提…

海格里斯HEGERLS智能四向穿梭车系统是如何赋能企业降本增效的?

随着人工智能和物联网等新技术的更新迭代&#xff0c;物流行业数字化&#xff0c;智能仓储已成趋势。我国智能仓储在“互联网”战略的带动下快速发展&#xff0c;与大数据、云计算等新一代互联网技术深度融合&#xff0c;智能仓储整个行业向着运行高效、便捷、低成本的方向迈进…

Vision Transformer推理中线性-角度注意转换压缩自注意

文章目录 Castling-ViT: Compressing Self-Attention via Switching Towards Linear-Angular Attention at Vision Transformer Inference摘要本文方法实验结果 Castling-ViT: Compressing Self-Attention via Switching Towards Linear-Angular Attention at Vision Transform…

Angular 调试工具(Augury)

目录 1、简介 2、检验代码 3、Angury 本地构建和安装 3.1 添加到Chrome 浏览器&#xff1a; 3.2 添加到Firefox浏览器 4、项目中对应的Npm脚本 5、Augury 三大主要功能 5.1 组件树&#xff08;Component Tree&#xff09; 5.1.1 Component Tree 5.2 路由树&#xff0…