• C博客作业05--指针


    这个作业属于哪个班级 C语言--网络2011/2012
    这个作业的地址 C博客作业05--指针
    这个作业的目标 学习指针相关内容
    姓名 李雷默

    0.展示PTA总分

    1.本章学习总结

    1.1 指针定义、指针相关运算、指针做函数参数。

    1.1.1定义:

    数据在内存中的地址也称为指针,如果一个变量存储了一份数据的指针,我们就称它为指针变量。这样的一份数据可以是数组、字符串、函数,也可以是另外的一个普通变量或指针变量。定义指针变量要在变量名前面加星号*。

    1.1.2运算:

        int    a = 10,   *pa = &a, *paa = &a;
        double b = 99.9, *pb = &b;
        char   c = '@',  *pc = &c;
        //最初的值
        printf("&a=%s, &b=%s, &c=%s
    ", &a, &b, &c);
        printf("pa=%s, pb=%s, pc=%s
    ", pa, pb, pc);
        //加法运算
        pa++; pb++; pc++;
        printf("pa=%s, pb=%s, pc=%s
    ", pa, pb, pc);
        //减法运算
        pa -= 2; pb -= 2; pc -= 2;
        printf("pa=%s, pb=%s, pc=%s
    ", pa, pb, pc);
        //比较运算
        if(pa == paa){
            printf("%d
    ", *paa);
        }else{
            printf("%d
    ", *pa);
        }
    

    指针变量保存的是地址,而地址本质上是一个整数,所以指针变量可以进行加法、减法、比较等运算。并且运算以后可以发现:pa、pb、pc 每次加 1,它们的地址分别增加 4、8、1,正好是 int、double、char 类型的长度;减 2 时,地址分别减少 8、16、2,正好是 int、double、char 类型长度的 2 倍。所以指针变量加减运算的结果跟数据类型的长度有关,而不是简单地加 1 或减 1。

    1.1.3指针做函数参数:

    用指针变量作函数参数可以将函数外部的地址传递到函数内部,使得在函数内部可以操作函数外部的数据,并且这些数据不会随着函数的结束而被销毁。像数组、字符串、动态分配的内存等都是一系列数据的集合,没有办法通过一个参数全部传入函数内部,只能传递它们的指针.有的时候,对于整数、小数、字符等基本类型数据的操作也必须要借助指针,一个典型的例子就是交换两个变量的值。

    void swap(int *p1, int *p2){
        int temp;  
        temp = *p1;
        *p1 = *p2;
        *p2 = temp;
    }
    

    1.2 字符指针:

    字符串中的所有字符在内存中是连续排列的,str 指向的是字符串的第 0 个字符;我们通常将第 0 个字符的地址称为字符串的首地址。字符串中每个字符的类型都是char,所以 str 的类型也必须是char *。

       char *str = "qimobuguake";
       int len = strlen(str), i;
      
       //直接输出字符串
       printf("%s
    ", str);
       //使用*(str+i)
       for(i=0; i<len; i++){
           printf("%c", *(str+i));
       }
       printf("
    ");
       //使用str[i]
       for(i=0; i<len; i++){
           printf("%c", str[i]);
       }
    

    上述代码运行结果均为qimobuguake,但它们在内存中的存储区域不一样,字符数组存储在全局数据区或栈区,第二种形式的字符串存储在常量区。全局数据区和栈区的字符串有读取和写入的权限,而常量区的字符串只有读取权限,没有写入权限。(因此被命名为字符串常量)

    1.3 指针做函数返回值:

    C语言允许函数的返回值是一个指针,我们将这样的函数称为指针函数。用指针作为函数返回值时,函数运行结束后会销毁在它内部定义的所有局部数据,包括局部变量、局部数组和形式参数。

    1.4 动态内存分配:

    申请内存使用的是malloc()和free(),都是标准函数,在stdlib.h中定义。申请内存有可能失败,失败时返回NULL,因此,动态申请内存时,一定要判断结果是否为空。malloc()的返回值类型是“void *”。

    1.5 指针数组及其应用:

    如果一个数组中的所有元素保存的都是指针,那么我们就称它为指针数组。

    dataType *(arrayName[length]);
    

    上述代码忠arrayName是一个数组,包含了length个元素,括号外面说明每个元素的类型为dataType *。

    1.6 二级指针:

    指针可以指向一份普通类型的数据,例如 int、double、char 等,也可以指向一份指针类型的数据,例如 int *、double *、char * 等。如果一个指针指向的是另外一个指针,我们就称它为二级指针。
    假设有一个 int 类型的变量 a,p1是指向 a 的指针变量,p2 又是指向 p1 的指针变量,它们的关系如下图所示:

    • 可以使用&获取指针的地址。
    • 每增加一级指针,在定义指针变量时就得增加一个星号*。

    1.7 行指针、列指针:

    二维数组指针是一个指针,它指向一个二维数组。
    指针数组和二维数组指针在定义时非常相似,只是括号的位置不同:

    int *(p1[5]);  //指针数组,可以去掉括号直接写作 int *p1[5];
    int (*p2)[5];  //二维数组指针,不能去掉括号
    

    2.PTA实验作业

    2.1 7-3 字符串的冒泡排序

    2.1.1 伪代码

    if (strcmp(a[i], a[i + 1]) > 0)\运用strcmp比较a[i]和a[i+1]大小,当a[i]>a[i+1]时,进行排序
    {
    	strcpy(b, a[i]);       \运用strcpy实现[i]和a[i+1]交换位置
    	strcpy(a[i], a[i + 1]);
    	strcpy(a[i + 1], b);
    }
    

    2.1.2 代码截图

    2.1.3找一份同学代码(尽量找思路和自己差距较大同学代码)比较,说明各自代码特点。

    由于本题思路比较简单,所以大家的代码都大同小异。

    2.2 6-9 合并两个有序数组(2)

    2.2.1 伪代码

            for (i = 0; i < m; i++)//新建一个数组c将a、b放进c中
    	{
    		*c = a[i];
    		c++;
    	}
    	for (i = 0; i < n; i++)
    	{
    		*c = b[i];
    		c++;
    	}
    	for (i = 1; i < m + n; i++)//通过冒泡法排序升序排序数组
    	{
    		for (j = i + 1; j < m + n; j++) {
    			if (a[i] > a[j])
    			{
    				t = a[i];
    				a[i] = a[j];
    				a[j] = t;
    			}
    

    2.2.2 代码截图

    2.2.3 找一份同学代码(尽量找思路和自己差距较大同学代码)比较,说明各自代码特点。


    我的代码用了循环嵌套,但是在运行时数据个数100000会超时,而同学的代码使用了逆向载入的方式避免了运行超时。

    2.3 7-4 说反话-加强版

    2.3.1 伪代码

    	for (i = len - 1; i >= 0; i--)\逆向输入数据
    	{
    		if (a[i] != ' ' && a[i] != '
    ')
    		{
    			tail = i;
    			for (j = i - 1; j >= 0; j--)
    			{
    				if (a[j] == ' ')
    				{
    					head = j + 1;
    					break;
    				}
    				if (j == 0)
    				{
    					head = j;
    					break;
    				}
    			}
    			i = j;
    			if (count > 0)\输出一个空格
    			{
    				printf(" ");
    			}
    			for (j = head; j <= tail; j++)\输出数据
    			{
    				printf("%c", a[j]);
    			}
    

    2.3.2 代码截图

    2.3.3 请说明和超星视频做法区别,各自优缺点。

    老师的做法比较清晰易读,但是在第一次接触时会有点难懂,必须反复读代码才能理解。我的代码需要说明的特殊情况较多,代码看上去就显得杂乱,不过也能得到结果。

  • 相关阅读:
    [C#] 多线程总结(结合进度条)
    [Winform] DataGridView 中 DataGridViewComboBox 的可编辑
    [Tool] 仿博客园插入代码的 WLW 插件
    [C#] 获取打印机列表
    [Access] C# 通过 COM 组件访问 Access 文件
    [Excel] 打印设置
    [Q&A] 应用程序清单生成失败
    [Excel] Worksheet.PasteSpecial
    canvas裁剪图片,纯前端
    javascript将base64编码的图片数据转换为file并提交
  • 原文地址:https://www.cnblogs.com/llmnb/p/14192123.html
Copyright © 2020-2023  润新知