0
点赞
收藏
分享

微信扫一扫

C语言进阶 ~ 一级指针与字符串


目录

​​2.1 指针强化​​

​​2.2 一级指针(char*)易错地方​​

​​2.2.1 对空字符串和非法字符串的判断​​

​​2.2.2 越界​​

​​2.2.3 指针的叠加会不断改变指针的方向​​

​​2.2.4 局部变量不要外传​​

​​2.2.5 函数内使用辅助变量的重要性​​

​​2.3 字符串​​

​​2.3.1 字符串初始化​​

​​2.3.2 数组法和指针法操作字符串​​

​​2.3.3 字符串拷贝函数 strcpy​​

​​剖析片段程序​​

​​2.4 const​​

​​2.4.1 冒牌的 “const”​​

​​2.4.2 const 与 指针​​

2.1 指针强化

强化1:指针是一种数据类型

1)指针变量也是一种变量,占有内存空间,用来保存内存地址测试指针变量占有内存空间大小。

2)保证所指的内存块能修改

3)指针是一种数据类型,是指它指向的内存空间的数据类型

4 ) 不允许向NULL和未知非法地址拷贝内存。

char *p3 = NULL;
//给p3指向的内存区域拷贝内存
strcpy(p3, "1111"); //err


char *p3 = 0x0001;
//给p3指向的内存区域拷贝内存
strcpy(p3, "1111"); //err

强化2:间接赋值(*p)是指针存在的最大意义

强化3:理解指针必须和内存四区概念相结合

强化4:应用指针必须和函数调用相结合(指针做函数参数)

值得一看:


用1级指针形参,去间接修改了0级指针(实参)的值。

用2级指针形参,去间接修改了1级指针(实参)的值。

用3级指针形参,去间接修改了2级指针(实参)的值。

用n级指针形参,去间接修改了n-1级指针(实参)的值。


#include <stdio.h>

void fun(char **p , int *len)
{
if (p == NULL)
{
return;
}

char *tmp = (char *)malloc(100);
if (tmp == NULL)
{
return;
}
strcpy(tmp, "adlsgjldsk");

//间接赋值
*p = tmp;
*len = strlen(tmp);
}

int main(void)
{

char *p1 = NULL;
int len1 = 0;
fun(&p1, &len1);
if (p1 != NULL)
{
printf("p1 = %s, len1 = %d\n", p1, len1);
}

printf("\n");
system("pause");
return 0;
}

C语言进阶 ~ 一级指针与字符串_字符串

① 程序运行至 char *tmp = (char *)malloc(100);

C语言进阶 ~ 一级指针与字符串_const 与 指针_02

C语言进阶 ~ 一级指针与字符串_指针强化_03

② 程序运行至 strcpy(tmp, "adlsgjldsk");

C语言进阶 ~ 一级指针与字符串_指针强化_04

C语言进阶 ~ 一级指针与字符串_c语言_05

③ 程序运行至 *p = tmp;

C语言进阶 ~ 一级指针与字符串_一级指针易错地方_06

④ 程序运行至 *len = strlen(tmp);

C语言进阶 ~ 一级指针与字符串_c语言_07

2.2 一级指针(char*)易错地方

2.2.1 对空字符串和非法字符串的判断


void copy_str(char *from, char
{
if (*from == '\0' || *to == '\0') // 正确的为if (from == '\0' || to == '\0') 地址是否为空
{
"func copy_str() err\n");
return;
}
for (; *from!='\0'; from++, to++)
{
*to = *from;
}
'\0';
}


2.2.2 越界


char buf[3] = "abc";


2.2.3 指针的叠加会不断改变指针的方向


char *getKeyByValue(char **keyvaluebuf, char
{
int i = 0;
char *a = (char *)malloc(50);
for (; **keyvaluebuf != '\0'; i++)
{
*a++ = *(*keyvaluebuf)++;
}
free(a);
}


2.2.4 局部变量不要外传


char *my_stract(char *x, char* y)
{
char str[80];
char *z=str; /*指针z指向数组str*/
while(*z++=*x++);
/*去掉串尾结束标志*/
while(*z++=*y++);
/*将str地址赋给指针变量z*/
return(z);
}


2.2.5 函数内使用辅助变量的重要性


int getSubCount(char *str, char *substr, int
{
int ret = 0;
char
char
if (str==NULL || substr==NULL || mycount == NULL)
{
1;
return
}
............


 

2.3 字符串

c语言没有字符串类型,通过字符数组模拟
c语言字符串,以字符‘\0’或数字0

2.3.1 字符串初始化

①  strlen:测字符串长度,不包含数字0,字符'\0'
      sizeof:测数组长度,包含数字0,字符'\0'

    char buf9[100] = "agjdslgjlsdjg";
    printf("strlen = %d, sizeof = %d\n", strlen(buf9), sizeof(buf9));

C语言进阶 ~ 一级指针与字符串_指针强化_08

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*
C语言没有字符串类型,通过字符数组模拟
C语言字符串,以字符‘\0’, 数字0
*/
int main(void)
{

//不指定长度, 没有0结束符,有多少个元素就有多长
char buf[] = { 'a', 'b', 'c' };
printf("buf = %s\n", buf);

//指定长度,后面没有赋值的元素,自动补0
char buf2[100] = { 'a', 'b', 'c' };
printf("buf2 = %s\n", buf2);

//所有元素赋值为0
char buf3[100] = { 0 };
//

//char buf4[2] = { '1', '2', '3' }; //数组越界

char buf5[50] = { '1', 'a', 'b', '0', '7' };
printf("buf5 = %s\n", buf5);

char buf6[50] = { '1', 'a', 'b', 0, '7' };
printf("buf6 = %s\n", buf6);

char buf7[50] = { '1', 'a', 'b', '\0', '7' };
printf("buf7 = %s\n", buf7);
//

//使用字符串初始化,常用
char buf8[] = "agjdslgjlsdjg";
//
//strlen: 测字符串长度,不包含数字0,字符'\0'
//sizeof:测数组长度,包含数字0,字符'\0'
printf("strlen = %d, sizeof = %d\n", strlen(buf8), sizeof(buf8));
//
char buf9[100] = "agjdslgjlsdjg";
printf("strlen = %d, sizeof = %d\n", strlen(buf9), sizeof(buf9));

/

printf("\n");
system("pause");
return 0;
}

C语言进阶 ~ 一级指针与字符串_const 与 指针_09

2.3.2 数组法和指针法操作字符串

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
char buf[] = "algjdlksajgldksjg";
int i = 0;
int n = strlen(buf);
char *p = NULL;

//[]方式
for (i = 0; i < n; i++)
{
printf("%c", buf[i]);
}
printf("\n");

//指针方法
//数组名字,数组首元素地址
p = buf;
//
for (i = 0; i < n; i++)
{
printf("%c", p[i]);
}
printf("\n");
//
for (i = 0; i < n; i++)
{
printf("%c", *(p+i) );
}
printf("\n");
//
for (i = 0; i < n; i++)
{
printf("%c", *(buf+i) );
}
printf("\n");
//
//buf和p完全等价吗?
//p++; 正常
//buf++; 此处出错
//buf 只是一个常量,不能修改

//
printf("\n");
system("pause");
return 0;
}

2.3.3 字符串拷贝函数 strcpy

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


//成功为0,失败非0
//1、判断形参指针是否为NULL
//2、最好不要直接使用形参
int my_strcpy(char *dst, char *src)
{
if (dst == NULL || src == NULL)
{
return -1;
}

//辅助变量把形参接过来
char *to = dst;
char *from = src;

//*to = *from
//to++, from++
//判断 *to是否为0, 为0跳出循环
while (*to++ = *from++)
{
NULL;
}

printf("my_strcpy: dst = %s\n", dst);

return 0;
}

int main(void)
{
char src[] = "abcedfdgds";
char dst[100] = { 0 };
int ret = 0;


ret = my_strcpy(dst, src);
if (ret != 0)
{
printf("my_strcpy err:%d\n", ret);
return ret;
}
printf("%s\n", dst);


printf("\n");
system("pause");
return 0;
}

剖析片段程序

    while (*to++ = *from++)
    {
        NULL;
    }

① *to = *from

② to++, from++

③ 判断 *to是否为0, 为0跳出循环

2.4 const

2.4.1 冒牌的 “const”

const旨在用户层面不能修改,而一般在机器修改时候都是用的是地址进行改数。

const int b = 10;
//b = 100; //err
int *q = &b;
*q = 22;
printf("%d, %d\n", b, *q);

C语言进阶 ~ 一级指针与字符串_一级指针易错地方_10

2.4.2 const 与 指针

    指针变量, 指针指向的内存, 2个不同概念

char buf[] = "aklgjdlsgjlkds";

    从左往右看,跳过类型,看修饰哪个字符

    const char *p = buf;
    // 等价于上面 char const *p1 = buf;

  • 如果是*, 说明指针指向的内存不能改变

    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;

 

举报

相关推荐

0 条评论