第十四天:指针进阶(一)

本文详细探讨了C语言中的指针和数组,包括字符指针、指针数组、数组指针以及数组参数和指针参数的用法。通过实例分析,强调了编程中的数学思维和发散思维的重要性。文章还提到了常量字符串、数组比较以及二维数组在传参时的注意事项,并介绍了如何正确理解和使用数组名及地址的概念。
摘要由CSDN通过智能技术生成

  这两天的学习状态较好,都学习了较多内容,由于指针进阶内容偏多,所以分为了两天进行学习,今天学习了指针进阶的前半部分和几道编程题,包括:打印水仙花数,打印菱形,喝汽水,杨辉三角和猜凶手问题,今天我也了解到了,编程语法的实现固然重要,但是如何去实现的数学思维也同样重要,今天的这几道编程题就给我好好上了一课,日后还要加强自己发散思维的训练。

字符指针

在指针的类型中我们知道有一种指针类型为字符指针 char* ;

一般使用:

int main()

{

    char ch = 'w';

    char *pc = &ch;

    *pc = 'w';

    return 0;
}

还有一种使用方式如下:

有一种使用方式如下:
int main()

{

    const char* pstr = "hello gaga.";//把一个字符串首地址放到pstr指针变量里

    printf("%s\n", pstr);

    return 0;

}

那就有可这样的面试题:

#include<stdio.h> 


int main()

{

    char str1[] = "hello gaga.";

    char str2[] = "hello gaga.";

    const char *str3 = "hello gaga.";//常量字符串!不能修改

    const char *str4 = "hello gaga.";
    

    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;

}

指针数组

int* arr1[10]; //存放整形指针的数组

char *arr2[4]; //一级字符指针的数组

char **arr3[5];//二级字符指针的数组

数组指针

数组指针的定义

整形指针: int * pint; 能够指向整形数据的指针。

浮点型指针: float * pf; 能够指向浮点型数据的指针。

那数组指针应该是:能够指向数组的指针。

下面代码哪个是数组指针?

int *p1[10];

int (*p2)[10];

//p1, p2分别是什么?

解释:

int (*p)[10];

//解释:p先和*结合,说明p是一个指针变量,然后指着指向的是一个大小为10个整型的数组。
//所以p是一个指针,指向一个数组,叫数组指针。

//这里要注意:[]的优先级要高于*号的,所以必须加上()来保证p先和*结合。

&数组名VS数组名

#include <Stdio.h>


int main()

{

    int arr[10] = {0};

    printf("%p\n", arr);

    printf("%p\n", &arr);

    return 0;

}
//打印的地址是一样的

#include <stdio.h>


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 表示的是数组的地址,而不是数组首元素的地址。

本例中 &arr 的类型是: int(*)[10] ,是一种数组指针类型

数组的地址+1,跳过整个数组的大小,所以 &arr+1 相对于 &arr 的差值是40.

数组名是数组首元素的地址

但是有两个例外

1.sizeof(数组名) - 数组名表示整个数组,计算的是整个数组的大小,单位是字节

2.&数组名 - 数组名表示整个数组,取出的是整个数组的地址

数组指针的使用

既然数组指针指向的是数组,那数组指针中存放的应该是数组的地址。

#include<stdio.h> 


int main()

{

    int arr[10] = {1,2,3,4,5,6,7,8,9,0};

    int (*p)[10] = &arr;//把数组arr的地址赋值给数组指针变量p

    //但是我们一般很少这样写代码
    int i = 0;
    for(i = 0; i < 10; i++)
    {
        printf("%d ", *((*pa) + i)) ;//打印arr数组   
    }

    return 0;

}

一个数组指针的使用:

#include<stdio.h> 

void print1(int arr[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 ", arr[i][j]);            
        }   
        printf("\n"); 
    }
}

void print2( int(*p)[5], int r, int c)//p是一个数组指针
{
    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}};
    //二维数组首元素地址是第一行
    print1(arr, 3, 5);
    print2(arr, 3, 5);//arr数组名,表示数组首元素地址
    return 0;
}

学了指针数组和数组指针我们来一起回顾并看看下面代码的意思

int arr[5];//整型数组
int *parr1[10];//整型指针数组

int (*parr2)[10];//数组指针该指针能够指向一个数组,数组十个元素,元素类型是int

int (*parr3[10])[5];//parr3是一个存放数组指针的数组,该数组能存放10个数组指针
                    //每个数组指针能够指向一个数组,数组五个元素,五个元素int

数组参数、指针参数

一维数组传参

#include<sstdio.h> 

void test(int arr[])//ok

{}

void test(int arr[10])//ok
{}

void test(int *arr)//ok
{}

void test2(int *arr[20])//ok

{}

void test2(int **arr)//ok

{}

int main()

{

 int arr[10] = {0};

 int *arr2[20] = {0};//存放 int* 的数组

 test(arr);

 test2(arr2);

}

二维数组传参

void test(int arr[3][5])//ok

{}

void test(int arr[][])//不ok,列不能省略
{}

void test(int arr[][5])//ok

{}

//总结:二维数组传参,函数形参的设计只能省略第一个[]的数字。

//因为对一个二维数组,可以不知道有多少行,但是必须知道一行多少元素。

//这样才方便运算。

void test(int *arr)//不ok,传过来是一行数组的地址

{}

void test(int* arr[5])//不ok

{}

void test(int (*arr)[5])//ok

{}

void test(int **arr)//不ok

{}

int main()  

 int arr[3][5] = {0};

 test(arr);

}

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值