精华内容
下载资源
问答
  • 上一次我们分享了指针的基本应用,这次我们扩展以下指针指针高级应用①行指针指针数组③结构体指针指针指针⑦函数指针...我们调用二维数组的方式有上面六种,想想数组和指针很相似,我们应该如何去定义一个指

    上一次我们分享了指针的基本应用,这次我们扩展以下指针。

    ①行指针

    首先我们先来看看二维数组的调用方法。
    二维数组调用
    我们分析一波,第一个num[i][j];这是我们最常见的访问方式,这就不讲了,然后第二种,我们知道数组名是数组的首地址,所以我们用地址偏移的方式来访问。对于这些转化我们只要记得这么一个,a[i]和*(a+i)(无条件等价)。
    我们调用二维数组的方式有上面六种,想想数组和指针很相似,我们应该如何去定义一个指针来表示二维数组呢?答案很显然,需要一个行指针(也就是数组指针),这个行指针是指针,用来储存数组的。他的定义是:基类型 (*+变量名)[数组的列];例如:int (*p)[4]=num;//这里定义并初始化了。
    行指针

    ②指针数组

    这个指针数组本质是数组,然后这个数组里面储存的是指针(地址)。这个一般都是用在字符数组上面的。例如:

    char *pstr[3]={“admin”, “lili”, “xiaoming”};
    for(i=0; i<3; i++)
    	{
    		printf("%s\n", *(pstr+i));
    		//printf("%s\n", pstr[i]);
    	}
    

    上面这两种方法都可以实现调用。

    ③结构体指针

    一般定义一个结构体是:结构体类型名+变量名+初始化,例如:STAFF_T staff={1001, “sxr”, “123456”, admin};那么我们定义一个结构体指针就是在变量名前加个*。例如:STAFF_T *psta=&staff;我们访问结构体成员的时候会有点不同的是之前是用点运算符,结构体指针是用箭头。例如:psta->ID;
    ④结构体指针数组

    STAFF_T staff[3]={{1001, "sxr", "123456", 1},{1002, "wer", "123456", 2}{1003, "fgr", "123456", 3}};
    STAFF_T *psta=staff;
    printf("%d\n", (psta+2)->ID);
    

    这里可以看出来,如果变成了数组的话,那么我们可以用指针偏移的方式来调用,还可以用之前的许多方式来调用。

    ⑤指针的指针

    显然指针是用来存放地址的,那么指针的指针就是用来放指针变量的地址的。这个一般都是在二维字符数组中使用的比较多,其他一般都不用。

    char str[3][10]={"admin", "lili", "xiaoming"};
    char *pstr[3]={str[0], str[1], str[2]};
    char **pp=pstr;
    for(i=0; i<3; i++)
    	{
    		printf("%s\n", (*(pp+i)));
    	}
    

    //

    int i=5;
    int *pi=&i;
    int **ppi = &pi;
    printf("%p\n", *ppi);
    

    ⑥函数指针
    函数指针是说定义一个指针来保存相同形式的函数的入口地址。那么我们就可以通过这个指针来访问这个函数了。

    int max(int v1, int v2)
    {
            return (v1 > v2 ? v1 : v2);
    }
    
    int min(int v1, int v2)
    {
            return (v1 < v2 ? v1 : v2);
    }
    
    int sum(int v1, int v2)
    {
            return (v1 + v2);
    }
    
    int main() 
    { 
    	int (*pfun)(int , int )=max;	
    	printf("%d\n", pfun(4,6));
    }
    

    要注意这里的函数指针的形式要和要使用的函数的格式一样定义的时候别忘了(),也就是(*pfun)。我们函数指针的用途是作为函数的形参,也就是回调函数。

    ⑦函数指针数组

    我们可以把一系列相同的函数整合在一起,组成函数指针数组。例如:

    int main() 
    { 
    	int i=0;
    	int (*pfun[3])(int , int )={max, min, sum};	
    	for(i=0; i<3; i++)
    	{
    		printf("%d\n", pfun[i](4,6));
    	}
    }
    

    这里别忘了初始化,以及定义的格式。还有就是我们这里调用只能是用[ ]的方式,因为每一个函数的入口地址是不一样的,并不是连续的。

    ⑧无类型指针

    我们之前知道有一个数据类型是void类型的,这个类型我们不能直接定义变量,因为在系统开辟内存空间的时候,不知道应该给他开多大的内存空间。但是这个void的类型的可以定义一个指针变量,无类型的指针可以指向任何的数据类型。
    它的定义是:

    void *p;
    

    他的赋值要遵循这样的原则,可以将任意类型的指针赋给无类型指针,但不能将无类型指针赋给其它类型指针(如果要,那么需要进行强制转化)。

    int a=10int *q=&a,*m;
    p = q;		/*允许赋值*/
    m = (int *)p;//这里就进行了强制转化
    

    另外如果你直接将无类型指针进行算术运算的话,也是不行的,因为我们的算术运算是和指针的基类型的空间大小有关,而我们void类型空间大小不确定,所以无法进行运算,如果要进行那么需要强制转化一下。
    我们一般会思考一个问题,那就是这个无类型指针有什么作用?我们在使用一些函数的时候,有时候会碰到不同类型的参数都要使用同一个函数,那么这时候的函数形参数据类型就可以定义为一个无类型指针,例如我们使用的memcpy函数(可以去C语言中看memcpy函数的原型,你就知道了)。除了这个时候,我们还会碰到返回值类型不确定的情况,这时候我们也可以用无类型的指针先代替,执行完成后在进行强制转化,例如我们后面会介绍的malloc函数(开辟空间的)。

    ⑨const限定符

    可用于不允许被修改的变量和形式参数,数据保护。

    char *strcpy(char *str1,const char *str2);
    

    例如这个strcpy这个函数,str2是源地址,因为我们在复制字符串的时候,不希望这个字符串被改变,不然我们复制的数据就改变了,所以我们加一个const进行修饰,表明这个内存对应的内容不能被修改。
    这个const加在不同的地方是会有不同效果的。

    const int *p;
    int const *p;
    //这上面的两个都表示p对应的内容不能被修改
    int * const P;
    //这个就和之前的不一样,这个表示p储存的地址不能被修改
    p=&a;//这个是错误的,在上面的情况下。
    

    我们总结一下,就是const右边是什么,那么这个什么就不能被改变。

    展开全文
  • 【原创】杨辉三角之函数调用版本

    千次阅读 2010-06-14 17:10:00
    都是直接main函数来书写的,这是很鸡肋的办法,其实要是失业相应的函数调用来写,你就会发现,使用main的方法的数组调整的方式,如果移植到函数调用里,几乎在现实中式完全不能够运行的其中难点就再于二级指针...

    平时比较常见的是杨辉三角的题目的程序,都是直接用main函数来书写的,这是很鸡肋的办法,其实要是失业相应的函数调用来写,你就会发现,使用main的方法的数组调整的方式,如果移植到函数调用里,几乎在现实中式完全不能够运行的

    其中难点就再于二级指针和二维数组的区别,转换,如何进行接引,反解引的问题,其实这个问题你如果明白了,你就相当于明白了C或者C++编译器是如何解释和读取二维数组的数组内容,编译器是如何实现对二维数组的的定位等等问题。

    希望对新入代码业的朋友们能有些帮助,如有纰漏,不吝赐教,谢谢!

     

    下面是关键的知识点

    对于数组 int p[m][n];

    如果要取p[i][j]的值(i>=0 && i<m && 0<=j && j < n),编译器是这样寻址的,它的地址为:

       p + i*n + j;

    从以上可以看出,如果我们省略了第二维或者更高维的大小,编译器将不知道如何正确的寻址。但是我们在编写程序的时候却需要用到各个维数都不固定的二维数组作为参数,这就难办了,编译器不能识别阿,怎么办呢?不要着急,编译器虽然不能识别,但是我们完全可以不把它当作一个二维数组,而是把它当作一个普通的指针,再另外加上两个参数指明各个维数为二维数组手工寻址,这样就达到了将二维数组作为函数的参数传递的目的,根据这个思想,我们可以把维数固定的参数变为维数随即的参数,例如:

        void Func(int array[3][10]);

        void Func(int array[][10]);

    变为:

        void Func(int **array, int m, int n);

    在转变后的函数中,array[i][j]这样的式子是不对的,因为编译器不能正确的为它寻址,所以我们需要模仿编译器的行为把array[i][j]这样的式子手工转变为:

        *((int*)array + n*i + j);

     

     

    下面是我的代码,最后面的注释是程序的输出:

     

     

     

    展开全文
  • 注:不希望用二维数组存放所有数据,这样就不节省空间了。希望一维数组仅存放头地址,来指向输出。 求大神帮帮我QAQ! ``` #include #include #define LEN sizeof(struct Student) struct Student ...
  • 7.2 二维数组的定义和引用 7.2.1 二维数组的定义 7.2.2 二维数组的引用 7.2.3 二维数组的初始化 7.2.4 二维数组程序举例 7.3 字符数组 7.3.1 字符数组的定义 7.3.2 字符数组的初始化 7.3.3 字符数组的引用 ...
  • (29)二维数组指针 (30)二维数组应用实例 (31)二维数组应用实例(2) (32)一维数组来存储字符串 (33)字符串的输入与输出 (34)字符串数组 (35)用于字符串处理的函数 (36)字符串应用实例 (37)传给Main函数的参数 (38)...
  • 12.1 二维数组的定义和引用 132 12.1.1 二维数组的定义 132 12.1.2 二维数组的引用 132 12.2 二维数组的初始化 133 12.3 二维数组应用举例 134 12.4 多维数组的定义和引用 136 习题 136 第13章 选择结构 138 ...
  • 深信服

    2014-10-15 00:18:00
    面试总结: 1. x86 小端字节序(判断代码实现),网络字节序是大端字节序。 2. 堆排序是否是稳定排序。 3. 代码改进以及异常错误处理的细节。 ...4. 两个单链表交叉,如何检测...7. 二维数组结合指针的相关知识点...

    面试总结:

    1. x86 小端字节序(判断代码实现),网络字节序是大端字节序。

    2. 堆排序是否是稳定排序。

    3. 代码改进以及异常错误处理的细节。

    4. 两个单链表交叉,如何检测出来。单链表中如何检测是否存在环(环也许在中间)。

    5. 基类指针调用子类实例的函数。加不加virtual时的区别。 隐藏和覆盖的区别。

    6. 拷贝构造函数能否用值传递。

    7. 二维数组结合指针的相关知识点。

    8. 其他都是笔试的题目。

    转载于:https://www.cnblogs.com/kira2will/p/4025488.html

    展开全文
  • 易学C++,C++入门

    2009-12-06 14:30:11
     7.4.1 线与面——一维数组和二维数组   7.4.2 二维数组的声明和初始化   7.4.3 省略第一维的大小   7.4.4 二维数组在内存中的存储情况   7.4.5 向函数传递二维数组   7.4.6 二维数组转化成一维...
  •  4.12 我看到了用指针调用函数的不同语法形式。到底怎么回事?  4.13 通用指针类型是什么?当我把函数指针赋向void *类型的时候,编译通不过。  4.14 怎样在整型和指针之间进行转换?能否暂时把整数放入指针变量...
  • 4.12 我看到了用指针调用函数的不同语法形式。到底怎么回事? 4.13 通用指针类型是什么?当我把函数指针赋向void *类型的时候,编译通不过。 4.14 怎样在整型和指针之间进行转换?能否暂时把整数放入指针变量中,...
  • 4.12 我看到了用指针调用函数的不同语法形式。到底怎么回事? 79 4.13 通用指针类型是什么?当我把函数指针赋向void *类型的时候,编译通不过。 80 4.14 怎样在整型和指针之间进行转换?能否暂时把整数放入指针...
  • 4.12 我看到了用指针调用函数的不同语法形式。到底怎么回事? 79 4.13 通用指针类型是什么?当我把函数指针赋向void *类型的时候,编译通不过。 80 4.14 怎样在整型和指针之间进行转换?能否暂时把整数放入指针...
  • 4.12 我看到了用指针调用函数的不同语法形式。到底怎么回事? 4.13 通用指针类型是什么?当我把函数指针赋向void *类型的时候,编译通不过。 4.14 怎样在整型和指针之间进行转换?能否暂时把整数放入指针变量中,...
  • 你必须知道的495个C语言问题

    千次下载 热门讨论 2015-05-08 11:09:25
    4.12 我看到了用指针调用函数的不同语法形式。到底怎么回事? 4.13 通用指针类型是什么?当我把函数指针赋向void*类型的时候,编译通不过。 4.14 怎样在整型和指针之间进行转换?能否暂时把整数放入指针变量中...
  • 4.12 我看到了用指针调用函数的不同语法形式。到底怎么回事?  4.13 通用指针类型是什么?当我把函数指针赋向void*类型的时候,编译通不过。 4.14 怎样在整型和指针之间进行转换?能否暂时把整数放入指针变量中...
  •  其他指针问题 4.12 我看到了用指针调用函数的不同语法形式。到底怎么回事? 4.13 通用指针类型是什么?当我把函数指针赋向void*类型的时候,编译通不过。 4.14 怎样在整型和指针之间进行转换?能否暂时把整数...
  • 4.12 我看到了用指针调用函数的不同语法形式。到底怎么回事? 50 4.13 通用指针类型是什么?当我把函数指针赋向void *类型的时候,编译通不过。 51 4.14 怎样在整型和指针之间进行转换?能否暂时把整数放入指针...
  • 《你必须知道的495个C语言问题》

    热门讨论 2010-03-20 16:41:18
    4.12 我看到了用指针调用函数的不同语法形式。到底怎么回事? 50 4.13 通用指针类型是什么?当我把函数指针赋向void *类型的时候,编译通不过。 51 4.14 怎样在整型和指针之间进行转换?能否暂时把整数放入指针...
  • 并运用二维数组记录存车的相应的数据。 取车系统的算法,通过scanf函数输入正确的车牌和取车时间,计算出泊车时间和泊车费用,其中泊车时间不足15分钟的以15分钟计算是一个重点。 主函数的算法,通过函数的调用,...
  • 如何动态分配二维数组 纯虚函数是如何使用的 堆和栈有什么区别 两个类互为成员应该如何声明 bool和BOOL有什么区别 GlobalAlloc(),malloc()和new()有什么区别 如何使用关键字volatile 如何实现int与CString,char*与...
  • 例如,在一维数组[21,46,24,99,57,77,86]中,查找数据元素99,首先从第1个元素21开始进行比较,比较结果与要查找的数据不相等,接着与第2个元素46进行比较,以此类推,当进行到与第4个元素比较时,它们相等,...
  • 12.3.1 指针与一维数组 12.3.2 指针与多维数组 12.4 指针与函数 12.4.1 指针作为函数的参数 12.4.2 指向函数的指针 12.4.3 指针型函数 12.5 指针与字符串 12.5.1 字符串的表达形式 12.5.2 字符指针作为函数参数 ...
  • 5.6 嵌套循环和二维数组 5.6.1 初始化二维数组 5.6.2 使用二维数组 5.7 总结 5.8 复习题 5.9 编程练习 第6章 分支语句和逻辑运算符 6.1 if语句 6.1.1 if else语句 6.1.2 格式化if else语句 6.1.3 if else...
  • o 5.8 我看到了用指针调用函数的不同语法形式。到底怎么回事? o 5.9 我怎样把一个 int 变量转换为 char * 型?我试了类型转换, 但是不行。 * 6. 空 (null) 指针 o 6.1 臭名昭著的空指针到底是什么? o 6.2 ...
  • C++ Primer Plus 中文版 第4版 清晰版

    千次下载 热门讨论 2009-12-06 14:45:21
    5.6 嵌套循环和二维数组 133 5.6.1 初始化二维数组 134 5.7 总结 136 5.8 复习题 136 5.9 编程练习 137 第6章 分支语句和逻辑操作符 139 6.1 if语句 140 6.1.1 if else语句 141 6.1.2 格式化if ...

空空如也

空空如也

1 2 3 4
收藏数 76
精华内容 30
关键字:

如何用指针调用二维数组