上次分享了指针的基本操作,这次分享一下学习指针的意义---间接赋值是指针存在的最大意义。
指针间接赋值需要三个条件:
1、2个变量(通常一个实参,一个形参)
2、建立关系,实参取地址给形参指针
3、形参去间接修改实参的值
这边给个例子说明一下
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int getMem3(char **myp1, int *mylen1, char **myp2, int *mylen2)
{
int ret = 0;
char *tmp1 = NULL;
char *tmp2 = NULL;
tmp1 = (char *)malloc(100);
strcpy(tmp1, "111112222");
*mylen1 = strlen(tmp1);
*myp1 = tmp1;
tmp2 = (char *)malloc(200);
strcpy(tmp2, "aaaaabbbb");
*mylen2 = strlen(tmp2);
*myp2 = tmp2;
return ret;
}
int main(int argc, char *argv[])
{
char *p1 = NULL;
int len1 = 0;
char *p2 = NULL;
int len2 = 0;
getMem3(&p1, &len1, &p2, &len2);
printf("p1:%s,len1:%d\n", p1, len1);
printf("p2:%s,len2:%d\n", p2, len2);
if (p1)
{
free(p1);
p1 = NULL;
}
if (p2)
{
free(p2);
p2 = NULL;
}
system("pause");
return 0;
}
我们可以看到getMem3()函数的作用为通过形参返回拷贝的内存地址及大小,这边是通过一个二级指针来返回拷贝字符串的地址,这即是指针最大的作用,如果不通过指针的话我们就需要返回一个结构体来接收这些,且拷贝赋值会浪费空间。
接下来说明一下字符串在C语言中如何进行表示的。
首先说明一下字符的基本规则
1.C语言的字符串,以零结尾的字符串
2.在C语言中没有字符串类型 通过字符数组 来模拟字符串
3.字符串的内存分配 堆上 栈上 全局区
首先可以通过数组的方式来初始化字符串
例如
//1、指定长度
char buf2[100] = { 'a','b','c','d' };
//2、不指定长度
char buf3[] = { 'a','b','c','d' };
但是需要注意
char buf2[2] = { 'a','b','c','d' };
这种方式是不行的,会包编译错误
如果没有指定长度的话,编译器会默认指定长度
char buf1[] = { 'a','b','c','d' };
但是这种方式就不能称为字符串,只能称为字符数组,因为不符合字符串的定义,结尾不是以'\0'结尾的。
还可以通过字符串的方式来初始化字符数组
//用字符串来初始化字符数组
int main(int argc, char *argv[])
{
//buf3 作为字符数组是5个字节,作为字符串是4个字节
char buf3[] = "abcd";
int size = 0;
int len = strlen(buf3);
printf("buf3字符的长度%d\n", len);
//buf3 作为数组 数组是一种数据类型 本质(固定大小内存块的别名)
size = sizeof(buf3);
printf("buf3数组所占内存空间大小%d\n", size);
printf("hello world\n");
system("pause");
return 0;
}
可以看到sizeof操作符合strlen函数的计算结果是不一样的,这是因为字符串末尾自带一个'\0'字符,所以在计算数组大小时会加上一。
还可以通过指针来定义一个字符串。
int i = 0;
char buf5[128] = "abcdefg";
char *p = NULL;
for (i = 0;i < strlen(buf5);i++)
{
printf("%c ", buf5[i]);
}
p = buf5; //buf5 代表数组元素的首地址
for (i = 0;i < strlen(buf5);i++)
{
printf("%c ", *(p+i));
}
这种方式与数组的一致,这边就不过多说了。