目录
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;
}
① 程序运行至 char *tmp = (char *)malloc(100);
② 程序运行至 strcpy(tmp, "adlsgjldsk");
③ 程序运行至 *p = tmp;
④ 程序运行至 *len = strlen(tmp);
2.2 一级指针(char*)易错地方
2.2.1 对空字符串和非法字符串的判断
void copy_str(char *from, char *to)
{
if (*from == '\0' || *to == '\0') // 正确的为 if (from == '\0' || to == '\0') 地址是否为空
{
printf("func copy_str() err\n");
return;
}
for (; *from!='\0'; from++, to++)
{
*to = *from;
}
*to = '\0';
}
2.2.2 越界
2.2.3 指针的叠加会不断改变指针的方向
char *getKeyByValue(char **keyvaluebuf, char *keybuf)
{
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++);
z--; /*去掉串尾结束标志*/
while(*z++=*y++);
z=str; /*将str地址赋给指针变量z*/
return(z);
}
2.2.5 函数内使用辅助变量的重要性
int getSubCount(char *str, char *substr, int *mycount)
{
int ret = 0;
char *p = str;
char *sub = substr;
if (str==NULL || substr==NULL || mycount == NULL)
{
ret = -1;
return ret;
}
............
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));
#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;
}
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);
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;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)