44.【C语言】指针(重难点)(G)

目录

19.字符指针变量

*定义

*简单说明

*如果是字符串

*像数组一样指定访问常量字符串的字符

*练习

20.数组指针变量

*定义

*格式

*例子

问题1

问题2

*利用指针打印

21.二维数组传参的本质

*回顾

往期推荐

19.字符指针变量

*定义

指向字符的指针变量,用于存储字符在内存中的地址

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	char a = 'm';
	char* pc = &a;
	return 0;
}

*简单说明

x86环境下,F11逐语句运行至return 0;

转到内存,输入&a

输入&pc

13 fc 6f 00--倒着写-->00 6f fc 13-->0x006ffc13是a的地址

*如果是字符串

回忆之前的内容

cpp 复制代码
#include <stdio.h>
int main()
{
  char arr[]="abcdef";
  char *pc=arr;
  return 0;
}

arr数组存储着字符串,arr是数组首元素的地址

类比数组,如果是字符串

cpp 复制代码
#include <stdio.h>
int main()
{
	char* pc = "abcdef";
	return 0;
}

x86环境下,F11逐语句运行至return 0;

转到内存,输入&pc

同理倒着写地址

地址框中输入0x00f07bcc 就找到了abcdef

arr数组是一段连续的空间,数组的内容是可以变的,所以常量字符串(char* pc = "abcdef";)(abcdef\0)也是一段连续的空间,常量字符串的内容不可以变(类比const修饰)!

const修饰见38.【C语言】指针(重难点)(C)

写成下方这样程序会崩溃会报错(写入权限访问冲突):

cpp 复制代码
char* pc = "abcedf";
*pc = "abc";

*像数组一样指定访问常量字符串的字符

cpp 复制代码
printf("%c","abcdef"[2]);

访问abcdef常量字符串的第二个字符c

类似于

cpp 复制代码
char arr[]="abcdef";
printf("%c",arr[2]);

同理

cpp 复制代码
printf("%s",pc);

类似于

cpp 复制代码
char arr[]="abcdef";
printf("%s",arr);

*练习

求输出结果

cpp 复制代码
#include <stdio.h>
int main()
{
	char str1[] = "abc";
	char str2[] = "abc";
	const char* str3 = "abc";
	const char* str4 = "abc";
	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;
}

分析:上方代码的==不是比较两个字符串的内容是否相等!比较字符串相等用的是strcmp函数

这里比的分别是数组首元素的地址和常量字符串首字符的地址

虽然两个数组的内容一样,但是abc字符串创建了两次,str1和str2存储的数组的首元素的地址不一样,所以not same

由于常量字符串具有内容不可以变的特点,因此abc没有必要创建两次所以str3和str4是same

下面调用内存说明

x86环境下,F11逐语句运行至return 0;

输入&str1

输入&str2

输入&str3

输入&str4

&str3和&str4都是cc 7b fa 00 ,指向地址0x00fa7bcc

20.数组指针变量

*定义

类比字符指针变量的定义,数组指针变量存放的是数组指针(地址)

*格式

数据类型 (*指针变量名称)[数组元素个数]=&数组名

*例子

问题1:以下代码运行是否有错误?

cpp 复制代码
#include <stdio.h>
int main()
{
	int arr1[5] = { 1,2,3,4,5 };
	int* p1 = &arr1;

    int arr2[5]={ 0 };
	int *p2[5] = &arr2;

    int arr3[5]={ 0 };
	int (*p3)[5] = &arr3;

    int arr4[5]={ 0 };
	int* (*p4)[5] = &arr4;
	return 0;
}

分析:p2的定义出了问题 ,由操作符运算优先级(见15.25【C语言】操作符的属性)可知:*p2[5]代表数组,不能为数组赋值&arr

++[ ]的优先级要高于*号的,所以必须加上()来保证p先和*结合,表明p2是指向数组的指针变量(即数组指针变量),也就是定义p3的写法++

问题2:p1,p3,p4的定义有什么区别

去除int *p2[5]=&arr;这一行后打开调试模式,x86环境下,F11逐语句运行至return 0;

监视arr,p1,p3,p4

打开内存

输入&p1

输入&p3

输入&p4

显然p1是整型指针,p3是数组指针(指向整个含5个int元素的数组的指针),p4是数组指针(指向含5个int*指针的数组的指针)

*利用指针打印

p-->&arr

*p-->*&arr即arr

21.二维数组传参的本质

*回顾

见13.5.【C语言】二维数组

*打印

写法1:实参,形参全是二维数组

cpp 复制代码
#include <stdio.h>
void test(int a[3][5], int r, int c)
{
  int i = 0;
  int j = 0;
  for(i=0; i<r; i++)
  {
    for(j=0; j<c; j++)
    {
      printf("%d ", a[i][j]);
    }
    printf("\n");
   }
}

int main()
{
  int arr[3][5] = {{1,2,3,4,5}, {2,3,4,5,6},{3,4,5,6,7}};
  test(arr, 3, 5);
  return 0;
}

写法2:指针

回顾:一维数组的数组名是首元素(单个,"0"维数组)的地址,可以推出:二维数组的数组名是首元素(第一行一维数组)的地址,同理三维数组的数组名是首元素(二维数组)的地址

所以可以用指针访问

对上方代码略加改动

cpp 复制代码
#include <stdio.h>
void test(int (*p)[5], int r, int c)
{
    int i = 0;
    int j = 0;
    for (i = 0; i < r; i++)
    {
        for (j = 0; j < c; j++)
        {
            printf("%d ", p[i][j]);
        }
        printf("\n");
    }
}

int main()
{
    int arr[3][5] = { {1,2,3,4,5}, {2,3,4,5,6},{3,4,5,6,7} };
    test(arr, 3, 5);
    return 0;
}

打印时p[i][j]有别的写法

如**++*(p+i)[j],*(*(p+i)+j)++**

总结:二维数组传参的本质:传递了地址,传递的是第一行这个一维数组的地址


往期推荐

19.【C语言】指针(重难点)(A)

37.【C语言】指针(重难点)(B)

38.【C语言】指针(重难点)(C)

39.【C语言】指针(重难点)(D)

40.【C语言】指针(重难点)(E)

43.【C语言】指针(重难点)(F)

相关推荐
环能jvav大师3 分钟前
基于R语言的统计分析基础:使用SQL语句操作数据集
开发语言·数据库·sql·数据分析·r语言·sqlite
吱吱鼠叔7 分钟前
MATLAB方程求解:1.线性方程组
开发语言·matlab·php
Antonio91512 分钟前
【CMake】使用CMake在Visual Studio内构建多文件夹工程
开发语言·c++·visual studio
LyaJpunov25 分钟前
C++中move和forword的区别
开发语言·c++
程序猿练习生30 分钟前
C++速通LeetCode中等第9题-合并区间
开发语言·c++·leetcode
一名路过的小码农40 分钟前
C/C++动态库函数导出 windows
c语言·开发语言·c++
m0_6312704042 分钟前
标准c语言(一)
c语言·开发语言·算法
万河归海42842 分钟前
C语言——二分法搜索数组中特定元素并返回下标
c语言·开发语言·数据结构·经验分享·笔记·算法·visualstudio
小周的C语言学习笔记1 小时前
鹏哥C语言36-37---循环/分支语句练习(折半查找算法)
c语言·算法·visual studio
Messiah___1 小时前
【论文阅读】Slim Fly: A Cost Effective Low-Diameter Network Topology 一种经济高效的小直径网络拓扑
开发语言·php