C语言进阶⑫(指针下)(指针和数组笔试题解析)(杨氏矩阵)

目录

1指针和数组笔试题解析

一维数组

字符数组

二维数组

2指针笔试题一

笔试题1:

笔试题2:

笔试题3:

笔试题4:

笔试题5:

笔试题6:

笔试题7:

笔试题8:

3笔试题二

3.1指向函数指针数组的指针

3.2函数指针

3.3函数指针

3.4指针+-

3.5数组指针

3.6函数参数设计

3.7函数设计

3.8(编程)杨氏矩阵

3.9(编程)模拟实现qsort


1指针和数组笔试题解析

一维数组

说出下面代码的输出结果


//一维数组
#include<stdio.h>
int main()
{
    int a[] = { 1,2,3,4 };
    printf("%d\n", sizeof(a));
    printf("%d\n", sizeof(a + 0));
    printf("%d\n", sizeof(*a));
    printf("%d\n", sizeof(a + 1));
    printf("%d\n", sizeof(a[1]));

    printf("%d\n", sizeof(&a));
    printf("%d\n", sizeof(*&a));
    printf("%d\n", sizeof(&a + 1));
    printf("%d\n", sizeof(&a[0]));
    printf("%d\n", sizeof(&a[0] + 1));
    return 0;
}

解析:


//一维数组
//数组名的意义:
//1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
//2. & 数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
//3. 除此之外所有的数组名都表示首元素的地址。
#include<stdio.h>
int main()
{
    int a[] = { 1,2,3,4 };
    printf("%d\n", sizeof(a));//16
    printf("%d\n", sizeof(a + 0));//4/8 第一个元素的地址
    printf("%d\n", sizeof(*a));//4   第一个元素的大小
    printf("%d\n", sizeof(a + 1));//4/8   第二个元素的地址
    printf("%d\n", sizeof(a[1]));//4    第二个元素的大小

    printf("%d\n", sizeof(&a));//4/8  整个数组的地址
    printf("%d\n", sizeof(*&a));//16  整个数组的大小(取地址解引用相当于最上面的printf)
    printf("%d\n", sizeof(&a + 1));//4/8  跳过a数组的下个空间的地址
    printf("%d\n", sizeof(&a[0]));//4/8   第一个元素的地址
    printf("%d\n", sizeof(&a[0] + 1));//4/8  第二个元素的地址
    return 0;
}

字符数组

说出下面代码的输出结果


#include<stdio.h>
#include<string.h>
int main()
{
    char arr[] = { 'a','b','c','d','e','f' };
    printf("%d\n", sizeof(arr));
    printf("%d\n", sizeof(arr + 0));
    printf("%d\n", sizeof(*arr));
    printf("%d\n", sizeof(arr[1]));
    printf("%d\n", sizeof(&arr));
    printf("%d\n", sizeof(&arr + 1));
    printf("%d\n", sizeof(&arr[0] + 1));

    printf("%d\n", strlen(arr));
    printf("%d\n", strlen(arr + 0));
    printf("%d\n", strlen(*arr));
    printf("%d\n", strlen(arr[1]));
    printf("%d\n", strlen(&arr));
    printf("%d\n", strlen(&arr + 1));
    printf("%d\n", strlen(&arr[0] + 1));
    return 0;
}

解析:


#include<stdio.h>
#include<string.h>
int main()
{
    char arr[] = { 'a','b','c','d','e','f' };
    printf("%d\n", sizeof(arr));//6
    printf("%d\n", sizeof(arr + 0));//4/8  第一个元素的地址
    printf("%d\n", sizeof(*arr));//1   第一个元素的大小
    printf("%d\n", sizeof(arr[1]));//1
    printf("%d\n", sizeof(&arr));//4/8
    printf("%d\n", sizeof(&arr + 1));//4/8
    printf("%d\n", sizeof(&arr[0] + 1));//4/8

    printf("%d\n", strlen(arr));//随机数(没有\0)
    printf("%d\n", strlen(arr + 0));//上面的随机数(没有\0)
    printf("%d\n", strlen(*arr));//(把97当做地址)错误
    printf("%d\n", strlen(arr[1]));//错误
    printf("%d\n", strlen(&arr));//上面的随机数(没有\0)
    printf("%d\n", strlen(&arr + 1));//上面的随机数-6(没有\0)
    printf("%d\n", strlen(&arr[0] + 1));//上面的随机数-1(没有\0)
    return 0;
}

说出下面代码的输出结果


#include<stdio.h>
#include<string.h>
int main()
{
    char arr[] = "abcdef";
    printf("%d\n", sizeof(arr));
    printf("%d\n", sizeof(arr + 0));
    printf("%d\n", sizeof(*arr));
    printf("%d\n", sizeof(arr[1]));
    printf("%d\n", sizeof(&arr));
    printf("%d\n", sizeof(&arr + 1));
    printf("%d\n", sizeof(&arr[0] + 1));

    printf("%d\n", strlen(arr));
    printf("%d\n", strlen(arr + 0));
    printf("%d\n", strlen(*arr));
    printf("%d\n", strlen(arr[1]));
    printf("%d\n", strlen(&arr));
    printf("%d\n", strlen(&arr + 1));
    printf("%d\n", strlen(&arr[0] + 1));
    return 0;
}

解析:


#include<stdio.h>
#include<string.h>
int main()
{
    char arr[] = "abcdef";
    printf("%d\n", sizeof(arr));//7          (加上\0)!!!
    printf("%d\n", sizeof(arr + 0));//4/8
    printf("%d\n", sizeof(*arr));//1
    printf("%d\n", sizeof(arr[1]));//1
    printf("%d\n", sizeof(&arr));//4/8
    printf("%d\n", sizeof(&arr + 1));//4/8
    printf("%d\n", sizeof(&arr[0] + 1));//4/8

    printf("%d\n", strlen(arr));//6
    printf("%d\n", strlen(arr + 0));//6
    printf("%d\n", strlen(*arr));//错误emm
    printf("%d\n", strlen(arr[1]));//错误emm
    printf("%d\n", strlen(&arr));//6
    printf("%d\n", strlen(&arr + 1));//随机数
    printf("%d\n", strlen(&arr[0] + 1));//5
    return 0;
}

说出下面代码的输出结果


#include<stdio.h>
#include<string.h>
int main()
{
    char* p = "abcdef";
    printf("%d\n", sizeof(p));
    printf("%d\n", sizeof(p + 1));
    printf("%d\n", sizeof(*p));
    printf("%d\n", sizeof(p[0]));
    printf("%d\n", sizeof(&p));
    printf("%d\n", sizeof(&p + 1));
    printf("%d\n", sizeof(&p[0] + 1));

    printf("%d\n", strlen(p));
    printf("%d\n", strlen(p + 1));
    printf("%d\n", strlen(*p));
    printf("%d\n", strlen(p[0]));
    printf("%d\n", strlen(&p));
    printf("%d\n", strlen(&p + 1));
    printf("%d\n", strlen(&p[0] + 1));
    return 0;
}

解析:


#include<stdio.h>
#include<string.h>
int main()
{
    char* p = "abcdef";
    printf("%d\n", sizeof(p));//4/8  指针的大小
    printf("%d\n", sizeof(p + 1));//4/8  第二个元素的地址!
    printf("%d\n", sizeof(*p));//1    第一个元素的大小!
    printf("%d\n", sizeof(p[0]));//1  同上emm
    printf("%d\n", sizeof(&p));//4/8
    printf("%d\n", sizeof(&p + 1));//4/8
    printf("%d\n", sizeof(&p[0] + 1));//4/8

    printf("%d\n", strlen(p));//6
    printf("%d\n", strlen(p + 1));//5
    printf("%d\n", strlen(*p));//错误
    printf("%d\n", strlen(p[0]));//错误
    printf("%d\n", strlen(&p));//随机数  从p的地址算,p里面存的地址!!
    printf("%d\n", strlen(&p + 1));//和上面不同的随机数
    printf("%d\n", strlen(&p[0] + 1));//5
    return 0;
}

二维数组

说出下面代码的输出结果


#include<stdio.h>
int main()
{
    int a[3][4] = { 0 };
    printf("%d\n", sizeof(a));
    printf("%d\n", sizeof(a[0][0]));
    printf("%d\n", sizeof(a[0]));
    printf("%d\n", sizeof(a[0] + 1));
    printf("%d\n", sizeof(*(a[0] + 1)));
    printf("%d\n", sizeof(a + 1));
    printf("%d\n", sizeof(*(a + 1)));
    printf("%d\n", sizeof(&a[0] + 1));
    printf("%d\n", sizeof(*(&a[0] + 1)));
    printf("%d\n", sizeof(*a));
    printf("%d\n", sizeof(a[3]));
    return 0;
}

解析:


#include<stdio.h>
int main()
{
    int a[3][4] = { 0 };
    printf("%d\n", sizeof(a));//12*4=48   整个数组大小
    printf("%d\n", sizeof(a[0][0]));//4   第一个元素大小
    printf("%d\n", sizeof(a[0]));//16   下一a[0]不是单独放在内部,不表示第一行
    printf("%d\n", sizeof(a[0] + 1));//4/8  a[0]是整形的地址,+1跳过一个整形emm
    printf("%d\n", sizeof(*(a[0] + 1)));//4  第一行第二个元素的大小
    printf("%d\n", sizeof(a + 1));//4/8    第二行的地址
    printf("%d\n", sizeof(*(a + 1)));//16   第二行大小  相当于a[1]
    printf("%d\n", sizeof(&a[0] + 1));//4/8   第二行地址
    printf("%d\n", sizeof(*(&a[0] + 1)));//16   第二行大小   同上上 
    printf("%d\n", sizeof(*a));//16     第一行大小等价于*(a+0)等价于a[0]     
    printf("%d\n", sizeof(a[3]));//16    3+5  1.值属性:8   2.类型属性:int
    //a[3]  值属性越界了,但是类型属性是int [4]  编译器推算的,不会真正取地址emm  
                                           //且sizeof内部是不进行计算的
    return 0;
}

总结:

数组名的意义:

1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。

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

3. 除此之外所有的数组名都表示首元素的地址。

2指针笔试题一

笔试题1:


#include<stdio.h>
int main()
{
    int a[5] = { 1, 2, 3, 4, 5 };
    int *ptr = (int *)(&a + 1);
    printf( "%d,%d", *(a + 1), *(ptr - 1));
    return 0;
}
//程序的结果是什么?

解析:


#include<stdio.h>
int main()
{
    int a[5] = { 1, 2, 3, 4, 5 };
    int* ptr = (int*)(&a + 1);  //整个数组地址+1跳过一个数组  本来的类型是int*[5]
    printf("%d,%d", *(a + 1), *(ptr - 1));//2,5  都是整形指针,只能跳过4个字节emm
    return 0;
}

笔试题2:


#include<stdio.h>
//由于还没学习结构体,这里告知结构体的大小是20个字节
struct Test
{
    int Num;
    char* pcName;
    short sDate;
    char cha[2];
    short sBa[4];
}*p;
//假设p 的值为0x100000。 如下表表达式的值分别为多少?
//已知,结构体Test类型的变量大小是20个字节
int main()
{
    printf("%p\n", p + 0x1);
    printf("%p\n", (unsigned long)p + 0x1);
    printf("%p\n", (unsigned int*)p + 0x1);
    return 0;
}

解析:


#include<stdio.h>
//由于还没学习结构体,这里告知结构体的大小是20个字节
struct Test
{
    int Num;
    char* pcName;
    short sDate;
    char cha[2];
    short sBa[4];
}*p;
//假设p 的值为0x100000。 如下表表达式的值分别为多少?
//已知,结构体Test类型的变量大小是20个字节
int main()
{
    printf("%p\n", p + 0x1);//+16进制的1,就是1  这个结构体指针+1跳过20字节
                            //0x100000变成0x100014    (16进制14就是10进制的20)
    printf("%p\n", (unsigned long)p + 0x1); //整形+1就是+1   0x100001
    printf("%p\n", (unsigned int*)p + 0x1);//跳过4个字节   0x100004
    return 0;
}

笔试题3:


#include<stdio.h>
int main()
{
    int a[4] = { 1, 2, 3, 4 };
    int* ptr1 = (int*)(&a + 1);
    int* ptr2 = (int*)((int)a + 1);
    printf("%x,%x", ptr1[-1], *ptr2);
    return 0;
}

解析:


#include<stdio.h>
int main()
{
    int a[4] = { 1, 2, 3, 4 };
    int* ptr1 = (int*)(&a + 1);   //跳过一个数组
    int* ptr2 = (int*)((int)a + 1);   //a的地址转化为int +1
                                     //一个地址给一个字节,差一个字节
    printf("%x,%x", ptr1[-1], *ptr2);  //ptrl[-1]==*(ptr1-1)==4
    return 0;
}
//结果是4,2000000    看图

看看佬的讲解:

笔试题4:


#include<stdio.h>
int main()
{
    int a[3][2] = { (0, 1), (2, 3), (4, 5) };
    int* p;
    p = a[0];
    printf("%d", p[0]);
    return 0;
}

解析:


#include<stdio.h>
int main()
{
    int a[3][2] = { (0, 1), (2, 3), (4, 5) };
    //()不是{}   是逗号表达式! 天坑  1  3
    //                            5  0
    //                            0  0
    int* p;
    p = a[0];
    printf("%d", p[0]);//p==a[0]   p[0]==a[0][0]==1
    return 0;
}

笔试题5:


#include<stdio.h>
int main()
{
    int a[5][5];
    int(*p)[4];
    p = a;
    printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
    return 0;
}

解析:


#include<stdio.h>
int main()
{
    int a[5][5];
    int(*p)[4];
    p = a;
    printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
    return 0;
}
//a的类型是int(*)[5]+1跳过5*4个字节   p的类型是int(*)[4]  +1跳过4*4个字节
//答案是FFFFFFFC,-4    看图

能力有限,再看看佬的讲解:

笔试题6:


#include<stdio.h>
int main()
{
    int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    int* ptr1 = (int*)(&aa + 1);
    int* ptr2 = (int*)(*(aa + 1));
    printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));
    return 0;
}

解析:


#include<stdio.h>
int main()
{
    int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    int* ptr1 = (int*)(&aa + 1); //&aa整个数组的地址+1跳过整个数组
    int* ptr2 = (int*)(*(aa + 1));//首元素(首元素是第一行)地址+1,第二行地址
    //第二行首元素地址解引用得到6  int*没有意义,本来就是   *(aa + 1)相当于aa[1]
    printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));//指针减一(前一个元素):10,5 
    return 0;
}

笔试题7:


#include<stdio.h>
int main()
{
    char* a[] = { "work","at","alibaba" };
    char** pa = a;
    pa++;
    printf("%s\n", *pa);
    return 0;
}

解析:


#include<stdio.h>
int main()
{
    char* a[] = { "work","at","alibaba" };//指针数组
    char** pa = a;
    pa++;//跳过数组里的一个元素,跳到at的地址
    printf("%s\n", *pa);//at(%s从a开始向后打印字符串)
    return 0;
}

笔试题8:


#include<stdio.h>
int main()
{
    char* c[] = { "ENTER","NEW","POINT","FIRST" };
    char** cp[] = { c + 3,c + 2,c + 1,c };
    char*** cpp = cp;
    printf("%s\n", **++cpp);
    printf("%s\n", *-- * ++cpp + 3);
    printf("%s\n", *cpp[-2] + 3);
    printf("%s\n", cpp[-1][-1] + 1);
    return 0;
}

解析:哪一步不懂可以看看放在后面的佬的图


#include<stdio.h>
int main()
{
    char* c[] = { "ENTER","NEW","POINT","FIRST" };
    char** cp[] = { c + 3,c + 2,c + 1,c };
    char*** cpp = cp;
    printf("%s\n", **++cpp);//++cpp==c+2 解引用得c+2内容,即POINT地址 再解引用得POINT
    printf("%s\n", *-- * ++cpp + 3);//++cpp在上一行基础在+1得到c+1地址
    //解引用得c+1内容 再--得到c的内容 再解引用得到ENTER的地址即E的地址 
    //再+3得到第二个E的地址  打印出ER
    printf("%s\n", *cpp[-2] + 3);//*cpp[-2]==*(*(cpp-2))
    //cpp在上面内容-2得到c+3的内容  解引用得到c+3地址 再解引用得到FIRST地址
    //再+3得到S的地址  打印出ST
    printf("%s\n", cpp[-1][-1] + 1);//cpp[-1][-1]==*(*(cpp-1)-1)
    //++cpp等价于cpp=cpp+1  cpp变了 但cpp-2 cpp没有变 还是指向c+1
    //cpp在上面内容-1得到c+2的内容  解引用得到c+2地址 再-1得到c+1的地址
    //再解引用得到NEW的地址  再+1得到E的地址  打印出EW
    return 0;
}

可以一边看文字一边画图理解:(也可以配合调试)

佬的讲解:

3笔试题二

3.1指向函数指针数组的指针

声明一个指向含有10个元素的数组的指针,其中每个元素是一个函数指针,该函数的返回值是int,

参数是int*,正确的是( )

A.(int *p[10])(int*)

B.int [10]*p(int *)

C.int (*(*p)[10])(int *)

D.int ((int *)[10])*p

解析:

A选项,第一个括号里是一个完整定义,第二个括号里是个类型,四不像。BD选项,[]只能在标识符右边,双双排除。只有C是能编过的。


3.2函数指针

定义一个函数指针,指向的函数有两个int形参并且返回一个函数指针,返回的指针指向一个有一个

int形参且返回int的函数。下面哪个是正确的?( )

A.int (*(*F)(int, int))(int)

B.int (*F)(int, int)

C.int (*(*F)(int, int))

D.*(*F)(int, int)(int)

解析:

D类型不完整先排除,然后看返回值,B的返回值是int,C的返回值是int *,故选A。判断返回值类型只需要删掉函数名/函数指针和参数列表再看就行了。int (*(*F)(int, int))(int)删掉(*F)(int, int)后剩下int (*)(int),符合题意。


3.3函数指针

设有以下函数void fun(int n,char *s){……},则下面对函数指针的定义和赋值均是正确的是:( )

A.void (*pf)(int,char); pf=&fun;

B.void (*pf)(int n,char *s); pf=fun;

C.void *pf(); *pf=fun;

D.void *pf(); pf=fun;

解析:

CD前半句压根就不是定义而是声明,A选项参数列表的第二个参数错了。应为char *,B选项正确。需要说明的是,对于函数名来说,前面的&和*都会被忽略,所以fun前面加不加取地址都没区别。只有定义出的函数指针变量(如题面中的pf)加上&后才会变成二级函数指针。


3.4指针+-


#include <stdio.h>
int main()
{
    int aa[2][5] = { 10,9,8,7,6,5,4,3,2,1 };
    int* ptr1 = (int*)(&aa + 1);
    int* ptr2 = (int*)(*(aa + 1));
    printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));
    return 0;
}

A.1, 6

B.10, 5

C.10, 1

D.1, 5

解析:

&aa的类型是int (*)[2][5],加一操作会导致跳转一个int [2][5]的长度,直接跑到刚好越界的位置。减一以后回到最后一个位置1处。*(aa + 1)相当于aa[1],也就是第二行的首地址,自然是5的位置。减一以后由于多维数组空间的连续性,会回到上一行末尾的6处。故选A。


3.5数组指针


#include <stdio.h>
int main()
{
    int a[5] = { 5, 4, 3, 2, 1 };
    int* ptr = (int*)(&a + 1);
    printf("%d,%d", *(a + 1), *(ptr - 1));
    return 0;
}

A.5, 1

B.4, 1

C.4, 2

D.5, 2

解析:

*(a + 1)等同于a[1],第一个是4,a的类型是int [5],&a的类型就是int(*)[5],是个数组指针。所以给int(*)[5]类型加一,相当于加了一个int [5]的长度。也就是这个指针直接跳过了a全部的元素,直接指在了刚好越界的位置上,然后转换成了int *后再减一,相当于从那个位置向前走了一个int,从刚好越觉得位置回到了1的地址处,所以第二个是1,故选B。


3.6函数参数设计

下面代码中print_arr函数参数设计哪个是正确的?( )


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

A.void print_arr(int arr[ ][ ],int row, int col);

B.void print_arr(int* arr, int row, int col);

C.void print_arr(int (*arr)[5], int row, int col);

D.void print_arr(int (*arr)[3], int row, int col);

解析:

二维数组相当于数组的数组,传到子函数变成数组的指针。int arr[3][5]相当于是3个元素的arr,每个元素是int [5],所以int [5]是类型说明不能省略。丢失的信息只有数组的元素个数,也就是3。A丢了类型中的5,B选项arr是首元素地址,首元素是第一行数组,指针层次错了。D选项5写成了3,


3.7函数设计

下面test函数设计正确的是:( )


char* arr[5] = {"hello", "bit"};
test(arr);

A.void test(char* arr);

B.void test(char** arr);

C.void test(char arr[5]);

D.void test(char* arr[5]);

解析:

指针的数组传递给子函数变为指针的指针,也就是二级指针。但是允许中括号写法,

写成char **arr、char *arr[]、char * arr[5]都可。所以BD正确。


3.8(编程)杨氏矩阵

杨氏矩阵

有一个数字矩阵,矩阵的每行从左到右是递增的,矩阵从上到下是递增的,

请编写程序在这样的矩阵中查找某个数字是否存在。

要求:时间复杂度小于O(N);

解题:

如杨氏矩阵:

1 2 3

4 5 6

7 8 9

再如:

1 2 3

2 3 4

3 4 5

查找某个元素——若遍历二维数组,若数组有n个元素,

则最坏情况下找n次,即时间复杂度为O(N),(时间复杂度是数据结构的内容,现在不懂可以略过)

而题目要求时间复杂度小于n。时间复杂度小于O(N)的算法:


#include<stdio.h>
int find_arr(int arr[3][3], int row, int col, int k)
{
    int x = 0, y = col - 1;//从右上角开始找
    while (x < row && y >= 0)
    {
        if (arr[x][y] > k)
        {
            y--;
        }
        else if (arr[x][y] < k)
        {
            x++;
        }
        else
        {
            printf("%d %d\n", x, y);
            return 1;
        }
    }
    return 0;
}

int main()
{
    int arr[3][3] = { 1,2,3,4,5,6,7,8,9 };
    //  1   2   3
    //  4   5   6
    //  7   8   9
    //若要找的元素是k=2,比右上角的3小,因为3是一列中最小的元素,所以去掉一列;
    //    若要找的元素是k=7,比右上角的3大,因为3是一行中最大的元素,
    //    所以去掉一行;7比在剩下的元素中右上角的6还要大,则又去掉一行;
    //    7与剩下元素中右上角的9小,则在这一行中查找7,
    //    (因为9已经是剩下元素所在列中最小的元素)去掉一列;
    //    8比7大说明还在8的左边,去掉一列;7与7相等则找到;
    //    如果7还找不到则结果就是找不到。

    int k = 0;
    scanf("%d", &k);
        //找到返回1 找不到返回0
    //传arr和行、列、要找的元素
    if (find_arr(arr, 3, 3, k))
    {
        printf("找到了\n");
        
    }
    else
    {
        printf("找不到\n");
    }
    return 0;
}

虽然封装了函数,但是找到的下标是自己打印的,这不是好的解决办法。

解决办法:用函数查找,用函数带回或返回找不到。

而且return不能直接带回两个值。

更好的代码实现:


#include<stdio.h>
int find_arr(int arr[3][3], int* row, int* col, int k)
{
    int x = 0, y = *col - 1;//从右上角开始找
    while (x < *row && y >= 0)
    {
        if (arr[x][y] > k)
        {
            y--;
        }
        else if (arr[x][y] < k)
        {
            x++;
        }
        else
        {
            *row = x;
            *col = y;
            return 1;
        }
    }
    return 0;
}
int main()
{
    int arr[3][3] = { 1,2,3,4,5,6,7,8,9 };
    int k = 0, x = 3, y = 3;
    scanf("%d", &k);
    //找到返回1 找不到返回0
    //传arr和行、列、要找的元素
    //传行和列的地址,则在函数中所求的下标就可以通过这两个地址放到x、y中
    if (find_arr(arr, &x, &y, k))
    {
        printf("找到了,下标是%d,%d\n",x,y);
        
    }
    else
    {
        printf("找不到\n");
    }
    return 0;
}
//这里传& x和& y的好处:
//既可以带进函数两个值:3和3,在函数中使用;
//又可以在函数结束的时候带回值——这种设计是返回型参数(输出型参数),
//用指针修改,把数值带回去。

3.9(编程)模拟实现qsort

自己敲出一个模拟的qsort并应用

(代码在上一篇)C语言进阶⑪(指针_上)(知识点和对应练习)回调函数模拟实现qsort。_GR C的博客-CSDN博客(有时间自己敲,不懂再看一眼)


(还有一些和字符串有关的指针作业放在下一篇了)

本篇完。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GR鲸鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值