指针数组

数组

倖福魔咒の 提交于 2019-11-29 15:55:25
一维数组 一维数组初始化 在创建数组时,我们必须定义数组的类型和大小,数组的大小不能为0,数组中的元素类型都是相同的。 数组长度必须是固定的,必须为常量或常量表达式,不能使用变量进行初始化。 一维数组初始化 完整初始化: int arr[3] = {1, 2, 3}; 不完整初始化: int arr[3] = {1, 2}; 自动计算数组长度初始化: int arr[] = {1, 2, 3}; 注意: 静态初始化缺省情况将数组元素自动设置为0,自动初始化缺省情况下是未初始化的。 数组初始化元素的个数不允许超过数组长度: int a[3] = {1,2,3,4}; // 不合法 字符数组的初始化 最笨拙的方式: char message[] = { 'h','e','l','l','o',0 }; 快速初始化方式: char message[] = "hello"; 这种初始化方式与上面的初始化方式是等效的,并且默认会在末尾 '\0' 。 上面都是字符数组初始化的基本方式,如果要初始化字符串常量,则采用: char *message = "hello"; 。 初始化字符数组和字符串常量的区别,可以表示如下: 作符返回一个指向数组的指针,而不是一个指向数组第一个元素的指针的指针。 注意: 数组名的值是一个指针常量,不能修改它的值。 int a[5]; int b[5]; a = b;

指针

*爱你&永不变心* 提交于 2019-11-29 15:51:20
内存和地址 内存其实就是一组有序字节组成的数组,数组中,每个字节大小固定,都是 8bit。对这些连续的字节从 0 开始进行编号,每个字节都有唯一的一个编号,这个编号就是内存地址。示意如下图: 指针变量保存的就是这些编号,也即内存地址。 地址与内容 我们只要知道内存地址,就可以访问这个地址的值,但是这种方法实在笨拙,于是便用变量名来代替地址: 名字与内存之间的关联仅仅只是编译器实现的,采用变量名的方式能够方便的记住地址,但是硬件仍然通过地址访问内存位置。 值和类型 考虑下面的32位值: ‭01100111011011000110111101100010‬ 对于这些位的解释可以分为很多种: 类型 值 1个32位数 1735159650 2个16位数 26476和28514 4个字符 glob 浮点数 1.116533e24 机器指令 beg.+110和ble.+102 可见: 不能简单地通过检查一个值的位来判断值的类型,而应该根据它的使用方式来判断 。 使用指针的优势 在C语言中,指针的使用非常广泛,因为使用指针往往可以生成更高效、更紧凑的代码。总的来说,使用指针有如下好处: 指针的使用使得不同区域的代码可以轻易的共享内存数据,这样可以使程序更为快速高效。 C语言中一些复杂的数据结构往往需要使用指针来构建,如链表、二叉树等。 C语言是传值调用,而有些操作传值调用是无法完成的

二叉树算法题

断了今生、忘了曾经 提交于 2019-11-29 15:20:30
二叉树层次遍历 //思路 特殊情况 ,根节点为null,深度为0,return 0 借助队列,队列储存每一层的所有节点, 先保存数组长度,用于控制依次遍历循环——遍历每一个节点保存值,该节点的所有子结点从队尾入队,访问过的节点从头出队 注意——需要先把width存下来,用于for循环的结束标志,因为for循环里面直接操作了queue,不能去都不敢动态获取 队列初始值为root,对每一层都要进行上述遍历——while循环控制,队列空代表叶节点这一层遍历完成,此时遍历结束,退出循环 每次循环开始前初始化一个curNodes储存该层所有节点,每次循环结束,将curNodes压入result var levelOrder = function(root) { if (root === null) return []; //空树 var result = [], queue = [root]; while (queue.length) { let width = queue.length; //需要先把width存下来,用于for循环,for循环里面直接操作了数组 let curNodes = []; for (let i = 0; i < width; i++) { let node = queue.shift(); curNodes.push(node.val); node.left ?

数组和指针--C++复习(3)

左心房为你撑大大i 提交于 2019-11-29 14:36:23
一、数组 1.数组的长度是固定的,而指针可以像迭代器来遍历数组; 2.数组不仅可以用来保存基本类型,还可以用来保存 类类型 : 1 class Per{ 2 **** 3 }; 4 5 const int size =2; 6 Per pers[size]; 7 Per p1; 8 Per p2; 9 pers[0]=p1; 10 pers[1]=p2;//那么就可以通过数组来获取类对象的不同内容 3.如果元素为类类型,调用默认构造函数进行初始化,如果没有默认构造函数,应显式调用其他构造函数。 4.数组不能直接复制或赋值。 二、指针 1.指向另外一种变量地址的变量,使用指针可以间接操作指向的变量对象; 2.通过指针来操作数组: 1 int arr[3]={1,2,3}; 2 int *ap=arr;//把首地址赋给ap 3 int *ap1=ap+1;//指针加1相当于把指针向后移1位,加n移n位 3.指向空:int *p=0;或者int *p=NULL; 4.void *指针,可以保存任何类型对象的地址,一般用于函数的返回值或者是形参。 5.指针和应用的区别:引用总是指向某个对象,而且定义引用时必须初始化,而指针可以不用初始化;给引用赋值修改的是该引用所关联的对象的值。 6.指针和const: (1)指向const对象的指针,如: 1 const float pi=3.14; 2

leetcode刷题记录---19.9.13

北战南征 提交于 2019-11-29 13:24:44
概述 1.数组中的第k个最大元素,利用快排的partition思想,加上二分检索 2.比特位计数,直观的方法时间复杂度为o(n*sizeof(int)),有效降低时间复杂度的方法是判断当前数字的奇偶性,再与前一个联系,得出结论。 3.最长上升子序列,动态规划o(n^2),贪心+二分o(nlogn)。维护一个数组,新进来的如果比数组最后的大,插在后面,否则找到第一个比新进来的大的元素,替换掉他。这个查找是属于有序数组中的查找,可以采用折半查找。 4.根据身高重建队列,这题先根据身高和人数排序(用到了sort的复杂排序,自定义排序规则)。然后再根据人数往数组中的合适位置插。 5.寻找重复数,o(logn)使用二分查找,判断左右数字出现的个数。 6.环形链表,查找链表的环的入口。两种方法unordered_set和快慢指针。快慢指针主要是推导公式,证明,为什么A = (n-1)(B+C)+C 1. 数组中第k个最大元素 ,一遍过,莫名其妙 题目描述:给定一个无序数组,找出这个数组中第k大的数字。 思路:快排的Partition函数 示例 1: 输入: [3,2,1,5,6,4] 和 k = 2 输出: 5 示例 2: 输入: [3,2,3,1,2,4,5,5,6] 和 k = 4 输出: 4 class Solution { public: void swap(int& a,int& b

指针数组和数组指针

帅比萌擦擦* 提交于 2019-11-29 12:36:48
指针数组和数组指针 指针数组:数组的每一个元素都是指针,故所占内存的小和机子位数有关。 数组指针:数组的指针,即指向一个数组的指针就是数组指针,对应的是二维数组。 具体就不细说了,主要是分得清,不要弄混了,直接看下面的例子 例子 #include<iostream> using namespace std; int main() { //定义数组 int arr1[3]; int arr2[3][10]; //数组指针 int *p1 = arr1; int(*p2)[10] = arr2; //首地址 cout << arr1 << " " << p1 << " " << &arr1[0] << " " << &p1[0] << endl; //第二行的首地址 cout << arr1 + 1 << " " << p1 + 1 << " " << &arr1[1] << " " << &p1[1] << endl; //首地址 cout << arr2 << " " << p2 << " " << p2[0] << " " << &p2[0][0] << endl; //第二行的首地址 cout << arr2 + 1 << " " << p2 + 1 << " " << p2[1] << " " << &p2[1][0] << endl; //arr2[1][1]的地址

指针详解

戏子无情 提交于 2019-11-29 09:57:45
前言:复杂类型说明 要了解指针,多多少少会出现一些比较复杂的类型,所以我先介绍一下如何完全理解一个复杂类型,要理解复杂类型其实很简单,一个类型里会出现很多运算符,他们也像普通的表达式一样,有优先级,其优先级和运算优先级一样,所以我总结了一下其原则:从变量名处起,根据运算符优先级结合,一步一步分析.下面让我们先从简单的类型开始慢慢分析吧: int p; //这是一个普通的整型变量 int *p; //首先从P 处开始,先与*结合,所以说明P 是一个指针,然后再与int 结合,说明指针所指向的内容的类型为int 型.所以P是一个返回整型数据的指针 int p[3]; //首先从P 处开始,先与[]结合,说明P 是一个数组,然后与int 结合,说明数组里的元素是整型的,所以P 是一个由整型数据组成的数组 int *p[3]; //首先从P 处开始,先与[]结合,因为其优先级比*高,所以P 是一个数组,然后再与*结合,说明数组里的元素是指针类型,然后再与int 结合,说明指针所指向的内容的类型是整型的,所以P 是一个由返回整型数据的指针所组成的数组 int (*p)[3]; //首先从P 处开始,先与*结合,说明P 是一个指针然后再与[]结合(与"()"这步可以忽略,只是为了改变优先级),说明指针所指向的内容是一个数组,然后再与int 结合,说明数组里的元素是整型的.所以P

C语言指针(一)

若如初见. 提交于 2019-11-29 08:25:19
指针与地址 一元运算符&可用于取一个对象的地址,地址运算符&只能应用于内存中的对象,即变量与数组元素。不能作用于表达式、常量或者register类型的变量。 p = &c; 一元运算符* 是 间接寻址 或 间接引用运算符 。当它作用于指针时,将访问指针所指向的对象,下面代码段说明了程序中如何使用&和*: int x = 1, y = 2, z[10]; int *ip; /* ip is a pointer to int */ ip = &x; /* ip now points to x */ y = *ip; /* y is now 1 */ *ip = 0; /* x is now 0 */ ip = &z[0]; /* ip now points to z[0] */ int * ip ,该声明表明表达式*ip的结果是int类型。 指针只能指向某种特定类型的对象(一个类外是指向void类型指针可以存放指向任何指针,但他不能间接引用自身) 一元运算符*和&的优先级比算术运算符的优先级高。但是下面表达式中圆括号是必须的,否则,该表达式将对ip进行加1运算,这是因为,类似于 *和++这样的一元运算符遵循从右至左的结合顺序。 (*ip)++ 指针也是变量,所以程序中可以直接使用,不用通过间接引用的方法使用。若iq是另一个指向整型的指针,那么下式表示将ip的中的值拷贝到iq中

一个比sort更快的排序

风格不统一 提交于 2019-11-29 06:41:38
一个比sort更快的排序,一百万个数只需要27ms 非常消耗内存 非常消耗内存 #include < stdio . h > #include < stdlib . h > void SuperSort ( int a [ ] , int l ) { //a是数组头指针,l是数据最大值 int i , j , k ; char * p = ( char * ) calloc ( l , 1 ) ; for ( i = 0 ; a [ i ] != 0 ; i ++ ) { p [ a [ i ] ] ++ ; } for ( k = 0 , j = 0 ; j < i ; ) { if ( p [ k ] == 0 ) { k ++ ; } else { p [ k ] -- ; a [ j ++ ] = k ; } } } int a [ 20 ] ; //举个例子,比如排序20个数(一定要是全局变量哦) int main ( ) { for ( int i = 0 ; i < 20 ; i ++ ) { a [ i ] = rand ( ) % 500000 + 1 ; //记住数值不能为0,也就是本算法不能排序0的数 } SuperSort ( a , 500000 ) ; //数组的最大值不超过50万,所以第二个参数就填50万 //然后a数组就排序完成了 for ( int

typedef用法和陷阱

一个人想着一个人 提交于 2019-11-29 03:37:25
一、typedef的用法 1.用typedef来声明新的类型名,来代替已有的类型名,也就是给类型起别名。比如 1 typedef float REAL; //用REAL来代表float类型 2 REAL a; //定义一个REAL类型的变量,等价于float a,即定义一个float类型的变量a 这种用法经常用来作为定义与平台无关的类型,方便代码的跨平台移植。 例如,定义REAL类型为目标平台精度最高的类型。 1>在支持long double的平台上定义为: typedef long double REAL; 注:long double为C99增加的类型,ANSI C标准规定了double变量存储为 IEEE 64 位(8 个字节)浮点数值,但并未规定long double的确切精度,但规定long double的精度不少于double的精度。所以对于不同平台long double可能有不同的实现,有的是8字节,有的是10字节,有的是12字节或16字节。关于具体的编译器的情况, 可以通过 sizeof(long double)得知。 2>在不支持long double的平台上改为 typedef double REAL; 3>在double不支持的平台上改为 typedef float REAL; 因此, 当跨平台时,只要改下 typedef 本身就行,不用对其他源码做任何修改。