知识点:
1. 指针使用的注意事项
- 不要轻易改变指针的位置
char* p = NULL;
strcpy(p,"string"); // 报错,无效(需要先动态给p开辟内存,或者定义时char p[num]这样使用才有效)
p="string"; // 可以
第一个是把string赋值给p,第二个是p指向“string”的首地址。
2. const 关键字
// 常量(创建一个指针还是可以改变的)
const int number = 100;
// 常量指针(常量指针的值是不能被修改的)
const int* numberP = &number;
// 指针常量(指针常量的地址是不能被修改的)
int* const numberP = &number2;
// 值不能修改,指针也不能修改
const int *const numberP = &number2;
3. 二级指针的内存模式
3.1 指针数组
指针数组
:数组指针指向的是数组元素的首地址
3.2 二维数组的几种定义方式
第一种定义方式:
char* name[10] = {"east","rose","jack"};// 后面的默认指向的是 NULL 地址,都是在静态常量区
char** name = {"east","rose","jack"}; // 这种定义方式有问题,直接去赋值那么 c 和 c++ 会把这哥们当做 二级指针。而不是指针数组
第二种定义的方式:
char name[10][30] = {"east","rose","jack"}; // 这个几个数据都是从静态常量区copy 到 栈的 buffer里面的
第三种定义方式(最常见的一种方式)动态开辟,不理解记住套路:
void print(char** str,int len){
int i = 0;
for(; i< len; i++){
// printf("%s\n",str[i]); // [] 也相当于挪动指针
printf("%s\n",*(str+i));
}
}
int main(){
int number = 4;
char** params = (char**)malloc(sizeof(char*)*number); // 开辟二位数组
// 开辟一维数组
for(int i =0; i<number; i++){
params[i] = malloc(sizeof(char)*100); // 不会去开辟一维数组
// 写一些数据
sprintf(params[i],"i = %d",i);
}
print(params,number);
// 释放数组
for(int i =0; i<number; i++){
if(params[i]){
free(params[i]);
params[i] = NULL;
}
}
// 然后再释放 params 二维数组 (也可以看做一维数组,只不过这个一维数组里面存放的是元素是 一级数组指针)
if(params){
free(params);
params = NULL;
}
}
4. 多级指针
void initParams(char*** params,int number){ // 三级指针就出来了,最多也就二级指针(数组指针)
// 开辟内存去赋值
char** tempParams = (char**)malloc(sizeof(char*)*number); // 开辟二位数组
// 开辟一维数组
int i =0;
for(;i<number; i++){
tempParams[i] = malloc(sizeof(char)*50); // 不会去开辟一维数组
sprintf(tempParams[i],"i = %d",i);
}
*params = tempParams;
}
int main(){
// 我想给字符串数组开辟内存,开辟内存写到另一个方法
char** params = NULL;
int number = 4;
initParams(¶ms,number);
print(params,number);
// 释放
}