嵌入式学习一阶段——C语言:指针三

指针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);   //ABCDE

strcmp/strncmp 字符串比较

字符串是如何比较的呢??
    一个一个字符的去比较他们的ASCII码
        if c1 > c2 返回1
        if c1 < c2 返回-1
        if c1 == c2 则继续比较下一个字符 ,如果全部相等则返回0

NAME 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);
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值