来复习一个例题:
#include <stdio.h>
#include <stdlib.h>
int main(){
int a[5][5];
int(*p)[4];
p = a;
printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2], );
system("pause");
return 0;
}
所以是两数之差为 -4
而-4的十六进制:
原码:1000 0000 0000 0000 0000 0000 0000 0100
反码:1111 1111 1111 1111 1111 1111 1111 1011(符号位不变,其他取反)
补码:1111 1111 1111 1111 1111 1111 1111 1100
十六进制:F F F F F F F C
所以最后的输出结果为:FFFFFC,-4
字符函数和字符串函数
重点介绍处理字符和字符串的库函数的使用和注意事项.
求字符串长度
strlen
长度不受限制的字符串函数
strcpy
strcat
strcmp
长度受限制的字符串函数介绍
strncpy
strncat
strncmp
字符串查找
strstr
strtok
错误信息报告
strerror
字符操作
内存操作函数
memcpy
memmove
memset
memcmp
strlen
size_t strlen( const char* str);
字符串已经'\0'作为结束标志,strlen函数返回的是在字符串中'\0'前面出现的字符长度
参数指向的字符串必须要以'\0'结束.
注意函数的返回值 size_t,是无符号的(易错)
学会strlen函数的模拟实现
#include <stdio.h>
#include <stdlib.h>
int main(){
char* str = "abcd";
printf("len = %d\n",strlen(str));
system("pause");
return 0;
}
自己实现strlen函数的功能
#include <stdio.h>
#include <stdlib.h>
size_t my_strlen(const char* string){
int len = 0;
while (*string != '\0'){
len++;
string++;
}
return len;
}
int main(){
char* str = "abcd";
printf("len = %d\n",my_strlen(str));
system("pause");
return 0;
}
会发现有很多的问题:首先缺乏安全意识(没有考虑到字符串是空的情况)
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>//使用断言
size_t my_strlen(const char* string){
assert(string != NULL);//使用断言
size_t len = 0;//返回值类型要一致
const char* p_str = string;//对指针进行参数保护(使用一个临时指针代替)
while (*p_str != '\0'){
len++;
string++;
}
return len;
}
int main(){
char* str = "abcd";
printf("len = %d\n",my_strlen(str));
system("pause");
return 0;
}
也可以用递归来写这个函数
size_t my_strlen(const char* string){
if(*string == '\0')
return 0;
else
return my_strlen(string + 1) + 1;
}
strcpy
#include<stdio.h>
#include<stdlib.h>
int main(){
char str1[] = "Hello abc";
char *str2 = "XYZ.";
printf("str1 = %s\n",str1);
strcpy(str1,str2);
printf("str1 = %s\n",str1);
system("pause");
return 0;
}
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
char* my_strcpy(char* strDestination, const char* strSource){
assert(strDestination != NULL && strSource != 0);//检查参数
char* pDestination = strDestination;
char* pSource = strSource;//保护参数
while (*pSource = '\0'){
*pDestination++ = *pSource++;
}
*pDestination = '\0';
return strDestination;
}
int main(){
char str1[] = "Hello abc";
char *str2 = "XYZ.";
printf("str1 = %s\n",str1);
strcpy(str1,str2);
printf("str1 = %s\n",str1);
system("pause");
return 0;
}
strcat
原字符串必须以'\0'结束
目标空间必须足够大,能容纳下原字符串的内容
目标空间必须可修改
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
int main(){
char str1[20] = "hello";
char* str2 = "world";
printf("str1 = %s\n",str1);
char* pret = strcat(str1, str2);
printf("str1 = %s\n", str1);
printf("str1 = %s\n", pret);
system("pause");
return 0;
}
char* str = NULL;(这个指针不指向任何空间)
char* str ="";(指向一个空间,空间里有一个\0)
char* str =" ";(指向一个空间,空间里有一个空格和一个\0)
strcmp
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
int main(){
char* str1 = "hello";
char* str2 = "world";
int ret = strcmp(str1, str2);
if (ret == 0)
printf("str1 = str2");
else if (ret < 0)
printf("str1 < str2");
else
printf("str1 > str2");
system("pause");
return 0;
}
strncmp
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
int main(){
char* str1 = "hello";
char* str2 = "world";
int ret = strncmp(str1, str2,3);//n是几,就比多少个字符
if (ret == 0)
printf("str1 = str2");
else if (ret < 0)
printf("str1 < str2");
else
printf("str1 > str2");
system("pause");
return 0;
}
strncpy,strncat也和上面同理,n是多少就链接,拷贝多少字符.
strstr
模式匹配 查找一个子串
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
int main(){
char* str1 = "abcdefghijklmn";
char* str2 = "def";
char* ret = strstr(str1, str2);
if (ret != NULL)
printf("ret = %s\n",ret);
else
printf("str2 不存在");
system("pause");
return 0;
}
strerror
memset();初始化
memcmp();
memcpy();
memmove();
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
int main(){
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
//int brr[10];
int brr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
memset(brr, 0, sizeof(int) * 10);
memcpy(brr, arr, sizeof(int) * 10);
memcmp(arr, brr, sizeof(int) * 10);
memmove(brr,arr,sizeof(int) * 10);
system("pause");
return 0;
}