c提高第四次作业

1. 简述指针数组和数组指针的区别?
答:
指针数组:是一个数组,每个元素都是指针
数组指针:是一个指针,指向数组的指针

2. 如何定义一个指向 int a[10] 类型的指针变量(数组指针)(使用3种方法)?
答:
1、根据数组类型,定义指针变量,数组指针变量
typedef int ARRARY[10]; //定义了一个名字为ARRARY的数组类型
//等价于typedef int (ARRARY)[10];

ARRARY *p; //数组指针变量

//编译会有警告,但不会出错,因为 a 和 &a的值一样
//就算p = a这样赋值,编译器内部也会自动转换为 p = &a
//不建议这么做
p = a;

//p 指向a数组,指向一维数组的指针
p = &a;

//如何操作数组指针变量 p
int i = 0;
for (i = 0; i < 10; i++)
{
(*p)[i] = i + 1;
//p = &a
//*p -> *(&a) -> a
//(*p)[i] -> a[i]
}

2、直接定义数组指针变量(常用)
//()[]同级,从左往右看
//()有*,它是一个指针,[]代表数组
//指向数组的指针变量,[]中的数字代表指针+1的步长
int(*p)[10];

//p 指向a数组,指向一维数组的指针
p = &a;


3、先定义数组指针类型,再根据类型定义指针变量(常用)
//数组指针类型,加上typedef
typedef int(*Q)[10];
Q p; //根据类型定义变量,p是数组指针变量
p = &a; //p指向数组a


3.
int a[10];
int b[5][10];
int (*p)[10];
p = &a; //为何加 &
p = b; //为何不用加 &
答: a是一维的,必须加& 才表示整一行的首地址
b是二维的,本来就代表整行的首地址

4. int a[3][5] = { 0 };
//a -> a + 0
//a + i
//*(a+i) -> a[i]
//*(a+i)+j -> &a[i][j]
//*(*(a+i)+j ) -> a[i][j]

5. 如何在栈上开辟一个二维数组,如何在堆上开辟一个二维数组?

6. int main(int argc, char *argv[]);
argc, argv分别代表什么?
答:
argc: 传参数的个数(包含可执行程序)
argv:指针数组,指向输入的参数

7. 找到数组中指定字符串的位置
#define NUM(a) (sizeof(a)/sizeof(*a))

char* keywords[] = {
"while",
"case",
"static",
"do"
};

int searcheKeyTable(const char* table[], const int size,
const char* key, int *pos);
答:

#pragma warning(disable:4996)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define NUM(a) (sizeof(a)/sizeof(*a))
/*
功能:找到数组中指定字符串的位置
参数:
table:字符串数组(指针数组)首地址
size:数组元素个数
key:匹配字符串,如:“do”
pos:酦醅字符串在数组中的位置,如”do“在keywords中的的位置为4
返回值:
成功:0
失败:非0
*/
int searcheKeyTable(const char* table[], const int size,
const char* key, int *pos) {
if (table == NULL || key == NULL || pos == NULL) {
return -1;
}

int i = 0;
int n = -1;//保留的是位置

for (i = 0; i < size; i++) {
if (strcmp(table[i], key) == 0) {
n = i;
break;
}
}
if (n == -1) {//没有匹配字符串

return -2;
}
*pos = n + 1;

return 0;
}
int main(void) {
const char* keywords[] = {
"while",
"case",
"static",
"do"
};

int pos = 0;
int ret = 0;

ret = searcheKeyTable(keywords, NUM(keywords), "do", &pos);
if (ret != 0) {
printf("searcheKeyTable err:%d\n", ret);
system("pause");
return ret;
}
printf("%s 在keywords位置为: %d\n", "do", pos);

printf("\n");
system("pause");
return 0;
}    
View Code

 

8. 将字符串数组进行排序

int sort(char **array1, int num1,
char (*array2)[30], int num2,
char ***myp3 /*out*/, int *num3);

int main()
{
int ret = 0;
char *p1[] = {"aa", "ccccccc", "bbbbbb"};
char buf2[10][30] = {"111111", "3333333", "222222"};
char **p3 = NULL;
int len1, len2, len3, i = 0;

len1 = sizeof(p1)/sizeof(*p1);
len2 = 3;

ret = sort(p1, len1, buf2, len2, &p3, &len3);

return 0;
}

答:

#pragma warning(disable:4996)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

/*
    功能:1、将字符串数组进行排序
    2、把二维数组buf2的字符取出来,
    3、上面的字符串放在p3,p3是在堆区分配的二维内存
    4、对p3中字符串进行排序,通过strcmp()进行排序
    参数:
    p1:指针数组首地址,char *p1[]={"aa","cccccc","bbbbbb"};
    len1:p1元素个数
    buf2:二维数组首元素地址,char buf2[][30] = {"111111","333333","222222"};
    len2:buf2字符串的行数
    p3:二级指针地址,需要在函数内分配二维内存,保存p1和buf2的自渡船,还需要排序
    len3:保存p3中字符串个数
    返回值:
    成功:0
    失败:非0
*/
int sort(char **array1, int num1,
    char(*array2)[30], int num2,
    char ***myp3 /*out*/, int *num3) {
    if (array1 == NULL || array2 == NULL ||
        myp3 == NULL || num3 == NULL) {

        return -1;
    }
    //打造一个指针数组 char *tmp[num1 + num2]
    char **tmp = (char**)malloc(sizeof(char *)*(num1 + num2));
    if (tmp == NULL) {
        return -2;
    }
    
    int i = 0;
    int j = 0;

    //char *array1[]={"aa","cccccc","bbbbbb"};
    //给每个指针分配内存(指向堆区)
    for (i = 0; i < num1; i++) {
        tmp[i] = (char *)malloc(sizeof(char) * strlen(array1[i])+1);
        strcpy(tmp[i], array1[i]);
    }

    //i的初始条件从num1开始,重要
    //char buf2[][30] = {"111111","333333","222222"}
    for (i = num1, j = 0; i < num1 + num2; i++, j++) {

        tmp[i]= (char *)malloc(sizeof(char) * strlen(array2[j]) + 1);
        strcpy(tmp[i], array2[j]);
    }
    

    //排序
    int n = num1 + num2;
    char *p = NULL;
    for (i = 0; i < n - 1; i++) {
        for (j = i + 1; j < n; j++) {
            if(strcmp(tmp[i],tmp[j])>0){//升序
                p = tmp[i];
                tmp[i] = tmp[j];
                tmp[j] = p;

            }
        }
    }

    //间接赋值是指针存在最大意义
    *myp3 = tmp;
    *num3 = num1 + num2;
    return 0;
}
void free_buf(char ***p3, int n) {
    if (p3 == NULL) {
        return;
    }
    char **tmp = *p3;
    int i = 0;
    for (i = 0; i < n; i++) {
        if (tmp[i] != NULL) {
            free(tmp[i]);
            tmp[i] = NULL;
        }
    }
    if (tmp != NULL) {
        free(tmp);
        *p3 = NULL;
    }
}
int  main()
{
    int ret = 0;
    char *p1[] = { "aa", "ccccccc", "bbbbbb" };
    char buf2[10][30] = { "111111", "3333333", "222222" };
    char **p3 = NULL;
    int len1, len2, len3, i = 0;

    len1 = sizeof(p1) / sizeof(*p1);
    len2 = 3;
    printf("排序前\n");

    for (i = 0; i < len1; i++) {
        printf("%s, ", p1[i]);
    }
    printf("\n");
    for (i = 0; i < len2; i++) {
        printf("%s, ", buf2[i]);
    }
    printf("\n");

    ret = sort(p1, len1, buf2, len2, &p3, &len3);
    if (ret != 0) {
        printf("sort err:%d\n", ret);
        system("pause");
        return ret;
    }

    printf("排序后\n");
    for (i = 0; i < len3; i++) {
        printf("%s, ", p3[i]);
    }
    printf("\n");

    //释放p3所指向内存
    //在函数内部把p3的值赋值为NULL
    free_buf(&p3,len3);

    printf("\n");
    system("pause");
    return 0;
}
View Code

 

posted @ 2018-08-10 16:03  砍柴人Ryan  阅读(211)  评论(0编辑  收藏  举报