64位编译器:
char :1个字节
char*(即指针变量): 8个字节
short int : 2个字节
int: 4个字节
unsigned int : 4个字节
float: 4个字节
double: 8个字节
long: 8个字节
long long: 8个字节
unsigned long: 8个字节
注意数组越界
输出数组a中有多少个元素: sizeof(a)/sizeof(a[0])
数组名 = 数组首地址 = 数组第一个数据的地址
数组传参时main函数向其他函数中传递数组的首地址和数组的个数(sizeof(array)/sizeof(array[0]))
,该地址在Linux中占8个字节,之后就可在函数中遍历数组。
指针变量:存放地址的变量
指向谁 偏移后指向谁
定义指针变量为指针标识符//其余为运算符
地址强制保存 int* a = (int *)0xfe;
*a = 520;
指针数组
多变量的地址的集合 存放地址的变量
是一个数组,数组的每一个元素是指针(指针的数组)
int* parray[3];
数组指针 int (*p)[x];
指向某个数组,指向数组首元素地址
指向数组的指针偏移时偏移的是整个数组的大小 类型x数组长度的长度
函数指针 void (*p)() {};
这里给一下关于地址错误的代码:
#include
int main()
{
int i = 10;
int *p = &i;
printf("i = %d\n",i);
printf("i = %d\n",*p);
printf("i的地址为:%d\n",&i);
printf("p的地址为:%d\n",p);//printf("p的地址为 %d\n",&p);
printf("i和p的地址一样都为 %d",&i);//偏移12位
return 0;
}
函数指针格式要求很强(参数类型,个数,返回值)
p = 【函数名】;
p()直接调用//(*p)();取内容,再调用
开辟 malloc(n * sizeof(int));
多次调用malloc所分配的地址不能有重叠部分,除非某次malloc所分配的地址被释放掉
malloc应该尽快完成内存分配并返回(不能使用NP-hard的内存分配算法)
内存大小调整 realloc
malloc申请的空间,程序不会主动释放。Linux中的话,程序结束后,系统会回收这个空间。使用free/p=NULL;
可以直接定义 “abc”或者‘a’
char *array = "xxx";
易造成段错误
字符串在内存中,除了有效字符外,还会自动在结尾处补一个’\0’,作为结束标志。
不能用sizeof来计算字符串中有效字符的个数!
常用strlen,他在计算字符串大小时,遇到’\0’就会结束计数。
指针标识字符串时,先定义,然后malloc开辟空间(注意内存泄漏问题),最后memset初始化元素:
char *p;
p = (char *)malloc(128);
memset(p,'\0',128);
malloc开辟空间也可能会失败,可以用返回值做判断:
if(p = NULL){
exit(-1);
}
char *strcpy(char* dest, const char *src);
参数:dest为目标字符串,src为原字符串。
返回值:目标串的地址。
例:
char strDest[128] = {
'\0'};
char *strSrc = "li";
strcpy(strDest,strSrc);
如果想要继续使用strcpy来复制字符串到strDest,则需要重新初始化数组:
memset(strDest,'\0',sizeof(strDest)/sizeof(strDest[0]));
strcpy(strDest,"li is handsome");
///分割线
char *strncpy(char *destinin, char *source, int maxlen);
参数:destinin:表示复制的目标字符数组;source:表示复制的源字符数组;maxlen:表示复制的字符串长度。
例:
strncpy(strDest,"x",5);
puts(strDest);
strcpy只是复制字符串,但不限制复制的数量,很容易造成缓冲溢出。strncpy要安全一些。 strncpy能够选择一段字符输出,strcpy则不能。
char *strcat(char *dest, const char *src);
功能:把src所指向的字符串(包括“\0”)复制到dest所指向的字符串后面(删除dest原来末尾的“\0”)。
要保证dest足够长,以容纳被复制进来的*src。*src中原有的字符不变。返回指向dest的指针。
例:
char strDest[128] = "123456";
char *strSrc = "xxx";
strcat(strDest,strSrc);
puts(strDest);
int strcmp(const char *s1,const char *s2);
strcmp函数是string compare(字符串比较)的缩写,用于比较两个字符串并根据比较结果返回整数。
基本形式为strcmp(str1,str2)
,若str1=str2,则返回零;若str1
两个字符串自左向右逐个字符相比(按ASCII值大小相比较),直到出现不同的字符或遇’\0’为止。
例:
char *str1 = "123";
char *str2 = "123";
判断两字符串是否一样:
if(!strcmp(str1,str2)){
printf("两个字符串相同\n");
}
char *strchr(const char *str, char c)
参数:str-要被检索的 C 字符串。c-在 str 中要搜索的字符。
功能:在参数str所指向的字符串中搜索第一次出现字符c(一个无符号字符)的位置。
返回值:返回一个指向该字符串中第一次出现的字符的指针,如果字符串中不包含该字符则返回NULL空指针。
例:
char *str = "abcd";
char c = 'h';
char *p = NULL;
p = strchr(str,c);
if(p == NULL){
printf("没有找到\n");
}else{
printf("找到\n");
puts(p);
}
strstr()
函数用来检索子串在字符串中首次出现的位置,其原型为:
char *strstr( char *str, char * substr );
函数参数:str参数为要检索的字符串,substr参数为要检索的子串。
函数返回值: 返回字符串str中第一次出现子串substr的地址;如果没有检索到子串,则返回NULL。
例:
char *substr = "hen";
char *p = NULL;
p = strstr(str,substr);
puts(p);
strtok字符串的分割 :char *strtok(char *s, char *delim);
例:
char str[] = "li,zhe,zhe,hello,world";
char *p = NULL;
p = strtok(str2,",");
puts(p); //获取到的第一个子串
p = strtok(NULL,",");
printf("获取到第二个串:p=%s\n",p);//获取到的第二个字串
如果p==NULL,说明后续没有子串了。
获取子串并将其存储在指针数组中:
char str2[] = "li,zhe,zhe,hello,world";
char *p = NULL;
char *psubs[10];
int i =1;
p = strtok(str2,",");
if(p!=NULL){
//printf("获取到第一个串p=%s\n",p);
psubs[i-1] = p;
}
while(1){
i++;
p = strtok(NULL,",");
if(p != NULL){
// printf("获取到第%d个串p=%s\n",i,p);
psubs[i-1] = p;
}else{
printf("没有子串了\n",p);
break;
}
}
int j;
for(j=0;j<i;j++){
puts(psubs[j]);
}
``
转为小写函数:strlwr
转为大写函数:strupr
————gets:
int mygets(char *p)
{
int ret = 0;
if(p == NULL){
return;
}
while((*p=getchar()) != '\n'){
ret++;
p++;
}
return ret;
}
————puts:
void myputs(char *p)
{
while(*p != '\0'){
putchar(*p++);
}
putchar('\n');
}
————strlen:
int mystrlen(char *p)
{
int cnt = 0;
while(*p++ != '\0'){
cnt++;
}
return cnt;
}
————memset:
void mymemset(char *p,char c,int size)
{
while(size){
*p++ = c;
size--;
}
}
————strcpy:
char *mystrcpy(char* dest, char *src)
{
if(dest==NULL || src==NULL){
return NULL;
}
while(*src != '\0'){
*dest++ = *src++;
}
*dest = '\0';
return dest;
}
————strncpy:
char *mystrncpy(char* dest, char *src, int maxlen)
{
if(dest == NULL || src == NULL){
return NULL;
}
while(*src != '\0' && maxlen >0){
*dest++ = *src++;
maxlen--;
}
*dest = '\0';
return dest;
}
————strcat:
char * mystrcat(char *dest, char *src)
{
while(*dest != '\0'){
dest++;
}
while(*src != '\0'){
*dest++ = *src++;
}
*dest = '\0';
return dest;
struct data{
char* name;
int score;
};
struct data data1;
字符串用ctrcpy赋值:strcpy(stu1.name,"lizhe");(
先开辟空间)
限定结构体变量作用域只在这个文件,防止别的文件有相同文件名而导致出现错误
结构体指针
struct data *p;
p = (struct data *)malloc(sizeof(struct data));
p->name = "lizhe";//错误
strcpy(p->name,"lizhe");
注意结构体指针的偏移 偏移的是整个结构体大小
写函数:
struct student* getmes()
{} 不需要返回值也可以
如果要找一个人
int FindSomeone(struct data *p,char *name)
{
int i;
for(i=0;i<128;i++)
{
if(strcmp(name,p->name) == 0)
{
return 1;
}
p++;
}
return 0;
}
结构体大小计算:自行参阅
https://blog.csdn.net/chenlichenforlinux21/article/details/89950075
https://blog.csdn.net/chenlichenforlinux21/article/details/103311310
typedef:为了代码编写简洁
char 能表示2的8次方
int 能表示2的32次方
double float 根据环境
4种数据类型0——128都可以表示
例:
typedef unsigned int u_int8;
u_int8 = oxfe;
//在结构体中 可以
typedef struct
{
}STU,*pstu;
结构体的应用
#include
//#include
struct Test
{
int stunum;
struct Test *next;
};
void printlink(struct Test *head)//打印链表
{
struct Test *point;
point = head;
while(point != NULL)
{
printf("%d\n",point->stunum);
point = point->next;
}
putchar('\n');
}
int getlinktotal(struct Test *head)//节点个数
{
int cnt = 0;
while(head != NULL)
{
cnt++;
head = head->next;
}
//printf("链表节点个数为:%d\n",cnt);
return cnt;
}
int searchlinktotal(struct Test *head,int a)//查找数据存在
{
while(head != NULL)
{
if(head->stunum == a)
{
return 1;
}
head = head->next;
}
return 0;
}
int createlink(struct Test *head,struct Test *new,int a)//指定位置后方添加
{
struct Test *p = head;
while(p != NULL)
{
if(p->stunum == a)
{
new->next = p->next;
p->next = new;
return 1;
}
p = p->next;
}
return 0;
}
struct Test* createlinkin(struct Test *head,struct Test *new,int a)//指定位置前插入
{
struct Test *p = head;
if(p->stunum == a)//链表头添加
{
new->next = head;
return new;//改变链表头!
}
while(p->next != NULL)
{
if(p->next->stunum == a)
{
new->next = p->next;
p->next = new;
return head;
}
p = p->next;
}
return head;
}
struct Test* delatelink(struct Test *head,int a)//删除
{
struct Test *p = head;
if(p->stunum == a)
{
head = head->next;
//free(p);
return head;
}
while(p->next != NULL)
{
if(p->next->stunum == a)
{
p->next = p->next->next;
return head;
}
p = p->next;
}
return head;
}
int main()
{
int i;
//struct Test *p = (struct Test*)malloc(sizeof(struct Test));
struct Test t1 = {
1,NULL};
struct Test t2 = {
2,NULL};
struct Test t3 = {
3,NULL};
t1.next = &t2;
t2.next = &t3;
struct Test new = {
100,NULL};
int b = createlink(&t1,&new,2);
if(b == 1)
{
printf("插入成功!");
}
int totalnum = getlinktotal(&t1);
printf("链表节点个数为:%d\n",totalnum);
printlink(&t1);
int ret = searchlinktotal(&t1,6);
if(ret == 1)
{
printf("YES!");
}
else printf("NO!");
struct Test *head = NULL;
head = &t1;
struct Test new1 = {
101,NULL};
head = createlinkin(head,&new1,1);
return 0;
}
头插法/尾插法:
#include
#include
struct test
{
int data;
struct test *next;
};
void printlink(struct test *head)
{
struct test *point;
point=head;
while(point !=NULL)
{
printf("%d ",point->data);
point = point->next;
}
putchar('\n');
}
struct test* insertfromhead(struct test *head,struct test *new)
{
if(head==NULL)
{
head=new;
}
else//如果不是
{
new->next=head;
head=new;//
}
return head;
}
struct test* createlink(struct test *head)
{
struct test *new;
while(1)
{
new =(struct test *)malloc(sizeof(struct test));
printf("input your new node data:\n");
scanf("%d",&(new->data));
if(new->data ==0)
{
printf("0 quit\n");
free(new);
return head;返回头
}
head = insertfromhead(head,new);//调用头插法函数并将返回数据给头
}
}
int main()
{
struct test *head = NULL;
head = createlink(head);
printlink(head);
struct test t1 ={
1000,NULL};//传参
head = insertfromhead(head,&t1);
printlink(head);
return 0;
}
尾插
#include
#include
struct test
{
int data;
struct test *next;
};
void printlink(struct test *head)
{
struct test *point;
point=head;
while(point !=NULL)
{
printf("%d ",point->data);
point = point->next;
}
putchar('\n');
}
struct test* insertbehind (struct test *head,struct test *new)
{
struct test *p =head;
if(p==NULL)
{
head=new;
return head;
}
while(p->next != NULL)
{
p=p->next;//
}
p->next =new;//
return head;
}
struct test* createlink2(struct test *head)//动态后插法
{
struct test *new;
while(1)
{
new =(struct test *)malloc(sizeof(struct test));
printf("input your new node data:\n");
scanf("%d",&(new->data));
if(new->data ==0)
{
printf("0 quit\n");
free(new);
return head;
}
head = insertbehind(head,new);
}
}
int main()
{
struct test *head = NULL;
head = createlink2(head);
printlink(head);
struct test t2 ={
2000,NULL};
head =insertbehind(head,&t2);
printlink(head);
return 0;
}