1.取地址运算
&为一元运算符,能够给出变量的存储地址
如scanf中存储变量的值需要用到&
int a=1;
printf("a = %d , &a =%p",a,&a);
地址使用%p进行输出
2.指针简介
指针是一个值为内存地址的变量,普通变量的值是实际的值,指针变量的值是地址,不同类型的指针大小都是一样的
间接运算符:*
p = &a; //指针p指向a
int b = *p; //将p指向变量的值存入b中
*运算符能够利用指针间接引用这个变量,用以表示指针变量所指的变量
*可以做右值也可以做左值
指针的声明
拥有指针变量后,可以通过取地址运算为一个已声明的指针进行赋值
int* p0 = &a; //p0是指向int类型变量的指针
char* p1 = &a; //p1是指向char类型变量的指针
float* p2 = &a; //p2是指向float类型变量的指针
空指针(零指针)
在声明指针时,应尽量对指针进行初始化,若暂时没有变量赋值,应将NULL(0地址)赋予指针,避免空指针的产生
定义零指针可以避免指针变量的非法引用
不同类型的指针无法进行赋值
指针与const
若定义了一个指针为const,表示这个指针一旦得到了某个变量的地址,就不能再指向其他变量
int *const q=&i;
*q=26; //成立
q++; //不成立
即指针固定指向的变量能够进行修改,但指针本身不能进行修改
const int *p=&i;
*p=26; //不成立
i=26; //成立
p=&j; //成立
若这样进行定义,则代表q指针指向的变量无法通过该指针进行修改,但被指向的变量本身并不为const类型的变量,且指针本身能进行修改
总的来说,若const在*之前,代表指针指向的变量无法通过指针进行修改,若const在*之后,代表指针本身无法被修改
3.指针与函数,数组
指针与函数
在函数中,可以通过指针来访问外面变量的值
函数若需要返回多个值,某些值就只能通过指针返回
将数组传入函数时传入函数的是数组的地址,,因此在函数内部可以修改数组的值
指针与数组
数组变量是const的指针,数组变量本身表达地址,而数组单元表达的是变量,数组变量不能被赋值
因此[],*运算符既可以对数组做,也可以对指针做
const int a[]={1,2,3,4,5};
若对数组进行const定义,代表每一个数组单元都被定义为了const,数组内的值无法被修改,所以const数组必须通过初始化进行赋值,这种操作可以在将数组值传入函数时,避免数组内部的值在函数中被修改
4.对指针进行操作
指针的加减
给一个指针进行加(减)1表示要让指针指向下(上)一个变量,指针需要在一片连续分配的空间(如数组)进行这种运算,否则这种运算无意义
实际上指针加减n相当于在指针的地址量上加减n*sizeof(该指针的类型)
指针的强制类型转换
指针也能进行强制类型转换,如:
#include <stdlib.h>
int n;
scanf("%d",&n);
int *a=(int*)malloc(n*sizeof(int)); //动态内存分配
free(a);
在进行数组的动态内存分配时,malloc()函数分配完后会返回一个void*类型的指针,此时需要进行强制类型转换将指针变为对应类型的
5.指针的应用
在函数中,能通过指针进行操作来改变函数外的变量
交换两变量的函数
void swap(int* a,int* b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
将字符插入到字符串中
#include <stdio.h>
#include <string.h>
void insertChar(char* str, char ch, int interval) {
int len = strlen(str);
int newLen = len + (len-1) * interval + 1;
char newStr[newLen];
int index = 0;
for (int i = 0; i < len; i++) {
newStr[index++] = str[i];
if (i != len - 1) {
for (int j = 0; j < interval; j++) {
newStr[index++] = ch;
}
}
}
newStr[newLen - 1] = '\0';
strcpy(str, newStr);
}
int main() {
char str[20];
scanf("%s", str);
insertChar(str, 'm', 1);
printf("%s", str);
return 0;
}
输入一个长度小于20的字符串,将‘m’插入到每个字符之间