目录:
一、常见的字符串函数(strlen,strcpy,strcat,strcmp)
二、关于atoi函数的实现
三、关于itoa函数的实现
一、常见字符串的函数 (strlen,strcpy,strcat,strcmp)
1.strlen:求字符串的长度,首先进行代码原理的实现:
int arr_strlen(char *arr) {
int count = 0;
for (int i = 0; arr[i] != '\0'; i++) {
count++;
}
return count;
}
int main() {
char arr[20] = "abcde";
int res= arr_strlen(arr);
printf("%d", res);
}
运行结果:
5
D:\c程序\p1-8\Debug\p1-8.exe (进程 17988)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
2.strcpy:字符串的拷贝,首先进行代码原理的实现:
void arr_strcpy(char *arr,char *brr) {
char* p = arr;
char* q = brr;
for (int i = 0; arr[i] != '\0'; i++) {
*p = *q;
p++;
q++;
}
}
int main() {
char arr[20] = "abcde";
char brr[] = "efghi";
arr_strcpy(arr, brr);
for (int i = 0; arr[i] != '\0'; i++) {
printf("%c", arr[i]);
}
}
运行结果:
efghi
D:\c程序\p1-8\Debug\p1-8.exe (进程 17696)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
3.strcat:字符串的链接,首先进行代码原理的实现:
void arr_strcat(char *arr,char* brr) {
char* p = arr;
char* q = brr;
for (int i = 0; arr[i] != '\0'; i++) {
p++;
}
for (int j = 0; brr[j] != '\0'; j++) {
*p = *q;
p++;
q++;
}
}
int main() {
char arr[20] = "abcde";
char brr[] = "efgji";
arr_strcat(arr, brr);
for (int i = 0; arr[i] != '\0'; i++) {
printf("%c", arr[i]);
}
}
运行结果:
abcdeefgji
D:\c程序\p1-8\Debug\p1-8.exe (进程 15664)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
4.strcmp:字符串的比较,原理是通过ASCII表比较,首先进行代码原理的实现:
int arr_strcmp(char *arr,char *brr) { //利用ascii码表比较字符串每个字母的大小
char* p = arr;
char* q = brr;
int res = 0;
while (*p != '\0' || *q != '\0') {
if (*p > *q) { //如果数组arr中第一个字大于brr中第一的字母,返回1,正数
res=1;
break; //循环直接退出
}
else if (*p < *q) { //如果数组arr中第一个字小于brr中第一的字母,返回-1,负数
res= -1;
break; //循环直接退出
}
else { //如果数组arr中第一个字等于brr中第一的字母,返回0
res= 0;
}
p++; //循环继续,指针继续遍历后面的字母,直到比较出大小
q++;
}
return res;
}
int main() {
char arr[20] = "abcde";
char brr[] = "abghi";
int result=arr_strcmp(arr, brr);
printf("%d", result);
}
运行结果:
-1
D:\c程序\p1-8\Debug\p1-8.exe (进程 8516)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
总结:上面都是对我们常见的字符串函数原理的总结,但在平时我们想要使用字符串函数,直接引用头文件:#include<string.h>
1.strlen(arr):调用库函数,参数arr代表的是:是求'\0'前面的字符长度。
2.strcpy(arr,brr):调用库函数,参数arr,brr代表的是:将brr字符串数组中的字符拷贝给arr数组,覆盖了arr原来的字符。
3.strcat(arr,brr):调用库函数,参数arr,brr代表的是:将brr字符串数组中的字符链接在arr字符串数组中字符的后面
4.strcmp(arr,brr):调用库函数,参数arr,brr代表的是:比较arr与brr中字符的ascii码值,如果arr>brr,则返回正数(一般情况下返回1),如果arr<brr,则返回负数(一般情况下返回-1),
如果arr=brr,则返回0.
二、关于atoi函数的实现
atoi:意思是将字符串的形式转换为数字的形式,例如:将字符串"123"转换为数字123.有以下几点需要注意:
1.当字符串前面是空格的时候,转化为数字的时候要把空格删掉,例如:" 123"转化为数字123
2.当字符串前面是+-号时,转化为数字要根据数学上的算法将正负号保留,例如:"+-+-+--123"转化为数字为-123
3.当字符串前面为字母时候,直接不进行转换,例如:"abcd123",程序直接退出
4.当字符串后面为字母时,后面的字母全部不要,例如:"123abc"转换为数字为123
接下来我们进行代码的实现,首先我们用库函数看一下这个结果
#include<stdlib.h> //记住使用atoi函数时引用头文件
int main() {
const char* arr = "123";
const char* brr = " 123";
const char* crr = "-123";
printf("%d %d %d", atoi(arr), atoi(brr), atoi(crr));
}
运行结果:
123 123 -123
D:\c程序\p1-8\Debug\p1-8.exe (进程 18296)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
接下来,我们对这个函数的原理进行代码的实现:
#include<ctype.h> //关于引用库函数isdigit所使用的头文件
#include<math.h>
int atoi_array(const char* arr) { //统计字符串中数字的个数
const char* p = arr;
int count = 0;
while (*p != '\0') {
if (*p == ' ') { //跳过空格
p++;
continue;
}
else if (*p == '+' || *p == '-') { //跳过符号
p++;
continue;
}
else if (isdigit(*p)) {
count++; //用count计数从而统计个数
p++;
}
else {
break;
}
}
return count;
}
int reserve(const char* arr) { //将字符串中的数字转化为数字
const char* p = arr;
int flag = 1; //标记负号,如果不用标记,也可以用判断奇偶
int res = 0;
int bit = atoi_array(arr);
while (*p != '\0') {
if (isblank(*p)|| *p == '+') {
p++;
}
else if (*p=='-') { //如果为负号就乘以-1
flag = (-1) * flag;
p++;
}
if (isdigit(*p)) { //如果为数字字符就转化为数字
res += (*p - '0')*(int)pow(10, --bit);
p++;
}
}
return res*flag;
}
int main() {
const char* arr = " -123";
int result=reserve(arr);
printf("%d", result);
}
运行结果:
-123
D:\c程序\p1-8\Debug\p1-8.exe (进程 19408)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
三、关于itoa函数的实现
itoa:意思是将整形数字以进制的形式转化为字符串,但是itoa原理的实现错综复杂,例如:
1.将数字123转化为10进制下的字符串,则为"123"
2.将数字100转化为8进制下的字符串,则为"144"
3.将数字16转化为16进制下的字符串,则为"a"
4.将数字-1转化为2进制下的字符串,则为"1111111111111111",16个1
我们如果想要实现以上功能该如何实现呢,首先我们将一些知识点罗列出来:
1.首先我们将最常见的数字以进制的形式转化为字符串,不管是十进制,八进制,我们根据进制转化的原理知道:当一个数转化为进制的时候要用辗转相除法,不断地除以它的进制数,然后倒着读就可以了
2.当遇到转化为16进制涉及abcd等字母的时候,我们怎么办,这是我们想到只需要把26个字母罗列出列,然后对应下表去存放数字就可以了
3.当遇到负数,我们又该怎么办,(我们都知道负数是以补码的形式保存在计算机里面)此时我们想到无符号处理负数,简单的以-1举例:我们知道当有符号的时候,用char类型保存-1,它的数值范围是-128~127,而转化为无符号类型的时候,它的数值范围就变成了0~256(此时负数辗转相除的结果就位11111111),此时的符号位也要变成数值位,符号位便消失了,不存在正负的情况,所以当我们将有符号类型强转为无符号类型,负数情况自然而然就解决了。
接下来我们进行代码的实现,首先我们用库函数看一下这个结果
int main() {
int a = -1;
char arr[100];
_itoa_s(a, arr, 2); //在vs中为了安全性函数引用的库函数变为_itoa_s
for (int i = 0; arr[i]!='\0'; i++) {
printf("%c", arr[i]);
}
运行结果:
11111111111111111111111111111111
D:\c程序\p1-8\Debug\p1-8.exe (进程 17308)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
接下来,我们对这个函数的原理进行代码的实现:
char* itoa_arr(int value,char* buff, int redex) {
assert(buff != NULL);
int index = 0;
int res = 0;
int flag = 0;//标记负号
char arr[100] = "0123456789abcdefghijklmnopqrstuvwxyz";//arr下标对应res,目的将字符取出
if (value < 0 && redex == 10) { //如果为10进制,将符号单独存放起来
buff[index++] = '-';
value *= -1; //此时value变为正数
flag = 1;
}
unsigned int u_value = (unsigned int)value; //将value进行无符号化
while (u_value != 0) { //辗转相除法
res = u_value % redex;
buff[index++] = arr[res];
u_value /= redex;
}
//实现数组的逆转
for (int i = 0; i < (index + 1) / 2; i++) {
char temp = buff[i+flag];
buff[i+flag] = buff[index-1];
buff[index-1] = temp;
index--;
}
return buff;
}
int main() {
char buff[100] = {0};
itoa_arr(-100, buff, 10); //测试代码
for (int i = 0; buff[i] !='\0'; i++) {
printf("%c", buff[i]);
}
}
结果一如下:
-100
D:\c程序\p1-8\Debug\p1-8.exe (进程 14780)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
将测试代码修改为itoa_arr(-1, buff, 2);结果如下:
11111111111111111111111111111111
D:\c程序\p1-8\Debug\p1-8.exe (进程 5260)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .