指针与字符串
1.字符指针
#include <stdio.h>
int main()
{
char str[] = "hello world";
char *p = str;
*p = 'm';
p++;
*p = 'i';
printf("%s\n", str);
p = "mike jiang";
printf("%s\n", p);
char *q = "test";
printf("%s\n", q);
return 0;
}
2.字符指针做函数参数
#include <stdio.h>
void mystrcat(char *dest, const char *src)
{
int len1 = 0;
int len2 = 0;
while (dest[len1])
{
len1++;
}
while (src[len2])
{
len2++;
}
int i;
for (i = 0; i < len2; i++)
{
dest[len1 + i] = src[i];
}
}
int main()
{
char dst[100] = "hello mike";
char src[] = "123456";
mystrcat(dst, src);
printf("dst = %s\n", dst);
return 0;
}
3.const修饰的指针变量
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
//const修饰一个变量为只读
const int a = 10;
//a = 100; //err
//指针变量, 指针指向的内存, 2个不同概念
char buf[] = "aklgjdlsgjlkds";
//从左往右看,跳过类型,看修饰哪个字符
//如果是*, 说明指针指向的内存不能改变
//如果是指针变量,说明指针的指向不能改变,指针的值不能修改
const char *p = buf;
// 等价于上面 char const *p1 = buf;
//p[1] = '2'; //err
p = "agdlsjaglkdsajgl"; //ok
char * const p2 = buf;
p2[1] = '3';
//p2 = "salkjgldsjaglk"; //err
//p3为只读,指向不能变,指向的内存也不能变
const char * const p3 = buf;
return 0;
}
4.指针数组做为main函数的形参
int main(int argc, char *argv[]);
main函数是操作系统调用的,第一个参数标明argv数组的成员数量,argv数组的每个成员都是char *类型
argv是命令行参数的字符串数组
argc代表命令行参数的数量,程序名字本身算一个参数
#include <stdio.h>
//argc: 传参数的个数(包含可执行程序)
//argv:指针数组,指向输入的参数
int main(int argc, char *argv[])
{
//指针数组,它是数组,每个元素都是指针
char *a[] = { "aaaaaaa", "bbbbbbbbbb", "ccccccc" };
int i = 0;
printf("argc = %d\n", argc);
for (i = 0; i < argc; i++)
{
printf("%s\n", argv[i]);
}
return 0;
}
5.项目开发常用字符串应用模型
1) strstr中的while和do-while模型
利用strstr标准库函数找出一个字符串中substr出现的个数。
a) while模型
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char *p = "11abcd111122abcd333abcd3322abcd3333322qqq";
int n = 0;
while ((p = strstr(p, "abcd")) != NULL)
{
//能进来,肯定有匹配的子串
//重新设置起点位置
p = p + strlen("abcd");
n++;
if (*p == 0) //如果到结束符
{
break;
}
}
printf("n = %d\n", n);
return 0;
}
b) do-while模型
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char *p = "11abcd111122abcd333abcd3322abcd3333322qqq";
int n = 0;
do
{
p = strstr(p, "abcd");
if (p != NULL)
{
n++; //累计个数
//重新设置查找的起点
p = p + strlen("abcd");
}
else //如果没有匹配的字符串,跳出循环
{
break;
}
} while (*p != 0); //如果没有到结尾
printf("n = %d\n", n);
return 0;
}
2) 两头堵模型
求非空字符串元素的个数:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int fun(char *p, int *n)
{
if (p == NULL || n == NULL)
{
return -1;
}
int begin = 0;
int end = strlen(p) - 1;
//从左边开始
//如果当前字符为空,而且没有结束
while (p[begin] == ' ' && p[begin] != 0)
{
begin++; //位置从右移动一位
}
//从右往左移动
while (p[end] == ' ' && end > 0)
{
end--; //往左移动
}
if (end == 0)
{
return -2;
}
//非空元素个数
*n = end - begin + 1;
return 0;
}
int main(void)
{
char *p = " abcddsgadsgefg ";
int ret = 0;
int n = 0;
ret = fun(p, &n);
if (ret != 0)
{
return ret;
}
printf("非空字符串元素个数:%d\n", n);
return 0;
}
3) 字符串反转模型(逆置)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int inverse(char *p)
{
if (p == NULL)
{
return -1;
}
char *str = p;
int begin = 0;
int end = strlen(str) - 1;
char tmp;
while (begin < end)
{
//交换元素
tmp = str[begin];
str[begin] = str[end];
str[end] = tmp;
begin++; //往右移动位置
end--; //往左移动位置
}
return 0;
}
int main(void)
{
//char *str = "abcdefg"; //文件常量区,内容不允许修改
char str[] = "abcdef";
int ret = inverse(str);
if (ret != 0)
{
return ret;
}
printf("str ========== %s\n", str);
return 0;
}
指针小结
定义 | 说明 |
int i | 定义整形变量 |
int *p | 定义一个指向int的指针变量 |
int a[10] | 定义一个有10个元素的数组,每个元素类型为int |
int *p[10] | 定义一个有10个元素的数组,每个元素类型为int* |
int func() | 定义一个函数,返回值为int型 |
int *func() | 定义一个函数,返回值为int *型 |
int **p | 定义一个指向int的指针的指针,二级指针 |