基础要好,房子才能盖的牢固,才能盖的高。先把基础补一补,再多刷点算法题看看。
1.c语言指针必须要先赋值才能够使用,不赋值就使用指针的指向是未知的。
2.指针是存放地址的变量。
3.数组名是一个地址,可以直接赋值给指针。
int num[4] = {1,2,3,4};
int *pNum;
pNum = num; //将数组地址值,赋值给指针。
pNum++; //指向数组的指针自加,自加一个元素长度的地址,指向下一个元素。
4.指针与常数加减,都是加减对应的元素。(就是指针+1:指向下一个数组元素,其余加减法也是以元素为最小的符号)
int *pNum2;
pNum2 = pNum+3; //pNum地址值指向数组最后一个元素4。
int count = pNum2-pNum; //结果为3,即num[0]和num[3]之间索引相减。3-0=3;(指针的算术运算只在同一数组内有意义,两个不同数组的指针运算结果不确定,可能会出错)
5.数组在声明之后只能一个一个的赋值,不能直接数组名放在等号左边赋值,因为等号左边必须是变量。
int array[3];
array = {1,2,3}; //这样赋值是错误的。
6.指针的算术加减运算是以指针的类型为基本单元,char指针+1就是加一个字节(char的长度1个字节)。int指针+1就是加四个字节(int的长度4个字节)。如下:
int main(){
char charArr[7]
int intArr[7] =
char *pCharArr;
char *pCharArr1;
char *pCharArr2;
char *pCharArr3;
int *pIntArr;
int *pIntArr1;
int *pIntArr2;
int *pIntArr3;
pCharArr = charA
pIntArr = intArr
pCharArr1 = char
pCharArr2 = char
pIntArr1 = intAr
pIntArr2 = intAr
}
7.c指针数组声明(就是数组元素都是指针)
int *num[3]; //声明一个名字是num的指针数组,数组中有三个int类型的指针元素,(同一指针数组中只能存放统一类型数据,数组中也是一样)
8.指针声明但不初始化时必须要加上数组的长度,指针声明并直接初始化时可以不用加数组长度。
char name[10]; //声明一个长度10个char元素的数组name,声明数组但不初始化必须加数组长度。
char address[] = {"abcdef"}; //声明一个数组并直接初始化,可以不加数组长度。
9.函数形参(指针除外)作用域只在函数内有效,函数间传值用函数返回值传递,或使用指针。
#include
typedef unsigned char uint8_t;
extern void swapdata(uint8_t dat_x,uint8_t dat_y);
int main(){
uint8_t x,y;
printf("请输入x,y:\n");
scanf("%d,%d",&x,&y);
printf("交换前x=%d,y=%d\n",x,y);
swapdata(x,y);
printf("交换后x=%d,y=%d\n",x,y);
}
//函数的形参只在函数内有效,是函数创建的临时变量,离开函数就失效了。无法改变实参的值。
void swapdata(uint8_t dat_x,uint8_t dat_y){
uint8_t temp;
temp = dat_x;
dat_x = dat_y;
dat_y = temp;
}
利用指针传递值,指针是指向数据的地址,指针指向的对应地址中保存着指针(*运算后取值后)的数据。
有点乱不知道怎么解释好了。
#include
typedef unsigned char uint8_t;
extern void swapdata(uint8_t *dat_x,uint8_t *dat_y);
int main(){
uint8_t x,y;
uint8_t *p_x,*p_y; //指针作为中间参数,好像不占有空间,让指针指向x和y。一个数据可以有一个指针,我还以为是重新又创建了一个中间变量,其实不是。一个数据可以创建一个指针指向他。
printf("请输入x,y:\n");
scanf("%d,%d",&x,&y);
p_x = &x; //将指针变量指向x和y。
p_y = &y;
printf("交换前x=%d,y=%d\n",x,y);
swapdata(p_x,p_y);
printf("交换后x=%d,y=%d\n",x,y);
}
//指针类型的参数就是地址,所以使用函数时,传递的是地址。
void swapdata(uint8_t *dat_x,uint8_t *dat_y){
uint8_t temp;
temp = *dat_x;
*dat_x = *dat_y; //将指针指向的数据,赋值给另外一个指针指向的数据。
*dat_y = temp; //同理,给指针参数赋值。
}
10.主函数需要将实参作为指针传递给被调用函数,被调用函数才可能改变实际参数。
void test(int *arg1,char *arg2); //像这样的函数,参数是指针。
11.数组名是地址,可以将其直接赋值给指针。如下
int arr[] = {1,2,3}; //数组名arr是个地址
int *p_arr; //*后面指针名也是个地址,(*地址)声明一个类型的指针。
p_arr = arr; //完成指针初始化,将指针指向数组首地址。
12.结构体中有数组的话,声明结构体时不用再另外加括号。按照顺序声明每个数据即可。
(结构体数组,一个数组里面都是结构体,哈哈哈,结构体里面还可以再有数组,无限套娃。)
typedef struct
{
uint8_t data;
uint8_t name;
uint8_t someData[DATA_MAX]; //这是个结构体中的数组。声明时直接按照元素索引顺序排列即可,无需另外加括号,结构体就是一段连续的存储单元,存储着一组数据。
uint8_t age;
}MY_OWN_STRUCT;
//声明结构体数组
MY_OWN_STRUCT my_struct[STRUCT_MAX] = {
{0x11,0x12,0x13,0x13,0x13,18},
{0x22,0x13,0x14,0x14,0x14,25},
{0x33,0x14,0x15,0x15,0x15,50}
};
uint8_t test = mystruct[1].data; //调用结构体中数据
uint8_t arr = mystruct[2].someData[1]; //调用结构体中的数组元素
13.普通变量作为函数参数传递时,把实参的值传递给形参,也就是说形参值是实参值的拷贝,形参和实参虽然是同样的值,但存储在不同的内存空间中。在被调用函数中,是对形参的操作,而对实参没有进行任何操作。普通变量作为函数参数时,实参值不会进行变化。而指针变量作为函数参数时,通过指针变量的值传递,是让形参指向实参变量指向的变量,通过指针变量的值传递后,形参变量和实参变量指向同一个变量。所以,在被调用函数中,对形参的操作,就是对其指向变量的操作。