指针3
字符串
字符串:一串字符,“多个字符” 单个字符,C语言有专门的类型 char / unsigned char C语言中,是没有字符串的类型的。C语言的字符串是通过char *(字符型指针)来实现的 字符串:用一组连续的地址空间来一次储存每个字符 并且要访问它,可以通过char * 字符串就是一串字符,0个或者多个字符,并且约定以字符‘\0’(空字符,ASCII为0的字符)标志字符串的结束 我们只需要知道字符串的首地址(char *),就可以访问每一个字符串的所有字符。so char * 就可以描述一个字符串(保存的就是这个字符串的首个字符的地址)字符串常量
字符串常量:不可以修改的字符串,只能读!! 如: C代码中,所有用”“引起来的都是字符串的常量 char *p = "abc" "abc" 是字符串常量 p是一个变量,p指向字符串的首字符的地址 p保存的是 'a' 的地址 *p代表是它指向的对象,'a' 这个对象只有右值,没有左值(所以这个字符串常量是不是就不能被更改)eg: char* p = "abc"; printf("%c\n",*p); //a
char ch = *p ; printf("%c\n",ch); *p = 'A'; //error , 非法的内存访问 p+1; //保存的'b'的地址 p+2; //保存的'c'的地址 p = "123"; //没有问题,p本身是一个变量,他是有左值 printf("%c\n",*p);字符串变量
字符串变量:可以被修改的字符串,可读可写!!eg: char s[5] = {'1','2','3','4','5'}; char p = s; //p 保存的是&s[0],'1'的地址 //p 代表他指向的对象.s[0],有左值,也有右值
//数组s是一个可读可写,但是“abc”是一个字符串常量 char s[5] = {"abc"}; =====》 s[0] = 'a' s[1] = 'b' s[2] = 'c' s[3] = '\0' s[4] = 0 char *p = s; int i; //p保存的s[0]的地址,*p 表示的是s[0],是一个变量 *p = 'A'; for(i = 0 ;*(p+i) != 0 ; i++) { printf("%c ",*(p+i)); //printf("%c ",s[i]); }练习
char s1[] = {'a','b','c'}; char s2[] = {"abc"}; =====> char s2[] = {'a','b','c','\0'} NOTE:“abc” ====》abc\0 编译器只会在 字符串常量(“”引起来)后面加一个 0 请问s1的元素有多少个 3个 s2的元素有多少个 4个 sizeof(s1) 求s1所占的字节数 sizeof(数组) = sizeof(数组元素) * 元素 sizeof(s1) = sizeof(char) * n = n char s3[5] = {'a','b','c'}; //5 char s4[5] = {"abc"}; //5 请问s3的元素有多少个 sizeof(s3) = sizeof(char) * 5 = 5 s4的元素有多少个 sizeof(s4) = sizeof(char) * 5 = 5 char s5[5] = {"abcde"}; //error why??练习
给一个字符串的指针(char *),求这个字符串的长度?? 字符串的长度是指:这个字符串中包含了多少个字符,数到\0为止; 不准使用(string.h) 有几个常用字符串的处理函数(标志C库里面) strlen_my #include <stdio.h> int strlen_m(char *s) { int n = 0; while(*s) { n++; s++; } return n; } int main() { char s1[] = {'5','7','8' }; char *s2= "abcde"; printf("s2[5] = %c\n",s2[5]); int sum = strlen_m(s2)+1; printf("sum=%d\n",sum); }几个常用的字符串处理函数(标准库里面的)
const 关键字的简介
const的含义:只要在一个变量前面用const来修饰的话,就意味着这个变量里面的数据,你就只可以访问,不能去修改,也就意味着只读! const的规则:const一旦修饰了一个变量,你一定要给这个变量初始化,如果你定义的时候不初始化,那么你后面无法去初始化它了strlen : 用来求一个字符串的长度
NAME strlen - calculate the length of a string
SYNOPSIS #include <string.h>
size_t strlen(const char *s); s:要计算长度的字符串的首地址 返回值: 返回值字符串s第一个\0前面的字符个数DESCRIPTION The strlen() function calculates the length of the string pointed to by s, excluding the terminating null byte ('\0'). 不计算\0
例子: strlen("abcde") ==== 5 char s[4] = {'1','2'}; int l; l = strlen(s); l = 2
l = strlen("abcd\nabc"); l = 8 l = strlen("123\123abc\0abc"); l = 9?? 10?? 3?? 7??? l = 7; l = strlen("123\0123abc\0abc"); l = 3?8?strcpy/strncpy
字符串拷贝函数 把一个字符串拷贝到另外一个字符串去NAME strcpy, strncpy - copy a string
SYNOPSIS #include <string.h>
//strcpy 用来 src 指向的字符串,拷贝到dest指向字符串中去,直到遇到\0 char *strcpy(char *dest, const char *src); dest : destination 目的地 src : source 源 从哪儿 返回值: 返回拷贝后的目的地字符串的首地址 例子: char s[6]; strcpy(s,"12345"); printf("%s\n",s); 但是 , strcpy有一个巨大bug!!! do you know??? 它没有考虑到越界的问题,有可能会导致内存的越界的非法访问 char s1[8]; char s2[8] = {"abcde"}; //一般的编译器会把s1和s2 放在连续的地址空间去 strcpy(s1 ,"12345678910"); printf("%s\n",s1); //12345678 //12345678910 printf("%s\n",s2); //910abcde //910 strncpy 正是为了解决这个strcpy的这个bug的(strcpy没有考虑dest指向的空间的大小问题) char *strncpy(char *dest, const char *src, size_t n); strncpy 把src指向的字符串前面顶多n个字符拷贝靠dest指向的空间里面 dest : src: n: strncpy 的功能和 strcpy 类似的,只不过它顶多拷贝src前面的n个字符到dest指向的空间中去 那么strncpy到底拷贝多少个字符呢?? <=n (1)、遇到\0拷贝结束,此时的\0也会拷贝进去 (2)、已经拷贝了n个字符拉(后面的\0不会自动拷贝,除非你的第n个字符是\0)练习
1、分析如下程序的输出结果: char s1[8]; char s2[8] = {"ABCDE"}; strncpy(s1,"123456789",8); printf("%s\n",s1); //12345678ABCDE printf("%s\n",s2); //ABCDEstrcmp/strncmp 字符串比较
字符串是如何比较的呢?? 一个一个字符的去比较他们的ASCII码 if c1 > c2 返回1 if c1 < c2 返回-1 if c1 == c2 则继续比较下一个字符 ,如果全部相等则返回0NAME strcmp, strncmp - compare two strings
SYNOPSIS #include <string.h>
int strcmp(const char *s1, const char *s2); int strncmp(const char *s1, const char *s2, size_t n); The strncmp() function is similar, except it compares only the first (at most) n bytes of s1 and s2. RETURN VALUE The strcmp() and strncmp() functions return an integer less than, equal to, or greater than zero if s1 (or the first n bytes thereof) is found, respectively, to be less than, to match, or be greater than s2.eg: strcmp("123","ABC") < 0
strcmp("123" , "123\0ABC") == 0 strcmp("1234" , "123"); > 0 strncmp(s,"zhou",4)strcat/strncat
NAME strcat, strncat - concatenate(连接) two strings
SYNOPSIS #include <string.h>
char *strcat(char *dest, const char *src); dest : 指向目标字符串(一段空间)dest指向这段空间,应该足够大 why src : 指向我们原始字符串 返回值: 如果成功的话,返回连接后的字符串的首地址 如果失败的话,返回NULL eg: char s1[12] = {"ABCD"}; strcat(s1,"12345"); printf("%s\n",s1); strcat 也有一个巨大bug!!你懂的 so , strncat 就是用来修复strcat的这个bug的 strncat 把src指向的字符串拷贝到dest的末尾,但是它顶多拷贝n个字符,,那么strncat到底拷贝多少个字符?? (1)、遇到\0结束 (2)、即使是没有遇到\0,但是已经拷贝了n个字节啦,也应该结束了吧。 char *strncat(char *dest, const char *src, size_t n);练习
1、分析如下程序的输出结果! char s[12]; strcat(s,"12345"); printf("%s\n",s); //12345 //没有初始化,打印出随机值 2、写一个函数,把一个十进制的数字字符串,转换成一个整数 "123" --> 123 "-456" ----> -456 (1)、明确任务目标 atoi:把一个十进制的数字字符串,转换成整数 (2)、确定任务的输入参数 “字符串” atoi(char *s) (3)、确定完成任务的返回值 int atoi(char *s) (4)具体的是实现代码 int atoi(char *s) { int d = 0; //当前位的数值 int num = 0; //整数的值 int minus = 0 ; //fushu if(*s == '-') { minus = 0; s++; } else if(*s== '+') { minus = 1; s++; } while(*s) { d = *s - '0'; num = num * 10 + d; s++; } if(minus == 0) { num = num * (-1); } return num; }memcpy 内存拷贝
NAME memcpy - copy memory area
SYNOPSIS #include <string.h>
void *memcpy(void *dest, const void *src, size_t n);memcpy 和 strncpy 好像都是一样的?如果都拷贝n个数据
strncpy:字符串拷贝函数 遇到' \ 0 '就结束 , 如果没有拷贝完,后面会补 n - i 个’\0‘;bzero
bzero :用来把一个指定的空间清0
NAME bzero ,explicit_bzero - zero a byte string
SYNOPSIS #include <string.h>
//用来把s指向的空间的前面的n个字节清0 void bzero(void *s, size_t n);
嵌入式学习一阶段——C语言:指针三
最新推荐文章于 2024-09-12 08:54:42 发布