首页 > 其他分享 >指针

指针

时间:2022-10-14 23:36:02浏览次数:78  
标签:arr int 地址 printf ptr 指针

重新回顾指针:

C语言指针笔记01 - Morning枫 - 博客园 (cnblogs.com)

&ptr  输出指针变量ptr的地址

ptr  输出指针变量ptr保存的地址(一个十六进制的地址,若输出采用%d,则输出一个整数)//字符串自身的地址就是它本身的值

*ptr  输出指针变量ptr保存的地址的值(相当于直接找到地址修改地址保存的值)


 由于指针也是个变量,所以它自己本身也可以进行算术运算:

 

 地址+1,但是定义是int的指针,int有四字节,所以指针保存的地址在内存中+4,即指向数组中下一个元素

实机演示运行一次:

 自增如此,同理可推自减。


 指针加/减运算:

已经理解自增和自减,加减也不在话下!

 

 此代码表示,指针指向数组当前位置的后面第二位元素


指针的比较:

直接上案例进行判断:

1.

 输出为:ok2和ok3

分析过程:

 ============================================

2.

 输出为:

Address of var[0] = 指向10的地址

Value of var[0] = 10

Address of var[00] = 指向100的地址

Value of var[1] = 100

 此案例进行的是地址的比较。。。


指针数组:

 

 实例:

 

 当执行完:

int i, *ptr[3];

内存中有:

 

 执行完第一个循环体后,有如下内存图变化:

 

 此时被称为指针数组

 

 接着,用指针数组来获取各个值:

 

 完整代码如下:

 1 #include <stdio.h>
 2 
 3 const int MAX = 3;
 4 
 5 int main(){
 6     int var[] = {10,100,200};
 7     int *ptr[3];
 8     for(int i = 0; i < MAX; i++){
 9         ptr[i] = &var[i];
10     }
11     for(int i = 0; i < MAX; i++){
12         printf("Value of var[%d] = %d\n", i, *ptr[i]);
13     }
14     return 0;
15 }

实例运用:

 1 #include <stdio.h>
 2 
 3 const int MAX = 4;
 4 
 5 int main(){
 6     char *books[] = {"西游记","水浒传","红楼梦","三国演义"};
 7 
 8     for(int i = 0; i < MAX; i++){
 9         printf("Value of var[%d] = %s\n", i, books[i]); //字符串本身就是地址,不用*books[]
10     }
11 }

 

&ptr  输出指针变量ptr的地址

ptr  输出指针变量ptr保存的地址(一个十六进制的地址,若输出采用%d,则输出一个整数)//字符串自身的地址就是它本身的值

*ptr  输出指针变量ptr保存的地址的值(相当于直接找到地址修改地址保存的值)


 

多重指针数组(指向指针的指针):

 

 快速入门:

 1 #include <stdio.h>
 2 
 3 int main(){
 4     int var;
 5     int *ptr;
 6     int **pptr;
 7     var = 3000;
 8     ptr = &var;     //把var变量的地址赋值给ptr
 9     pptr = &ptr;    //把ptr存放的地址赋值给pptr
10     printf("var的地址=%p var=%d\n", &var, var);
11     printf("ptr本身的地址=%p ptr存放的地址=%p ptr=%d\n", &ptr, ptr, *ptr);
12     printf("pptr本身的地址=%p pptr存放的地址=%p pptr=%d\n", &pptr, pptr, **pptr);
13     return 0;
14 }

内存图示例:

 

 更多级的指针可以从二级指针理解和去推导即可。


传递指针给函数:

 案例1(传递指针/地址给指针变量)入手:

 1 #include <stdio.h>
 2 
 3 //函数写在main前就不用声明,写在main后就需要在前面声明
 4 void test2(int *p); //函数声明,接收int *
 5 
 6 void main(){
 7     int num = 90;
 8     int *p = &num;      //把num地址赋值给p
 9     test2(&num);    //传地址
10     printf("\n main()中的num=%d", num);
11     test2(p);   //传指针
12     printf("\n main()中的num=%d", num);
13 }
14 
15 void test2(int *p){
16     *p += 1;
17 }

内存示意图:


案例2(传数组给指针变量)入手:

首先确认:

 

 指针数组传递的是地址,而不是值,因此操作过程中有且只有一个数组(理解为全局)在被操作,而不是和值一样操作值的副本(理解为局部)

 1 #include <stdio.h>
 2 
 3 //函数声明
 4 double getAverage(int *arr, int size);
 5 double getAverage2(int *arr, int size);
 6 
 7 int main(){
 8     int balance[5] = {1000,2,3,17,50};  //定义带有五个元素的int数组
 9     double avg;
10     avg = getAverage(balance, 5);  //传递以一个指向数组的指针作为参数
11     printf("Average value is: %f\n", avg);
12     return 0;
13 }
14 
15 double getAverage(int *arr, int size){  //下标遍历
16     int i, sum = 0;
17     double avg;
18     for( i = 0; i < size; i++){
19         sum += arr[i];  //数组下标运算
20         printf("\n arr存放的地址=%p", arr); //不改变arr的地址,只对下标进行修改
21     }
22     avg = (double)sum / size;
23     return avg;
24 }
25 
26 double getAverage2(int *arr, int size){ //指针遍历
27     int i, sum = 0;
28     double avg;
29     for( i = 0; i < size; i++){
30         sum += *arr;    //地址运算
31         printf("\n arr存放的地址=%p", arr);
32         arr++;  //指针的自增运算,会对arr存放的地址做修改
33         //arr[0] = arr + 0
34         //arr[1] = arr + 1个int的字节(4)
35         //arr[2] = arr + 2个int的字节(8)
36     }
37     avg = (double)sum / size;
38     return avg;
39 }

内存图:


返回指针的函数:

 

 快速入门:

 1 #include <stdio.h>
 2 #include <string.h>
 3 
 4 char *strlong(char *str1, char *str2){  //表明此函数是一个指针函数
 5     printf("\n str1的长度是:%d,str2的长度是:%d", strlen(str1), strlen(str2));
 6     if(strlen(str1) >= strlen(str2)){
 7         return str1;
 8     }else{
 9         return str2;
10     }
11 }
12 
13 int main(){
14     char str1[30], str2[30], *str;  //str是一个指针类型,指向一个字符串
15     printf("\n请输入第一个字符串:");
16     gets(str1);
17     printf("\n请输入第二个字符串:");
18     gets(str2);
19     str = strlong(str1, str2);
20     printf("\n Longer string:%s \n", str);
21     return 0;
22 }

 

返回函数指针的有关注意事项:

 

 关于第一点和第二点,需要深刻理解!!!:

 1 #include <stdio.h>
 2 
 3 int *func(){
 4     int n = 100;    //局部变量
 5     return &n;
 6 }
 7 
 8 int main(){
 9     int *p = func();    //func返回指针
10     int n;
11     n = *p;
12     printf("\n value = %d \n", n); //所以最后不一定能输出100
13     return 0;
14 }

对于函数返回销毁,它只是放弃了需要返回的函数的使用权限,但是其中内存改变的值并没有重新初始化(只要没有代码调用新的内存(例如printf会调用内存,此时可能会重新给之前返回的函数占用的内存重新赋值,从而导致返回的值被覆盖)),只要在执行其他代码前调用了返回函数的值,就有可能正常运行输出返回的值。具体看第三点。。

关于第三点,进行了static修饰后,即可正常运行上面的案例程序:

 1 #include <stdio.h>
 2 
 3 int *func(){
 4     static int n = 100;    //如果这个局部变量是static性质的,那么它将保存在内存中的静态数据区
 5     return &n;
 6 }
 7 
 8 int main(){
 9     int *p = func();    //func返回指针
10     int n;
11     n = *p;
12     printf("\n value = %d \n", n); //所以最后不一定能输出100
13     return 0;
14 }

关于static的用法:

static 关键字 - Morning枫 - 博客园 (cnblogs.com)


应用实例:

 

 

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 int *random1(){
 5     static int arr[10]; //让arr的空间在静态数据区保存
 6     for(int i = 0; i < 10; i++){
 7         arr[i] = rand();
 8     }
 9     return arr;
10 }
11 
12 void main(){
13     int *p;
14     p = random1();  //p指向在random1生成的数组的首地址(即第一个元素的地址)
15     for(int i = 0; i < 10; i++){
16         printf("\n%d",*(p+i));
17     }
18 }

函数指针:

 定义:

 

 

 实例演示:

 1 #include <stdio.h>
 2 
 3 int max(int a, int b);
 4 
 5 int main(){
 6     int x, y, maxVal;
 7     //函数指针
 8     //函数指针名字是pmax
 9     //int表示该函数指针指向的函数是返回int类型
10     //(int , int)表示该函数指针指向的函数形参是接收两个int
11     //要注意这个函数指针是有地址的
12     //在定义函数指针时,也可以写形参名(可以不与指向的函数形参名或者传递的变量名相同),如:int (*pmax)(int i, int j) = max;
13     //简单理解为:本身有地址的pmax函数指针保存了max函数的地址//
14     int (*pmax)(int, int) = max;
15     printf("Input two numbers:");
16     scanf("%d%d", &x, &y);
17     maxVal = (*pmax)(x,y);  //通过函数指针去调用参数,即*pmax-->max,当然也可以写成pmax(x,y)也是允许的
18     //类似于*pmax取到了函数max的首地址
19     //maxVal = max(x,y);
20     printf("Max value = %d\n", maxVal);
21     printf("pmax保存的地址:%p,pmax本身的地址:%p", pmax, &pmax);
22     return 0;
23 }
24 
25 int max(int a,int b){   //Max函数,接收两个int,返回值大的
26     return a>b ? a:b;
27 }

内存图:

函数指针——回调函数:

介绍:

 

 实例:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 //回调函数
 5 //int (*f)(void),f是一个函数指针,它可以接收的函数是返回int,没有形参的参数
 6 //f在这被initArray调用,充当了回调函数的角色
 7 void initArray(int *array, int arraySize, int (*f)(void)){
 8     int i;
 9     for(i = 0; i < arraySize; i++){
10         array[i] = f(); //通过函数指针调用getNextRandomValue函数,(*f)()=f()
11     }
12 }
13 
14 //获取随机值
15 int getNextRandomValue(void){
16     return rand();  //rand系统函数,会返回一个随机整数
17 }
18 
19 int main(){
20     int myarray[10], i; //定义一个数组和int
21     //说明:
22     //1.调用initArray函数
23     //2.传入了一个函数名getNextRandomValue(地址),需要使用函数指针来接收
24     initArray(myarray, 10, getNextRandomValue);
25     for ( i = 0; i < 10; i++){
26         printf("%d\n", myarray[i]);
27     }
28     printf("\n");
29     return 0;
30 }

指针使用的注意事项以及空指针:

 

 关于第二点和第三点:

 

标签:arr,int,地址,printf,ptr,指针
From: https://www.cnblogs.com/MorningMaple/p/16773970.html

相关文章

  • 【C语言有这个就够了】五.指针(1)
    (一)指针的定义1.指针是内存中一个最小单元的编号,也就是地址2.平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量intmain(){inta=10;int*p=&a;//指......
  • 36.智能指针类
    程序1:#pragmawarning(disable:4996)//2022年10月13日21:47:46#include<iostream>usingnamespacestd;classMaker{public:Maker(){cout<<......
  • 学习日记--(复习qsort、学习枚举、指针)
    1、两数之和方法一:暴力枚举思路:枚举数组中每一个数,寻找之后的数字是否存在target-x。int*twoSum(int*nums,intnumsSize,inttarget,int*returnSize){for......
  • C++编写一个程序,初始化一个 double 类型的数组,然后把该数组的内容拷贝至3个其他数组中
    也就是说,给定以下声明,则函数调用如下所示:doublesource[5]={1.1,2.2,3.3,4.4,5.5};doubletarget1[5];doubletarget2[5];doubletarget3[5];copy_arr(target1......
  • 力扣刷题时的头节点以及指针的使用
    什么使用要用到指针在力扣刷链表相关的题时可能经常会看到,题目传递过来一个头节点,我们完全可以通过这个头节点来遍历整个链表,为什么还要使用另一个变量来等于他。刚开始学......
  • c语言九(1) 指针
    指针/初探指针1.内存​ 计算机中的最小单位是bit位​ 最小的存储单位为byte字节(一个字节=8位)​ 运行的软件,游戏,程序都是在内存中​ 一个正在运行的程序我们称......
  • Leetcode 844 -- 双指针&&O(1)时间复杂度
    题目描述比较含退格的字符串思路这里主要考虑O(1)空间复杂度的做法。一个字符是否会被删掉,只取决于该字符后面的退格符,而与该字符前面的退格符无关。因此当我们逆......
  • C++智能指针
    C++提供了四个智能指针模版类,分别为:auto_ptr,unique_ptr,shared_ptr与weak_ptr(其中auto_ptr为C++98提供的解决方案,在C++11中已废除,并提供另外三种)。这三者均定义了类似指......
  • C++ 智能指针详解
    这篇博客主要参考上面这个博客和《Boost程序库完全开发指南:深入C++准标准库》第三版   一个智能指针就是一个C++的对象,这个对象的行为像一个指针,但是它却可以在其......
  • C语言-指针
    一、指针的概念要知道指针的概念,要先了解变量在内存中如何存储的。在存储时,内存被分为一块一块的。每一块都有一个特有的编号。而这个编号可以暂时理解为指针,就像酒店的门......