c语言是按照顺序执行的,c语言是面向过程的语言
字符串:
1)如何定义:
char *str1 = "hi";
char str2[] = "hi";
char strArr1[] = { 'h', 'i' };
char strArr2[] = { 'h', 'i', '0' };
char strArr3[] = { 'h', 'i', '\0' };
2)字符串以"\0"结束
3)相关函数
strlen :遍历,然后'\0'结束
strcpy :*(dist++) = *(src++)
*(src++) :++后取值
*号不一定是常量,也可能是指针
函数:
声明:没有函数体
void(int,int) 形参可以写也可以不写
写了函数声明,不一定要写函数定义,可以直接写函数定义。
.h: 头文件
只有函数声明
.c: C语言的源文件
.cpp;
C++的源码文件
头文件+C++的源码文件
.hpp:
定义:有函数体
参数:
函数调用,传参的本质,压栈
ebp : 新的栈帧的尾部,通过栈帧尾部拿到参数。
默认参数
java没有默认参数
占位参数:
函数重载
1)函数名相同,
2)参数类型,个数,顺序 一样
3)
函数指针
和指针函数
指针:
大学:指向内存的地址
符号:
* 定义指针
& 解引用,取地址符号【引用】
-> 指针访问数据
. 指针访问数据
指针的声明:
int *
char *
指针的大小:
固定长度,和操作系统的位数有关,
int * 32位 4bit 64位8bit
char * 32位 4bit 64位8bit
指针的使用:
*
int a = 0X11223344
char *cp = (char *)&a;
printf("%X",*cp) 输出为44
a在内存中的存储是 44 33 22 11 ;小端存储
总结一下:
1) 不要把内存当成内存
2)如果是char * ,就相当于一个字节一个字节获取
3)如果是int *,就相当于四个字节四个字节的获取数据
三种指针类型:
1)空指针 NULL
int *a= NULL
2)野指针
指针的地址已经被释放了
3)空类型指针
void *a 能指向任何数据类型
1、指针常量:const修饰常量(指针指向不可以改,指针指向的值可以改)
2、常量指针:const修饰指针(指针指向可以改,指针指向的值不可以改)
3、修饰指针 + 修饰常量(指针、指针指向的值都不能修改)
操作系统的内存模型:
堆
栈
代码段
全局区域
char * //不可修改的 ,因为存储在只读的内存页
什么时候释放:
程序结束的时候释放
数组 :
char name[] = "ziya";
如果想输出i,可以使用 printf("%c\n",name[i]) 或 printf("%c\n",*(name+1))
name是数组的内存首地址
printf("%c\n",*name+1 )输出的是z 后面的第一个 {
c语言常见的几种指针用法
1、指针指向变量:
下面有这样一个代码块:
-
#include <stdio.h>
-
void test(int x,int y)
-
{
-
int tmp;
-
tmp=x;
-
x=y;
-
y=tmp;
-
}
-
int main()
-
{
-
int a=10;
-
int b=15;
-
test(a,b);
-
printf("a=%d,b=%d\n",a,b);
-
return 0;
-
}
最后输出的结果还是a=10,b=15。因为在函数调用时,实参和形参之间只是值传递。但我们使用指针结果就不一样了,如:
-
#include <stdio.h>
-
void test(int *x,int *y)
-
{
-
int tmp;
-
tmp = *x;
-
*x = *y;
-
*y = tmp;
-
}
-
int main()
-
{
-
int a = 10;
-
int b = 15;
-
test(&a,&b);
-
printf("a=%d,b=%d\n",a,b);
-
return 0;
-
}
输出结果a=15,b=10。变量a和b的值发生了交换。这是因为我们利用指针访问变量的存储单元,间接修改变量的值。
2、指针指向数组:
定义一个数组并初始化,int array[5]={2,5,12,7,8},定义一个指针变量并把数组的地址赋给它,int *p=array,注意数组名就是数组的地址,而且数组的地址就是首元素的地址。因此我们的指针变量就指向了数组的首元素,*p=2。如果把(p+1),那么指针变量就指向了数组的下一个元素5,因此我们可以利用指针来遍历数组的各个元素:
-
#include <stdio.h>
-
int main()
-
{
-
int array[5] = {1,2,3,4,5};
-
int i;
-
int *p = array;
-
for(i = 0; i < 5; i++)
-
{
-
printf("array[%d]=%d\n",i , *(p+i));
-
}
-
return 0;
-
}
3、指针指向字符串:
我们都知道用数组存储字符串,如char name[10]="jack",上面已经简单讲述了指针指向数组,所以我们可以这样做,char *name="jack",指针变量指向字符串的首个字符并可以依次访问字符串的各个字符。
4、指针指向函数:
我们需要知道怎样表示一个指针指向函数,说白了就是语法要正确,下面我也取一个代码块来说明一下:
-
#include <stdio.h>
-
int sum(int x,int y)
-
{
-
return x+y;
-
}
-
int main()
-
{
-
int a = 5;
-
int b = 6;
-
int (*p)(int,int);
-
p = sum;
-
int result = (*p)(a,b);
-
printf("The result is %d\n",result);
-
return 0;
-
}
不难发现上面代码块里语句(*p)(a,b)可以用p(a,b)来代替,因为p和sum就是一样的,只是用前者可能更容易理解一点。而我们要知道怎样定义一个指针指向函数,int (*p)(int,int)这是固定写法,前面的int是指针将来指向的函数的返回值的类型,如果没有函数返回值,那就是void,后面括号里的两个int 当然就是指针将指向的函数的形参。指针指向函数用起来确实有点抽象,要想熟练运用的话就多去做一些这方面的练习吧!
5、指针指向结构体:
我们首先首先定义一个结构类型,
-
struct student
-
{
-
char *name;
-
int ages;
-
};
再根据类型定义结构体变量 struct student stu={"Rose",15};定义一个指针指向结构体类型,struct student *p;把结构体变量stu的地址赋给指针变量p,p=&stu;我们可以有3种方式来访问结构体中的属性ages:
stu.ages=15;
(*p).ages=15;
p->ages=15;
不过第三种方式在C语言中只能用来指向结构体。
综上所述,指针的基本用法就是这几种,还有些用法不常见的小编在此就一一例举了,有兴趣的话可以去翻阅相关的资料。