二级指针:

二维数组?---》数组的数组
二级指针?---》指针的指针

概念:二级指针存储的是一级指针的地址
(定义意味着有空间
  有空间就会有地址)
  
  格式:
       定义一级指针的格式:
       存储类型  数据类型 * 指针变量名;
       
       定义二级指针的格式:
       存储类型  数据类型 **指针变量名;
       分析:
            存储类型:二级指针自身的存储类型
            数据类型**:二级指针的数据类型
            数据类型*:二级指针所指向的类型
            指针变量名:见名知义
            
--------------------------------------------------------
总结:
(1)什么时候需要定义一个二级指针出来?----》当需要该一级指针的值时
(2)如何确定指针的类型?
-----》去掉[变量名] ,剩余的就是该指针自身的类型
     eg:
         int *p; int *
         int **pp; int **
(3)如何确定指针所指向的类型?
----》去掉[* 指针变量名] ,剩余的就是该指针所指向的类型
(4)如何分析一个指针一次性访问空间的大小?
----》依赖于所指向的类型
    char **pp; pp一次性访问空间的大小为4个
    char *p; p一次性访问的空间为1个
    int ****pppp;pppp一次性可以访问空间为4个

#include <stdio.h>int main(int argc, const char *argv[])
{int a = 90;int b = 78;int *p = &a;printf("*p = %d\n",*p);//*p = 56;//p = &b;int **pp = &p;*pp = &b;printf("*p = %d\n",*p);return 0;
}

-----------------------------------------------------------------------------------------------------

指针和数组的结合:
指针和一维数组的关系:

指针的算术运算:(+ - * / % ++ --)

假设以p和q为例(注意:p和q是同类型的指针变量)
p + N:代表p向地址增大方向移动N个数据类型的大小(p + sizeof(数据类型) * N)
p - N:代表p向地址减小方向移动N个数据类型的大小(p - sizeof(数据类型) * N)
p++:代表p向地址增大方向移动1个数据类型的大小(p + sizeof(数据类型) * 1)
p--:代表p向地址减小方向移动1个数据类型的大小(p - sizeof(数据类型) * 1)
p-q:代表两个指针之间相隔元素的个数( p - q / sizeof(数据类型))

#include <stdio.h>int main(int argc, const char *argv[])
{//定义三个指针变量int *p;short *q;char *s;int *r = p+4;printf("r-p = %d\n",r-p);/*p++;printf("p = %p\n",p);printf("p = %p\t p + 1 = %p\n",p,p+3);printf("q = %p\t s + 1 = %p\n",q,q+1);printf("s = %p\t s + 1 = %p\n",s,s+1);*/return 0;
}

p++和p+1的区别:
p++《===》 p = p+1;因此,p++会引起指针指向的改变
p+1不会引起指针指向的改变

数组名:
(1)作为数组名,可以代表整个数组
(2)也可以代表数组的首地址

打印输出数组元素的方式:
arr[i]  <===> *(arr+i)  <===> *(p+i) <===> *(p++)  <===> p[i] <===> i[arr]  <===> i[p]

​
#include <stdio.h>int main(int argc, const char *argv[])
{int arr[5] = {1,2,3,4,5};printf("sizeof(arr) = %d\n",sizeof(arr));//定义一个指针,指向该一维数组的首元素int *p = arr;//printf("arr = %p\n",arr);//printf("&arr[0] = %p\n",&arr[0]);int i;for(i=0;i<5;i++){//printf("%d ",arr[i]);//printf("%d ",*(arr+i));//printf("%d ",*(p+i));//printf("%d ",*(p++));//printf("%d ",p[i]);//printf("%d ",i[arr]);printf("%d ",i[p]);}printf("\n");return 0;
}​

分析:可以使用p[i]这种方式来遍历数组的原因是:编译器会自动将p[i]编译成*(p+i)

总结:
对于数组名:arr[i] 
对于指针:*(p+i) / *(p++)

练习: 
(1)从键盘获得一个字符串,利用指针实现求该字符串中空格的个数

​
#include <stdio.h>#define N 20
int main(int argc, const char *argv[])
{//定义一个字符数组char str[N] = {'\0'};//定义一个字符指针指向该数组的首元素char *p = str;printf("请输入一个字符串:\n");gets(p);int count = 0;//遍历该字符串while(*p != '\0'){if(' ' == *p){count++;}p++;}printf("count = %d\n",count);return 0;
}​

(2)利用指针实现冒泡(改变指针指向/ 不改变指针指向)

#include <stdio.h>#define N 5int main(int argc, const char *argv[]){//利用指针实现排序int arr[N] = {0};//定义一个整形指针变量指向该数组首元素int *p = arr;printf("请输入:\n");int i,j;for(i=0;i<N;i++){//scanf("%d",&arr[i]);scanf("%d",p+i);}printf("排序之前为: \n");for(i=0;i<N;i++){//printf("% ",arr[i]);printf("%d ",*(p+i));}printf("\n");for(i=0;i<N-1;i++){p = arr;//让p重新指向首元素for(j=0;j<N-1-i;j++){if(*p > *(p+1)){int temp;temp = *p;*p = *(p+1);*(p+1) = temp;}p++;}}printf("排序之后为: \n");p = arr;for(i=0;i<N;i++){//printf("% ",arr[i]);printf("%d ",*(p+i));}printf("\n");return 0;}

冒泡排序:从左至右,两两依次进行比较

注意:冒泡按照数据找位置

选择排序

假设有N个数:
         第一趟:找出最大的数,将该数与位置为0的数字进行交换
         第二趟:从总个数减1的人数中,再找出最大的数字与位置为1的数字进行交换。。
         。。。。。。。。。。。。

注意:选择按照位置找数据

#include <stdio.h>#define M 5
int main(int argc, const char *argv[])
{int arr[M] = {0};int i;for(i=0;i<M;i++){scanf("%d",&arr[i]);}int j;//int index;//选择排序for(i=0;i<M-1;i++){//index = i;for(j=i+1;j<M;j++){/*if(arr[index] > arr[j]){index = j;}*/if(arr[i] > arr[j]){int temp;temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}/*//交换int temp;temp = arr[i];arr[i] = arr[index];arr[index] = temp;*/}printf("排序之后为:\n");for(i=0;i<M;i++){printf("%d ",arr[i]);}putchar('\n');return 0;
}

作业:
1,指针实现,定义一个字符串,实现字符串的倒置  "break" ---> "kaerb"

#include<stdio.h>
#include<string.h>#define M 5
int main(int argc, const char *argv[])
{//指针实现,字符串的倒置char arr[M] = {'\0'};printf("请输入字符串:\n");//定义指针char *p = arr;    //  p = &arr[0]gets(p);//使用strlen来测出arr数组的有效字节int l;l = strlen(arr);//p(首地址) + l -1 就是末地址p = p + l - 1;int i;for(i = 0;i < M;i++){printf("%c",*(p-i));}putchar('\n');return 0;
}

2,利用指针实现strcat功能

#include<stdio.h>
#include<string.h>#define M 15
#define N 20
char *mystrcat(char *p,char*q,int n)
{if(NULL == p || NULL == q){printf("NULL_ERROR!\n");return NULL;}while(*p){p++;}//n代表连接arr2的n位while(n--){*p++ = *q++;}*p = '\0';return q;
}
int main(int argc, const char *argv[])
{//使用指针实现strcat的前n位char arr1[M] = {'\0'};char arr2[N] = {'\0'};printf("请输入两个字符串:\n");//gets输入字符串gets(arr1);gets(arr2);/*定义指针,指向数组的首地址char *p= &arr1[d];char *q= &arr2[0];*///定义数组arr1和arr2的有效字符长度int l1,l2;l1 = strlen(arr1);l2 = strlen(arr2);if(   M < l1 + l2 + 1){printf("error!!!\n");return -1;}/*while(*p){p++;}*//*遍历arr2while(*q){*p++ = *q++; }*/char *s;s = mystrcat(arr1,arr2,2);printf("连接之后:%s\n",arr1);return 0;
}

C补习--------->第六天,二级指针、指针和数组的关系、选择排序相关推荐

  1. 指针增量和数组的关系,指针偏移的补充,(重要面试),gdp调试,将数组中的n个元素逆序存放

    1.指针增量和数组的关系 //加1  代表了地址偏移了一个类型的字节数(整形数偏移四个字节,char形数偏移了一个字节) 再来下标法: 2.指针偏移的补充 也可以换一种写法(第12行) 但是呢同样的代 ...

  2. 二维数组的冒泡/选择排序(两种实现方法)

    一.思路 1.降维排序 一种思路是先将二维数组转化为一维数组,再利用一维数组的排序算法进行排序,最后转换回二维数组. 2.指针运算 另一种思路是直接对二维数组进行排序,利用二维数组在内存中是顺序排放的 ...

  3. 【数组】—冒泡排序选择排序---【巷子】

    /* 什么是冒泡排序:从头到尾比较相邻的两个数的大小,如果符合条件则进行比较 [注]:从小到大进行排序 假设有一个数组 var arr = [9,8,7,6,5,4]; 我们想要进行这个数组进行排序那 ...

  4. 数组array、数组方法,二维数组,冒泡/选择排序

    目录 数组 array 数组的特点 数组的遍历 (循环) forEach()遍历(只能用于数组) map() some() every() 数组方法 去掉vuejs里面数组里的{__ob__: Obs ...

  5. 【C语言指针】 指针+-整数、指针-指针、解引用、指针数组、二级指针、结构体声明、初始化、传参

    目录 一.指针 1.指针是什么 1.1.一个单元1个字节 2.指针和指针类型 2.1.指针类型的意义 ① 解引用 ② + -整数 例:把每个整形里放1 每个字节里放1 总结: 3.野指针 3.1.野指 ...

  6. c/c++ 函数、常量、指针和数组的关系梳理

    压力才有动力,15年中旬就要准备实习,学习复习学习复习学习复习学习复习--无限循环中,好记性不如烂笔头--从数组开始,为主干. c 的array由一系列的类型相同的元素构成,数组声明包括数组元素个数和 ...

  7. 【C 语言】二级指针作为输入 ( 自定义二级指针内存 | 二级指针排序 | 通过 交换指针指向的内存数据 方式进行排序 )

    文章目录 一.二维指针 排序 ( 通过 交换指针指向的内存数据 方式进行排序 ) 二.完整代码示例 一.二维指针 排序 ( 通过 交换指针指向的内存数据 方式进行排序 ) 在上一篇博客 [C 语言]二 ...

  8. c语言 数组指针,C语言数组名及指向数组指针的小结

    相信不少的C语言初学者都知道,数组名相当于指针,指向数组的首地址,而函数名相当于函数指针,指向函数的入口地址. 现在有这样一个问题,如果对数组名取地址,那得到的会是什么呢?很多人立刻会想到:给指针取地 ...

  9. 【C基础】指针/指针运算/二级指针/函数指针

    指针定义: 指针是一种数据类型,使用它可以用来定义指针变量,指针变量中存储的其实是整数,这种整数代表了内存的编号. 指针的使用: 1.函数之间相独立,但有些时候需要共享变量.传参是值传递全局变量容易命 ...

最新文章

  1. Java黑皮书课后题第4章:4.19(商业:检测ISBN-10)改写编程练习题3.9,将ISBN号作为一个字符串输入
  2. mysql 不同分区 同时insert_Mysql分区表的原理和优缺点
  3. Linux C编程学习--main()函数简析
  4. 源码分析Android Handler是如何实现线程间通信的
  5. 内卷、996的背后,AI技术该如何服务企业“人、财、物”?
  6. 串口输出换行_stm32初学者必会操作----usart串口调试工具
  7. c语言如何输出一维数组字母,C语言一维数组初步学习笔记
  8. 5G + 云网融合,加速万物互联
  9. 小程序tabBar设置
  10. docker的安装教程以及常用命令(一)
  11. 大学毕业生推荐表的计算机水平,大学毕业生就业推荐表学校鉴定评语
  12. GT-P3110如何root
  13. 频点、带宽、FFT点数、采样率的关系
  14. Error opening data file Tesseract-OCR\tessdata/eng.traineddata问题 解决
  15. foxit 福昕阅读器 点击书签跳转时,保持 页面 缩放比例
  16. 32位汇编语言学习笔记(43)-- 生成随机数
  17. Failed to execute goal org.codehaus.mojo:exec-maven-plugin:3.0.0:exec (defau-cli) on project
  18. linux下 redis如何清空缓存
  19. Unity如何限制3D物体的旋转角度
  20. CI框架的使用-原生SQL和ORM模式操作数据库、视图

热门文章

  1. [ Oracle EBS ] 资产 摊销调整、累计折旧等介绍
  2. 婚礼纪 java面试
  3. 芒果不能用百度了,怎么办?
  4. 有哪些好用的微信群管理工具?
  5. HTML怎么跟随页面缩放,如何让网页跟着 浏览器全比例缩小(示例代码)
  6. 叮当健康明日港股上市:拟募资3.4亿港元 单季期内亏损4亿
  7. 查询一段时间内的具体时间
  8. 使用Vue实现todos(Vue CLI和VueX)
  9. 职场健康:大脑20个已知秘密[转]
  10. 【Scratch】青少年蓝桥杯_每日一题_6.25_加密