1.指针深层解析数组
我们经常使用指针来进行运算,而将指针运用到调用函数当中,我们需要注意的是:
想要运用指针来通过地址传递改变指针的值,必须越级,如果传递指针的值或者地址,调用时还是指针或者地址的话,那么还是属于值传递,越级就是说,传递的级别和调用的级别不一样,比如实参传递地址,形参用地址指向的值这样不同级别的才能实现地址传递来改变实参的值
如:
void swap1(int a, int b)
{
int temp;
temp = a;
a = b;
b = temp;
}
void swap2(int* x, int* y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
int main()
{
int a = 10, b = 20;
swap1(a, b);//值传递,结果为10,20
printf("%d %d\n", a, b);
swap2(&a, &b);//地址传递,结果为20,10
printf("%d %d\n", a, b);
return 0;
}
以以上为例子,因为调用函数时,函数结束后,会摧毁数据,所以用值传递的话在被调函数中确实运行交换了值,不过数据摧毁后在主函数中并没有变化,而用地址传递的话,改变地址指向的值,回到主函数时地址指向的值就会改变。
但指针也不是万能的,比如数组的情况下可以直接修改字符串,而指针不行。
用数组定义的字符串里面的字符串称为栈区字符串,可以改变,而指针定义的字符串为数据区常量区字符串,不可改变,而当数据区中的常量一样时,地址也一样
int main()
{
char ch[] = "hello world";//栈区字符串,字符串可以改变
char* p ="hello world" ;//数组去常量区字符串,字符串不可改变
char* p1 = "hello world";//地址和p的一样
printf("%p\n", p);
printf("%p\n", p1);
ch[2] = 'm';//可以用实现
//p[2] = 'm';//不可实现
printf("%s\n", ch);
printf("%s\n", p);
return 0;
}
2.字符串做参数
上编文章说到,指针做参数时,会丢失精度,需要手动传输精度,而字符串做参数时并不需要传递元素个数
void 函数名(int* a,int n)//需要传递精度
{
代码体
}
void 函数名(char* p)//不需要传递精度
{
代码体
}
int main()
{
int a[]={1,2,3};
int n=3;
char* p="hello";
}
上编说到,const修饰什么,什么就不能被改变,那么,可以通过不同维度的来改变或者通过同维度不同的变量来改变。
int main()
{
int a, b;
a = 10;
b = 20;
const int* p = &a;
p = &b;//通过不同的维度来改变
printf("%d\n", *p);//20
p = &a;
int* temp = p;
*temp = b;//通过同维度但不同的变量来改变
printf("%d\n", *p);//20
}
3.关于字符串的函数
(1)字符串复制
函数strcpy()和函数strncpy()
char ch[]="hello world";
char str1[100]={0};//定义100是怕空间不够
char str2[100}={0};//给数组初始值
strcpy(str1,ch);
strncpy(str2,ch,2);
printf("%s\n",str1);
printf("%s\n",str2);
str1和str2可以赋初值,防止此类问题发生
(2)字符串追加,意思是将一个数组的字符串追到另一个数组的字符串去
函数strcat()和函数strncat()
char ch[100] = "hello";
char str1[] ="world";
char str2[] ="world";
strcat(ch, str1);//将str1中的字符串追加到ch后面
printf("%s\n", ch);
strncat(ch, str2, 2);//将str2中前面2个字符追加到ch的后面
printf("%s\n", ch);
可以给需要被追加的数组赋予明确的字符数
(3)字符串的比较
函数strcmp()和函数strncmp()
char ch[100] = "hello";
char str1[] ="hello";
char str2[] ="hallo";
int a=strcmp(ch, str1);
printf("%d\n", a);
int b=strncmp(ch, str2);
printf("%d\n",b);
两个字符串相同返回值为0;大于返回值为1,小于返回值为-1;
(4)格式化函数形式
函数sprintf()和函数sscanf()
char ch[] = "hello world";
char str1[100] = { 0 };
char str2[100] = { 0 };
sprintf(str1, "hello world");//可以像复制函数那样,复制
printf("%s\n", str1);
sprintf(str2,"%d,%d,%d",1,2,3);//也可以将数字这样用
printf("%s\n",str2);
char str3[100]="1,2,3";
int a,b,c;
sscanf(str3,"%d,%d,%d",&a,&b,&c);//提取str3中的数据
printf("%d %d %d",a,b,c);
printf()是将指定的东西打印,而sprintf()是将指定的数据赋给指定数组或指针
(从后面到前面)
scanf()是从键盘获取数据,而sscanf()是从已有的数据获取
(将前面的东西给后面)
注意
char ch[]="hello world";
char arr[100];
sscanf(ch,"%[^\n]",arr);
printf("%s\n",arr);
要用%[^\n]才能把包括空格的字符串给到后面的地址,如果直接是%s的话,到空格会结束
(5)查找字符或字符串
函数strchr()和函数strchr()
char ch[] = "hello world";
char str[]="lo";
char* p=strstr(ch,str);//两个都是地址
printf("%s\n",p);
p=strchr(ch,'w');//第一个是地址,第二个是int类型
printf("%s\n",p);
strstr函数是从字符串中找字符串,而strchr函数是从字符串中找字符
strstr函数和strchr函数返回值都是地址
(6)字符串分割函数
函数strtok(),意思是分割截取的意思,截取 到打的字符前面的所有字符,知道出现\0或者第一个字符
char arr[]="hello.world.asd.123";
char* p=strtok(arr,".");
printf("%s\n",p);
while(arr)
{
p=strtok(NULL,".");//用NULL多次截取
printf("%s\n",p);
}
函数截取之后,截取的点会变成\0,下次再次截取的时候,不能用arr而用NULL,才能再次截取
(7)字符串转换函数
函数atoi(),atof(),atol()
char arr[]=" -123hello world";
int i=atoi(arr);
printf("%d\n",i);
忽略前面所有的空格,知道遇到数字或正负号才开始转换,遇到非数字或字符串结束符\0才结束转换
转载至