cpp学习笔记(关于数组+字符串和字符数组)

1.cpp中的数组和java中不大一样,首先cpp中的数组不是对象,无法调用length方法,只能通过计算来得到数组的长度.

一维数组;

而且要么在定义的时候确定数组的长度.

要么在后面初始化的时候确定数组长度;

反正是不能和java一样写个空数组放在那里,,,,,,,,,

一维数组定义的时候,如果没有确定元素,就一定要确定长度
  如果确定了元素(初始化完成)但是没有给出长度,那么cpp就可以自己猜出长度来

int arrrr[] = { 12345 };
很顺滑地知道长度是1了

数组在定义的时候,使用类型+数组名+[]={}进行定义;

其中有一个处理方法

//typedef定义类型 前面也那这个定义过指针
	//这里也可以修改成
	typedef int A[10];//此时A就不再是一个变量,而是"长度为十的数组"的别名

关于多维数组(以二维数组为例)

二维数组在内存中的排列,其实还是线性的,这一点可以由指针进行验证

//多维数组仍然是线性排列的内存空间,而不是我们想象中的矩阵
	//00 01 02 03 04 10 11 12 13 14 
	//用指针可以试一下,而Java中实现的是矩阵(数组的数组)

	int vec[2][2] = { 1,2,3,4 };
	int * point2 = &vec[0][0];//(对于二维数组,不能用数组名字代替第一个元素的地址了)
for (int i = 1; i <= 4; i++) {
		cout << *point2 << endl;
		point2++;
	}

输出结果为1234,证明仍然是线性排列的

但是作为矩阵进行储存和调用的时候还是不受影响的,可以随便使用...

关于二维数组的定义和初始化问题

      对于二维数组,注意一下高低维度
      低纬度必须定义长度数值
      合理的情况是可以猜测的
      不足可以自动填充(考试时候的数组有可能缺得像狗啃的

下面代码是为了方便,其实是跑不起来的
例如这样可以自动填充上去
int[4][2]={{1,2}{3.4}{5}}
实际上的填充效果是{  {1,2}, {3,4}, {5.0}, {0,0} }

最高维度在这种情况下可以不写

int[][2]={1,2,3,4}
会自己分成{ {1,2} , {3,4} }

但是剩下的维数是必须写的,如下图所示就会报错

(错误代码)int[4][]={1243};

考试时候注意一个特殊情况

// 特殊情况----------关于cpp自动识别------------------------------------------------------------
    // 顺序读取的
    //[2][2]={1,2,{3,4}}前面读完1,2可以当成第一行
    // 下面三四自动识别为第二行
    //[2][2]={1,{3,4}}是不行的读取完一个他不知道接下来3是第几行的

2.关于数组地址和指针的问题

(1)数组的名字(无论是及维度数组都是一样的)都代表第一个元素的位置

 cout << vec << endl;
cout << &vec[0][0] << endl;
	// 由这个验证可知,无论是第及维度的数组,数组名字都是第一个元素的位置
	// 只不过int指针无法匹配int[][];

数组的第一位元素均可与对应类型的指针匹配,但是数组名字不一定

 对于一维数组
    int arr[] = { 1 };
	int * point1 = arr;//可以用数组名字代替第一个地址
对于二维数组或者高维数组
	int vec[2][2] = { 1,2,3,4 };
	int * point2 = &vec[0][0];//不能用数组名字代替第一个元素的地址

按照老师的回复,int[][] 和 int *不匹配----------------------------------------
只有int[] 和int*才是匹配的,所以一维数组可以直接用

盖棺定论:数组名字一定是第一个元素的地址,错的只是指针可能不匹配

挺烦的,所以以后数组在传参之类的操作时做一个规范

要么直接指明第一个元素建立指针,而不是只想数组名字

要么直接用数组名字开搞(传参什么的),不管指针了

3.关于数组作为参数.

     关于数组作为形参,和结构体形参不太一样好像,结构体形参分为值传递和地址传递
    // 数组不存在值传递这个问题,一般直接传入名字即可
    //而传递数组名就是在传递数组头位置的地址,
    // 也可以用指针传入第一个数字的地址,也可以不用指针直接传入名称
    // 多维数组也可以直接传入名称

   //数组地址传递作为参数有两种方式
    //int * arr
    //int   arr[]

(不过大家需要的都是地址)


    关于传入的时候,也有两种方式(而且数组只存在值传递)
    可以利用&传入第一个元素的地址/指针
     也可以传入数组名字

补充:在传递时刻可能会有的问题

(1)数组处在形参列表的时候,可以省略掉最高维的长度,但是剩下的低纬度都的不行

(例如)

void sort(int x[][][2])//不行

void sort(int x[2][][])//不行

void sort(int x[][2][2])//行

(2)在传参时可能遇到的几个问题

void bub1(int  arr[][10]) {}
void bub2(int  arr[][12]) {}
void bub3(int  arr[2][10]) {}
void bub(int  arr[5][]) ;这个本身的语法就是错误的,没有低纬度;
int m1[5][10];
	bub1(m1);第一个方法没问题,低纬度的数目是确定的,高纬度没有指定
	bub2(m1);低纬度不一样,他不认为这是同类型的数组
	bub3(m1);传入没有问题,但是高纬度会发生风险

做个总结;

传入的时候,参数和列表中的

1,低维必须对应,否则根本不认为是同一种数组

2.高维尽量对应,因为可能会有风险存在

一点小总结

/1,数组并不是对象,数组名就是第一个的地址,所以不能用length
    //2.越界几乎没啥影响
    //3.没有赋值的元素可能为0或者null
    //4.指定长度超出的时候,int{2}={1 2 3 4  4}挑衅行为不建议
    //5.关于一维数组定义的时候,如果没有确定元素,就一定要确定长度

3.关于字符数组和字符串的区别和字符数组的一些方法.

在java里面,无论是string还是stringbuffer,底层都是字符类型的数组,但在这里貌似不大一样

(1)字符数组的长度和字符串的长度是不一致的(哪怕内容一致)

string ar="123";占据空间为四个
char ar[]={1,2,3};占据空间为三个

字符串最末尾其实还有一个\0的字符,这个字符不计入长度,但是会扎据内存,代表字符串的结束.

两者可以相互转化但是


	char ar[4] = "1234";这个是有问题的,这个字符串的内存其实是五个字节
    char ar[4] = "123"这个才是正确的
	// 里面有一个\0,作为字符串截止的符号
	//而开辟的仅仅是四个字节的空间而已
	char ar[4] = { 1,2,3,4 };//而这样子写数组,长度为四
	//多出来的那个\0是作为数组结尾,不计入数组长度,但是占用数组空间
	//字符数组里面没有这个东西

(2)字符数组的一些方法

[1]strcat方法,拼接方法(拼接的时候保证前面的数组有充足的长度容纳)

char arr1[20] = { "thisaass" };
	char arr2[5] = { "FUCK" };
	//strcat_s(arr1,arr2);//组合方案

[2]我感觉比较重要,关于strcpy方法

    char arr1[20] = { "thisaass" };
	char arr2[5] = { "FUCK" };
	strcpy( arr1 , arr2 );

输出结果是fuck对吧?

这是替换对吧?

不对!哈皮!

这个底层原理如下

    //并不是直接替换,准确而说,这两个里面输入的不是字符串,而是输入十六进制的地址
    //例如strcpy(a, b)从第一个数组的a地址(一般就是首位),后面全部替换成b地址的东西
    //如果贴上去的是数组(一般都是数组)
    //那么就是从这个地址往后的全部贴上
    
    //举个例子    strcpy(arr1, arr2) ;  输出结果就是FUCK

    //再举个例子  strcpy(arr1+1, arr2+1)
    //arr1把第二个地址替换成arr2的第二个地址
    //    (t)hisissass___F(UCK)   输出结果就是    tUCK

 

另外上述两个方法前面要加上宏文件,不然没法太好地使用

#define _CRT_SECURE_NO_WARNINGS 
//还有下面这两个包导入一个
#include <cstring>
#include <string.h>

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值