指针,字符串处理函数,内存操作函数,内存泄漏,内存污染

int a = 10;
int * p = &a;

指针 

定义指针的三步骤

1 *与符号结合代表是一个指针变量

2 要保存谁的地址,将他的定义形式放在此处

3 用*p替换掉定义的变量

分析
1 与*结合代表这个一个指针变量

2 p是变量,p的类型是将变量p本身拖黑,剩下的类型就是指针变量的类型 int *。

3 指针变量p用来保存什么类型数据的地址,将指针变量p和指针变量p最近的*一起拖黑。剩下什么类型就保存什么类型数据的地址,int。

通过*取指针变量所指向那块空间内容时,取的内存的宽度和指针变量本身的类型有关

万能指针
不可以定义 void 类型的变量,因为编译器不知道给变量分配多大的空间,但是可以定义 void *类型,因为指针都是8个字节的地址,万能指针可以保存任意的地址。

const 修饰指针

const 修饰的是p,还是*

const int *p= &a;//const修饰的是*

不能通过 *p,改p所指向空间的内容,例如:*p=100:err 因为不能通过p改p所指向空间的内容

int *const p=&a;//const修饰的是变量p

p保存的地址不可以修改,例如:p=&b;err p本身的值不能被更改

const int *const p=&a;

p本身的指向不能改变,不能通过*p修改p指向向那块空间的内容

int a = 10;
int * p = &a;
int ** q = &p;

 如果*和&相遇,相抵消

**q == *(*q) == *(p) == a;

**q == *(*q) == *(&a) == a; 

[ ]并不是数组专属

[ ] == *()

p[0] == *(p+0);

指针数组
指针数组是一个数组,数组的每一个元素都是一个指针

main(int a,char *v[ ])

字符串处理函数

strcpy

将源字符串 src 的内容复制到目标字符串 dest 中,直到遇到空字符 \0

char dest[20];
char src[] = "Hello";
strcpy(dest, src);

strncpy

将源字符串 src 的前 n 个字符复制到目标字符串 dest 中,或者直到遇到空字符 \0,取决于哪个条件先达成

char dest[20];
char src[] = "Hello";
strncpy(dest, src, 3);  // 复制 "Hel" 到 dest
dest[3] = '\0';  // 手动添加空字符,以确保字符串终止

strcat

将源字符串 src 的内容连接到目标字符串 dest 的末尾,目标字符串 dest 必须足够大,以容纳两个字符串的总长度。

char dest[20] = "Hello";
char src[] = " World";
strcat(dest, src);  // 连接 " World" 到 "Hello" 后面

strncat

将源字符串 src 的前 n 个字符连接到目标字符串 dest 的末尾,或者直到遇到空字符 \0,取决于哪个条件先达成。

char dest[20] = "Hello";
char src[] = " World";
strncat(dest, src, 3);  // 连接 " Wo" 到 "Hello" 后面
dest[8] = '\0';  // 手动添加空字符,以确保字符串终止

strcmp

比较字符串 str1 和 str2 的内容,如果相等返回0,如果 str1 小于 str2 返回负数,如果 str1 大于 str2 返回正数。

char str1[] = "apple";
char str2[] = "banana";
int result = strcmp(str1, str2);  // 比较 "apple" 和 "banana"

strncmp

比较字符串 str1 和 str2 的前 n 个字符,如果相等返回0,如果 str1 小于 str2 返回负数,如果 str1 大于 str2 返回正数。

char str1[] = "apple";
char str2[] = "applesauce";
int result = strncmp(str1, str2, 5);  // 比较 "apple" 和 "apple" 的前5个字符

sprintf

将格式化的数据写入字符串 str

char str[50];
int num = 10;
sprintf(str, "The number is %d", num);  // 将 "The number is 10" 写入 str

sscanf

从字符串 str 中读取格式化输入。

char str[] = "123 4.56";
int num;
float fnum;
sscanf(str, "%d %f", &num, &fnum);  // 从 str 中读取整数和浮点数

strchr

在字符串 str 中查找字符 c 的第一次出现,并返回指向该字符的指针。

char str[] = "Hello";
char *ptr = strchr(str, 'l');  // 查找第一个 'l'

strstr

在字符串 haystack 中查找子字符串 needle 的第一次出现,并返回指向该子字符串的指针。

char haystack[] = "Hello world";
char needle[] = "world";
char *ptr = strstr(haystack, needle);  // 查找 "world"

strtok

分割字符串 str 为一系列子字符串,使用分隔符 delim

char str[] = "Hello,World,How,Are,You";
char *token = strtok(str, ",");  // 使用逗号作为分隔符
while (token != NULL) {
    printf("%s\n", token);  // 逐个打印分割出的子字符串
    token = strtok(NULL, ",");
}

atoi

将字符串 str 转换为整数。

char str[] = "12345";
int num = atoi(str);  // 将 "12345" 转换为整数 12345

atof

将字符串 str 转换为浮点数。

char str[] = "3.14";
float num = atof(str);  // 将 "3.14" 转换为浮点数 3.14

当不知道如何使用,使用man指令查看即可

man sscanf

内存分布

1局部变量
 a >作用域在定义变量的{ }之内有效
 b >生命周期程序运行至变量定义处开辟空间,所在的函数结束之后释放空间
c >未初始化的值随机
2静态局部变量
 a >作用域在定义变量的{ }之内有效
 b >生命周期执行 main 函数之前就已经开辟空间,程序结束之后才释放空间
c >未初始化的值0
3全局变量
 a >作用域整个工程,所有文件
 b >生命周期执行 main 函数之前就已经开辟空间,程序结束之后才释放空间
 c >未初始化的值0
4静态全局变量
 a >作用域当前文件
 b >生命周期执行 main 函数之前就已经开辟空间,程序结束之后才释放空间 
 c >未初始化的值0

 

#include "stdio.h"

int a;
static int b;
int c = 10;
static int d = 10;

int main()
{
    int e;
    int f = 10;
    static int g;
    static int h = 10;
    char * i = "test";
    char * p = malloc(1024);
    memset(p,0,1024);
    strcpy(p,i);
    printf("%s\n",p);
    free(p);
    return 0;
}

误区:这样是错误的,因为开辟空间的地址并没有给到main栈的p。在 fun 函数中,虽然分配了内存,但是没有将分配的内存地址返回给 main 函数中的 p,因此 main 函数中的 p 仍然是 NULL,导致后续的内存操作出现错误。

字符串常量存文字常量区在使用时,取的是字符串首元素的地址,文字常量区的内容是不可以改变的。

char i[ ] = "test";此时的i是在栈区,内容可以被修改

char * i = "test";此时的i是在文字常量区,内容不可以被修改

内存操作函数

内存操作函数遇到0会\0都不会结束操作,而 str 字符串处理函数遇到\0都会结束

memset

将指定内存区域的前 n 个字节设置为特定的值。memset 并不关心数据是否为字符串,它只是简单地设置指定内存块的值.

char buffer[10];
memset(buffer, 0, sizeof(buffer));  // 将 buffer 的前10个字节设置为0

注意memset 只是按字节设置,不会在遇到 \0 字符时停止操作,它会一直设置指定的字节数。

memcpy

将源内存区域的数据复制到目标内存区域,通常用于复制非字符串数据。memcpy 也不关心数据是否为字符串,它只是按字节复制数据。

char src[] = "Hello";
char dest[10];
memcpy(dest, src, sizeof(src));  // 将 src 复制到 dest

注意memcpy 仅复制指定的字节数,不会考虑字符串的终止符 \0

内存泄漏

内存申请,不释放,导致程序使用内存空间一直增长

内存污染

向没有申请过的内存空间写入数据。例如:int * p = 100;p并没有指向的地址。

  • 15
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值