注:通过xshell实现对liunx系统等的远程链接
c语言数组
1.
一维数组的初始化和遍历
初始化的方法:
①全部初始化 //例 int a[8]={1,2,3,4,5,6,7,8};
②局部初始化 // 例: int a[10]={0,1,2,3,4,5,6,7}
③全部初始化不指定下标,系统根据元素个数自动确定大小 // 例: int a[]={1,2,3,4,5,6,7,8,9} 则相当于a[9]
注:局部初始化没有赋值的元素自动赋值为0
数组大小等于 数组内元素个数*数组类型
数组内元素个数=数组大小/数组第一个元素 (变相求个数,通过sizeof实现)
如果在数组内部定义一个数组不去初始化,那么每一个元素都是初始值
int a[5]={0}; 相当于把a中的五个元素全部定义为0
一维数组的遍历
for(i=0;i<sizeof(数组名)/sizeof(数组里第一个元素如a[1]);i++)
printf("%d ",a[i]);
for循环遍历
sizeof求数组大小
putchar(10):向终端输出一个ASCII码为10的字符,换行
注意:数组序数从0开始,所以最大编号为n-1,即a[10]第一个元素为a[0],最后一个元素为a[9]
排序:
冒泡排序
别名交换排序,从一边开始从小到大或者从大到小比较,满足规则就进行交换,(规则基本上为大于或小于)
需要两个for循环
for 大循环,控制整体比较多少次
for 小循环,控制本次比较中,进行多少次比较/交换
循环内部:一个数比它后一个数大/小时,交换可以选择新建一个元素n暂时存放数据,或者见下
sizeof(数组名)/sizeof(数组名[第一个元素])
二维数组:
存储类型,数据类型,数组名,下标两个[行数][列数]
命名规则:
int a[3][4];
遍历需要两个for循环
外循环控制行数 ,内循环控制列数
按行存储,没有初始化的自动补0
相当于n个行的集合
列数必须写,行数可以不写
不写行数计算机会想办法自动识别,不写列数计算机无法判断到底有几行
遍历循环外层控制行数,内层控制列数
三:字符数组,字符串
字符串本质也是一个字符数组
字符数组:数组里每一个元素都是字符
字符串的逆序:
实现原理如下:
向一个字符串插入数据:
指针对字符串的处理
字符串函数(系统提供的)
①: 为什么要是使用字符串函数
一般字符串都保存在一个数组里面,但数组定义好之后,无法直接进行整体操作,所以会借助字符串函数来对字符数组进行操作
直接用数组名,相当于使用数组首地址
而不是使用内容
数组如果没有初始化,就必须写下标指定大小
常用字符串函数
strlen man strlen
头文件 string.h 字符串处理函数常用头文件
原型 size_t strlen(const char *s);
功能 获取一个字符的长度
参数 s:要获取长度的字符串
直接传入一个字符串或者数组名均可
只获取字符串长度,遇到\0就停止,\0不计入内
但sizeof会计算字符串的\0
sizeof和strlen的区别:
sizeof主要用来内存空间分配大小,是关键词,标识符,
strlen仅用来看字符串长度,是一个库函数
一个侧重长度,一个侧重空间
返回值: 字符串长度
②strcmp
头文件:同上
原型:int strcmp(const char *s1,const *s2);
功能:比较两个字符串的内容,大小,
参数为要比较的两个字符串
只是对两个字符串进行比较然后返回值,不对字符串内容做修改
返回值:
0 s1和s2相等
>0 s1大于s2,返回多少说明s1和s2第一个不相同的字符差值是多少,<0的也是
<0 s1小于s2
strcmp比较的是\0之前的内容,与字符串所在内存空间无关
一直比较,直到遇见不相同的,比较该位后立即停止,后面的不进行继续比较
如果两个字符串前面的相同,后面的一个没了,那么会拿\0和另一个字符串比较
strncmp : 比较字符串前n个字节大小
strncmp(数组1,数组2,n的值) strcmp(a1,a2,4)即为比较a1和a2前4个字符大小
strcpy:
复制函数
头文件同上
char *strcpy(char *dest,const char *src);
strcpy(字符串1,字符串2)
将字符串2 的内容拷贝到字符串1 中
返回值为目的字符串的首地址,
字符串1里面就算有内容也会被覆盖,原字符串比复制过来的长也会被覆盖,后面的不会继续显示,(\0也会过来)
strncpy(只拷贝字符串2的前n位到字符串1中),但是这样的没有\0,如果字符串1原长度比n长,仍然会显示后面的内容
strcat()函数
头文件同上
把字符串2粘到字符串1后面,需要s1足够长
粘贴字符串2中的内容直到遇到第一个\0
遇见s1中第一个\0后开始拼接,也就是说字符串1和字符串2第一个\0后面的内容都无法显示
但用for循环可以遍历出来字符串1后面的内容
#include <stdio.h>
#include <string.h>
int main(int argc, const char *argv[])
{
char s1[32] ="hello wo\0rldadadjajdalsdkjaskdj"; //hello woabcdefg\0
char s2[32] ="abcdefg\0higk";
strcat(s1,s2);
printf("s1 = %s\n",s1);
return 0;
}
strcpy手动实现:
原理:循环拷贝,依次装填
指 针
用途:
使用程序紧凑高效
可以有效表达数据结构
用来动态分配内存
得到多于一个函数返回值
概念:
当程序中定义一个变量之后,程序就会为这个变量分配内存空间,我们内存空间中每一个字节都有自己的编号,将这个编号称之为地址,也叫作指针
在不影响理解的情况下,有时对地址,指针,指针变量不区分,统称指针,
最终目的:找到需要的变量
如果前面是一种类型,表示这是一条定义语句,定义一个指针变量
*pa=&a
地址在32位操作系统中占4个字节,64位占8个字节,不论什么类型的指针,指向所指向的地址
在使用时,*pa=100;
表示取指,取指针pa指向的内存的值
-m32 以32位编译输出(gcc语句最后面加)
不同类型的指针,步长不一样
指针变量的运算:
是以指针变量所存的地址量作为运算量而进行运算的
实质就是地址的运算
只能进行算数运算,关系运算,赋值运算
指针变量加减表示指针变量向地址大或小的方向进行移动,移动n个操作空间
指针算数运算符:
两个指针相减表示两个地址之间的操作空间(也就是几个元素)
注:两个指针做运算必须是同类型指针,类型不同,无意义
一个指针变量加减意义,乘除无法计算,没有意义
后置++优先级高于前置++
后置的结合律从左往右,
前置和*优先级相同,结合律从右往左
关系运算符:
< > >= <= != --
两个指针变量可以通过通过关系运算符来判断保存地址的大小
指向两个不同数据区域的数据两个指针之间进行关系运算,也没有意义
指针与一般整数变量之间的关系运算,也没有意义
但是可以和0去比较是否相等
判断指针是否为空,一般会让其与NULL相与
指向地址大的指针大于指向地址小的指针
6.2.3 赋值运算符
指针变量之间可以直接赋值,但是不能将一个整数赋值给指针变量,因为没有开辟空间
指针赋值运算:通过赋值运算符将指针变量送一个地址值
例:
输入一个字符串,通过指针将字符串元素翻转
要求:定义两个指针,分别保存起始位置和末尾位置字符,通过交换的方式实现
#include <stdio.h>
#include <string.h>
int main(int argc, const char *argv[])
{
int a[5] = {1,2,3,4,5};
int *p = a;
int i;
for(i = 0 ; i < 5;i++)
{
//printf("%d ",a[i]);
printf("%d ",*(p+i));
}
putchar(10);
char *s = "helloworld";
char str[32] ="hello nanjing";
s = str;
//printf("%s\n",s);
for(i = 0 ; i < 10;i++)
{
printf("%c",s[i]);
}
putchar(10);
return 0;
}