指针变量的初始化
int a;
int *p=&a;
int * *q=&p;
(q)=a;
访问一维数组的,指针一般在32位机占4个字节,在64位机占8位字节。
const:constant常量的意思
如果 在一个变量前面放一个const,表示变量只读,不可更改,在定义的时候就要初始化,后面不可再赋值。
const int a =9;
int const a =9;////两种写法一样。
const 用到指针上
int a=9;
const int *p=&a;
*p=2;/////这句话会出错,因为*p不能再更改
int a=9;
int b=8;
int *const p=a;
p=b;和上一句不同的是,这句话是p不能更改,
int a=9;
int b=8;
const int *const p=&a;///*p和p都不能更改
数组
- 数组是本身是不能更改地址的
arr=arr+1;//这样就好像是要改变arr地址一样,是错误的。
指针数组
int a ,b ,c
int *p[3] = {&a,&b,&c};数组里面的都是指针。
*(p[0]) = 7;对数组的第一个元素指针所指向的a进行更改。
运算符的优先级
Paste_Image.png
二维数组
-
初始化:int arr[ 2 ] [ 3 ] = { { [ 1 ] = 4 } , { [ 2 ] = 2 } } ;可以在后面赋值。一般二维数组,定义的时候就给它初始化
-
二位数组可以省略行号,但是 不能省略列号。
int arr[][ 2]={ 2, ,43, 5,};可以
iint arr[2][]= { 432, 64, 7, 2,};不可以
二维数组的第i行第j列的访问
- 第i行首元素的地址:&arr[i][0]===>arr[i]===>*(arr+i)===>arr+i//最后那个指向的是一行元素的地址
- 第i行第j个的元素地址:&arr[ i ] [ j ]===>arr[ i ]+j===>*(arr+i)+j
- 第i行第j个的元素:arr[i ][ j ]===>* ( arr [ i ] + j )===>*( *( arr+i ) +j )
数组指针也叫行指针
int arr[2][ 3]={ 1,2,3,4,5,6};/////arr指向一行的地址
int (*p)[ 3]=arr;////这里的p指向一行,不是一个元素。
函数
- 需要注意的是如果函数是char,int,float,double类型的话,必须有return,而且return后必须接与函数类型相同的变量或者常量。
- void后可以没有return,如果有的话,return后什么都不加。
- 调用函数的时候:函数名+(和函数里面的格式相同)
#include<stdio.h>
void haha(int *p,int *q)/////小括号里面的是形参:形式上的参数,
{
int temp = *p;
*p = *q;
*q = temp;
}
int main()
{
int a=0,b=6;
haha(&a,&b);////括号里面的是实参:函数调用的时候用的。
printf("a= %d,b= %d",a,b);
return 0;
}
全局变量和局部变量(按照作用领域分)
- 全局变量一般都是在函数外面,调用 函数的时候可以改变全局变量。
- 局部变脸在函数里面。
静态变量和自动变量(按照生存期分)
- 静态局部变量和静态全局变量
- 自动局部变量和自动全局变量
static,静态函数修饰
- 栈区:存放的内容可以进行更改,(转到字符串那里,对应)
- 文字常量区:常量字符串(内容太只读不可更改)
函数指针
实际上函数指针和函数名都指向同一个入口地址,不同就是函数指针是一个指针变量,不像函数名称那样是死的,它可以指向任何函数。
int (p )(int )=swap;///第一个int指的是swap是int型的函数,第二int指的是形参是int类型,p代表 一个指针变量
数组的调用
#include<stdio.h>
void swap(int *p,int size)
{
int i=0;
for(i=0;i<size;i++)
{
printf("arr[%d]=%d\n",i,p[i]);
}
}
int main()
{
int arr[]={1,2,3,4,5,6};
int size=sizeof(arr)/sizeof(int);
swap(arr,size);
// printf("a=%d\n",a);
return 0;
}
指针函数:主体是个函数,函数的返回值是个指针,函数类型的指针。
字符串
字符串的初始化
- 字符串的初始化:char zifu[4]= {'q','e','f' ,'\0'},注意最后一个必须是‘\0’,要不然就是字符数组了。
- char zifu[10] = {"hello"};======>char zifu [10] = "hello ";
- char p = " hello ";其指向*文字常量区,内容不可更改,不能使用strcpy()。
- 打印字符串用%s。不是%c。如果字符串里面有\0,那么以后的东西都不用打了。
- strlen(字符串名)可以计算\0之前的字符,需要头文件include<string.h>
- strcpy(字符串1,字符串2);把字符串2拷贝到字符串1,删除字符串1.左边的字符串的大小应该大于右边的字符的大小,它也需要头文件include<string.h>。
字符串的一些应用函数
- strlen(字符串名)可以计算\0之前的字符,需要头文件include<string.h>
- strcpy(字符串1,字符串2);把字符串2拷贝到字符串1,删除字符串1.左边的字符串的大小应该大于右边的字符的大小,它也需要头文件include<string.h>。
- strcmp();,比较两边的字符串两边的大小。
int result = strcmp(zifu,zifu2);
printf("result=%s\n",result);
- strcat(字符串1,字符串2);把右边和左边的连接到一起。注意左边的字
符串足够大。
strcat(zifu,zifu1);
printf("zifu=%s\n",zifu);
自己制作一个mylength的命令,用函数完成
#include<stdio.h>
#include<string.h>
int mylength(const char *string)
{
int length=0;
while(*string !='\0')//////注意string前面的*不要缺少。
{
length++;
string++;
}
return length;
}
int main ()
{
// char zifu1[3] = "ok";
char string[10]="hello";
//char *string="hello";这个位置用指针和用字符串都可以。
int length=0;
// char zifu2[10] = "hello";
// char *p = "hello";
// int i;
length = mylength(string);
// strcpy(zifu1,zifu);
// printf("zifu1 = %s\n",zifu1);
// printf("*p = %p\n",p);
// printf("zifu = %s\n",p);
// long int length = strlen(zifu1);
// int result = strcmp(zifu,zifu2);
// strcat(zifu,zifu1);
// printf("zifu=%s\n",zifu);
printf("length=%d\n",length);
return 0;
}
- strncmp(字符串1.字符串2,要比较的字符串长度)比较两个字符串的大小,感觉没什么意义。
- strncpy(字符串1,字符常量,字符个数)替换字符串1的内容。
- strncat(字符串1,字符串2,字符个数),连接连个字符。
- 字符串输入:scanf(" %s",str1);它只会吸收空格之前的字符,不包括空格。
字符串数组
- 初始化char str[2] [10] ={"hello" ,"world"};
- char * str1[2] = {123,nihao};相当于指针数组::char *p="123";
char *p1="nihao", char *str1[2] = {p,p1};
结构体
- 结构体,可以将不同种类数据结合到一起的集合。
- struct {
属性变量:特征变量
};
#include<stdio.h>
#include<string.h>
int main()
{
struct person
{
char name[10];/////1.如果结构体的里面的成员变量
都是基本的数据类型,那么第一成员变量内存从内存偏移量为0的位置。
2.如果结构体成员里是 集合类型,比如数组,结构体,枚举。。
那么成员变量按照其本身算。:char sex[3]:它的里面就是三个字节
3.总的字节数是最大成员变量字节数的倍数 。
char sex;
int height;
float score;
};
struct person man;
man.sex='m';
strcpy(man.name,"xxxx");///第一种初始化
printf("man.sex=%c\nman.name=%s\n",man.sex,man.name);
struct person man1={"xx1",'w',12,123.0};第二种初始化
printf("name=%s,sex=%c\n",man1.name,man1.sex);
return 0;
}
如何计算struct所占的字节。
Paste_Image.png
结构体嵌套
#include<stdio.h>
#include<string.h>
int main()
{
struct birthday
{
int year;
int month;
int day;
};
struct person
{
char name[10];
char sex;
struct birthday birth;
};
struct person man;
struct person man1={"xx1",'w',{2016,10,20}};
printf("name=%s,sex=%c\n,birthday=%d,%d,%d\n",man1.name,
man1.sex,man1.birth.year,man1.birth.month,man1.birth.day);
return 0;
}
无名结构体
struct
{
int a;
char b;
}xxxx;在定义的结构体的时候就把他的名字定一出来,跟在后面。
指针结构体
int main()
{
struct person
{
int height;
char sex;
};
struct person man;
struct person *p = &man;
(*p).sex='w';
(*p).height=123;
printf("person.height=%d\nperson.sex=%c\n",man.height,man.sex);
p->height=333;
p->sex='w';
printf("person.height=%d\nperson.sex=%c\n",man.height,man.sex);
return 0;
}
重命名typedef
- typedef+要改变的类型+改变后的名字。可以放在include下面,全局有效。
int main()
{
typedef struct student
{
char name[10];
int num;
}student;////把struct student命名为student。
student stu = {"xxx",10};
printf("name = %s\n num=%d\n",stu.name,stu.num);
return 0;
}
结构体数组
#include<stdio.h>
#include<string.h>
typedef struct student
{
char name[10];
int num;
}student;
int main()
{
int i;
student stu[2]=
{
{"xxa",213},
{"xxb",311}
};
for(i=0;i<2;i++)
{
printf("stu[%d]name = %s\n num=%d\n",i,stu[i].name,stu[i].num);
}
return 0;
}











网友评论