字符串数组和字符串的传参
char str[32] = {"hello world"};
int fun(char *pstr);
// 字符串遍历
while( str[i] != '\0')
{
i++;
}
while(*p != '\0')
{
p++;
}
int MyStrcp(char* pdst,char *psrc)
{
while( *psrc != '\0')
{
*pdst = *psrc;
pdst++;
psrc++;
}
*pdst = '\0';
return 0;
}
int main(void)
{
char pdst[32] = "hello";
char psrc[32] = "world";
MyStrcp(pdst,psrc);
fputs(pdst,stdout);
return 0;
}
char *str = "hello";
char *srr = "world";
使用指针存在问题是因为指针所指向的字符串是一个字符串常量,通常存储在只读的内存区域中。在C语言中,字符串常量是不可更改的,任何试图修改它们的操作都是未定义的行为。
二级指针
指向一级指针变量的指针
void * 指针 缺省类型指针
void * -> int * char *、double * 不需要强制类型转换
int 、 char *、double -> void * 需要强制类型转换
void *memcpy(void *dest, const void *src, size_t n);
void * 作为函数参数,可以传递char *,double *、int *的指针,实现一个函数下的不同类型指针传参
const 指针
readonly 只读
1 const int *p;
2 int const *p;
3 int * const p;
4 const int *const p;
5 int const *const p;
1和2是等价的 const 修饰*p 不能变,p可以改变
3const 修饰p p不可以改变,但是*p 可以改变,这一定要初始化,不然一直是野指针;(比如数组的数组名)
4 和 5 const 修饰 p ,也修饰 *p,值和地址都不能变;
char *strcpy(char *dest, const char *src);
char str[] = {"hello world"}; // 定义数组
char *p = "hello world"; // 定义指针,指向字符串常量,不可以改值
// const char *p ="hello world";
str = "how are you" // 错
p = "how are you" // 可以,改变指向
*str = 'H'; // 对
*p = 'H'; // 错
数组指针和指针数组
数组指针是指针,指针指向整个数组
int a[5] = {1,2,3,4,5};
int (*p)[5] = &a;
a可以理解为int *,但在下面两种情况不能理解为int *型
1.sizeof();
2.& 操作
&int * == int **
&a == int(*)[5] // &a+1 40个字节
a == &a 首地址相同,但是不同类型
对数组名字取地址得到指向整个数组的数组,值不变,类型升级为指向整个数组的数组指针
对数组指针*,值不变,类型降级为指向第一个元素的指针 *&a
**p == 1 *(*p + 1) == 2 // a本身是地址 &a 两个访问
- *p 是指向整型数组的指针,再加一个 * 表示获取指针指向的数组的第一个元素的值。因此,**p 的值应该是数组的第一个元素,即 a[0],也就是 1。
- *(*p + 1) 表示指针 p 指向的数组中的第二个元素的值。首先 *p 是指向整型数组的指针,然后 *p + 1 表示数组的第一个元素的地址加一,即指向数组的第二个元素。最后再加一个 * 表示获取指针指向的数组的第二个元素的值。因此,*(*p + 1) 的值应该是数组的第二个元素,即 a[1],也就是 2。
2. 指针数组
指针数组是数组,数组的每个元素都是指针
int *a[5] : 定义一个数组,数组名为a,有5个元素,每个元素为int * 型
char *pstr[7] = {"Monday","Tuesday","wed","thus","fir","sat","sun"};
char str[7][32] = {"mo","thus" ........};
第一个定义的都是常量