【备用知识——字符串的操作】
模块讲解:数组、数组指针
void *memset(void *s, int ch, size_t n);
函数解释:将s中当前位置后面的n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s 。
memset:作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法
(1) 数组首元素的地址和数组地址是两个不同的概念(类型决定步长!)
例:int a[10];
a:代表数组首元素的地址 (a代表数组元素类型,即a[0])
&a:数组的地址(&a代表数组类型,即int [10])
(2)以一维数组为例
#include <iostream>
using namespace std;
int main()
{ //①定义数组
typedef int(MTYPE)[5];//讲解此句话的含义
MTYPE array; //等价于int array[5];
for(int i = 0; i<5; i++)
{
array[i] = i;
cout<<array[i]<<endl;
}
//定义一个指向数组类型的指针的三种方式
//②:用定义的数组类型MTYPE定义数组指针变量(方式一)
MTYPE *pArr = &array; //pArr指向数组类型(即指向&array,而不是指向数组元素)
for(int i = 0; i<5; i++)
{
cout<<(*pArr )[i]<<endl;
}
//②:定义一个数组指针类型pMTYPE,用pMTYPE定义数组指针变量(方式二)
typedef int(*pMTYPE)[5]; //类比typedef int(MTYPE)[5];//讲解此句话的含义
pMTYPE ptr = &array; //此处的 *ptr = 数组的地址,即&array。
//②:直接定义一个数组指针ptrArr(方式三)
char (*ptrArr)[5]; //ptrArr是一个指向char[5]数组的指针,它指向数组,而不是指向数组的元素,因此给它赋值时用数组的地址,而不是数组元素的地址。
ptrArr = &array; //注意:此处不是array(&array[0]数组首元素的地址),而是&array(数组的地址)
//数组指针ptrArr的使用:
首先把一个数组地址赋值给数组指针ptrArr
然后用(*ptrArr)去取出该数组的地址
最后进行使用,使用方式(*ptrArr)[i]
}
【解读】 typedef int(MTYPE)[5];的含义
(3)※【重点来了】数组名加一增加的步长是多少?(【注】多维数组和一维数组不同)
#include <iostream>
using namespace std;
int main()
{//一维数组
int c1[5] ;
cout<<(int)c1 <<endl;
cout<<(int)(c1+1)<<endl; //一维数组的数组名+1,地址增加一个元素sizeof(c1[i])的大小
//二维数组
int c2[3][5];
cout<<(int)c2 <<endl;
cout<<(int)(c2+1)<<endl; //二维数组的数组名+1,地址增加 5*sizeof(c2[i][j]) 的大小
【总结】
// 一维数组的数组名代表首元素的地址,相当于&c1[0];因此c1+1的地址增量是sizeof(int)
// 二维数组的数组名表示对应的数组指针,相当于int (*c2)[5];因此c2+1的地址增量是sizeof(int [5])
// 三维数组的数组名表示对应的数组指针,相当于int (*c2)[5][4];因此c3+1的地址增量是sizeof(int [5][4])
// 以此类推到N维数组
【综上所述】一维数组名自成一派,多维数组名实质上表示的是数组指针。
getchar();
}
常见返回值问题
char* getchar()
{
//char *p1 = "AAAA"; //常量区
//return p1; //返回成功
char p2[100] = "AAAA"; //局部变量区
return p2; //返回失败
}
==============================================
二级指针的(输出)内存模型
//在被调函数中分配内存,把结果给甩出来(甩给主调函数)
//这种模型:实参是地址或者引用
#include <iostream>
using namespace std;
//二级指针的输出模型
struct student
{
char name[100];
int age;
};
struct student* create1()
{
struct student* s = (struct student*)malloc(sizeof(struct student)); //在被调函数中分配内存
return s;
}
int create2(struct student** s)
{
if(s==NULL) //如果传进去的实参是无效的值(即传进去的实参的地址是NULL), 而不能用 if(*s==NULL)
return 0;
*s = (struct student*)malloc(sizeof(struct student));
return 1;
}
int main()
{
//形式一
struct student *stu1 = NULL;
stu1 = create1();
//形式二
struct student *stu2 = NULL;
create2(&stu2);
return 0;
}
二级指针的易犯错误模型以及相关知识
(1)char buf[100];//buf是const常量,不能被修改
(2)编译器会把p[i]转换成*(p+i)