发现一个很好的c学习网站 http://see.xidian.edu.cn/cpp/html/
做了一些练习:
#include <string.h>
#include <stdio.h>
#define ARRLEN(arr) (sizeof(arr)/sizeof(arr[0]))
f(int a) {
auto b=0;
static c= 1; // 奇怪的static特性 ,绝对是不同于java的
b = b+1;
c = c+1;
return
(a+b+c);
}
ff(int *a) {// 函数结束后实参不发生变化;形参发生变化,但是形参作用域仅在函数内,在函数结束后立即被回收。
int aa=123;
a = &aa;
}
fff(char *ch) {//同上
char *aa="a123";
ch = aa;
printf("bb %s\n", ch);
}
char *ffff(char *ch) {// 函数结束aa的值返回,但aa返回之后就被回收了,即使这样,返回值还是有效的! 不会被回收的吧!
char *aa="a123";
ch = aa;
return aa;
}
fffff(int intarr[]) {//因为形参和实参指向同一块内存,函数中形参修改导致内存变化,虽函数结束形参消失,实参还是发生变化
int arr[] = {1,23,45,81,12};
intarr[2] = arr[3];
}
ffffff(char *charr[]) {// 同上
char *arr[] = {"aa","bb","cc","dd"};
charr[2] = arr[3];
}
fffffff(char *charr[]) {// 这种情况有别于上述两个例子,只是形参发生了指向的变化,而实参对应的内存并未变化,故函数结束后实参不变。
char *arr[] = {"aa","bb","cc","dd"};
charr = arr;
}
charstr() {
char *ss = "abcdefghijkl"; // -- 这应该是最奇怪的一种数据类型, 存的是字符的指针(地址),但个数不定,直到'\0'
// 为什么可以将字符串赋值给 char * ---- 这是c的特有的一种机制。
char *sss = "qwer";
int i;
char ch;
sss = ss;
//ss = "sssss"; 可以; 但是*ss = "sssss"; 不行 *ss代表的是ss字符串的一个字符,故不能将字符串赋值给字符
ch = *(ss+3); // 可以对字符串中某个字符取值,不能设值?
//*ss = 's'; // 不行, *ss已经是常量的原因? 左边不能是常量吧。。! 那怎么才可以获取字符串中字符的引用,而后赋值呢? 无解?
for(i=0; i<strlen(ss);i++) {
printf("\nchar of ss %c", ss[i]); // 此处,字符串当做了字符数组来处理了,当然,我们可以这样写: *(ss+i)
//等同printf("\nchar of ss %c", *(ss+i));
//ss[i] = 'V'; xxx 为什么不能直接修改字符串中的字符
}
printf("\nsss %c\n", *sss); // *sss代表的是sss字符串的一个字符, 因此此处需要使用%c,而不能%s
printf("sss %c\n", *(sss+2)); // printf("sss20 %c\n", *(sss+20)); 超过了长度,获取的值为空
printf("sss %c\n", *sss);
printf("sss %c\n", ch);
sss = ffff(ss);
printf("ss %s\n", ss);
}
chararr() {
int i;
char *chararr[] = {'a','b','c','d','d','d','d','d','d','d'};
char *strarr[] = {"AasfasfA","BB","CC","DD","EE","FF"};
//printf("arr %d\n", sizeof(arr));
printf("strlen(chararr) s %d\n", strlen(chararr)); // strlen 作用于arr不报错,但根本得不到正确结果!
printf("strlen(strarr) s %d\n", strlen(strarr)); // 这样获取的是数组第一个元素的 长度?好像也不对
printf("ARRLEN(strarr) s %d\n", ARRLEN(strarr));
for(i=0; i<ARRLEN(chararr);i++) {
//等同printf("char of chararr %c\n", chararr[i]); // *(ss+i)
printf("\nchar of chararr %c", *(chararr+i));
chararr[i] = chararr[i]-32; // 转换为大写字母, 仅对小写字母有效
}
for(i=0; i<ARRLEN(strarr);i++) {
printf("str of strarr %s\n", strarr[i]); // *(ss+i)
//等同printf("\nstr of ss %c", *(ss+i));
strarr[i] = "hello lk";
}
printf("chararr:%c\n",chararr[1]);
printf("strarr:%s\n",strarr[2]);
}
strarr() {// 字符串和字符数组之间那些龌蹉的事情
// 如果给数组初始化??
int i;
char *chararr[] = {'a','b','c','d','d','d','d','d','d','d'};
}
test() {
char *iarr[] = {12,233,2433,634};
char *carr[] = {"AA","BB","CC","DD"};
printf("int arr %d\n", iarr[0]);// 对于数组,*arr、arr[0] 都是指向一个元素的值;arr指向一个元素的地址,相当于&arr[0]
printf("int arr %d\n", *iarr);
printf("int arr %d\n", &iarr[0]); // 打印地址,和iarr相等
printf("int arr %d\n", iarr); // 地址, 对于地址而已,都是一个7位的整数吗??
printf("int arr %s\n", iarr);// 出现乱码
printf("int arr %d\n", iarr[2]);
printf("int arr %d\n", *(iarr+2));
printf("int arr %d\n", &iarr[2]);
printf("int arr %d\n", iarr+2);
}
// 字符串和字符数组的相同和区别? char[]、 char*
// 所谓指针,其实还是比较难理解的; 我的理解是它一块连续内存的起始地址;连续内存的每个小块的长度在定义时确定,连续内存在定义或使用中确定。
// 类似于int **intpp;char **charpp ; 其实还是初看比较恐怖的, 前者意为指向整数的地址的地址, 就是说存放一个地址,内容又是一个指向整数的地址
// 二维整数数组?
// 后者类似,一块连续的指向字符的地址-- 可理解为字符数组,一块连续的指向字符数组或字符串的地址,可理解为 字符数组的数组、 或字符串数组?
// 疑问, 数组名就是指针吗?参见 http://tech.163.com/05/0823/11/1RR94CAS00091589.html
// 指针和地址 到底什么关系———— 指针有两个重要属性,一地址,二地址存储数据的类型
eweiArr(){//二维数组
int a[3][4]={{0,1,2,3},{4,5,6,7},{8,9,10,11}};
printf("e wei arr: :%d\n",a );
printf("e wei arr: :%d\n",*a );
printf("e wei arr: :%d\n",a[0] );
printf("e wei arr: :%d\n",*(a+0) );
printf("e wei arr: :%d\n",&a[0][0] );
//因此对于二维数组,a,a[0],*(a+0),*a,&a[0][0]是相等的,___ 都是第一个元素的地址!
//----------------, a+i,a[i],*(a+i),&a[i][0]是相等的,___ 都是第i个元素的地址!
// 因为在二维数组中不能把&a[i]理解为元素a[i]的地址,不存在元素a[i]。C语言规定,它是一种地址计算方法,表示数组a第i行首地址
// a[i]+j则是一维数组a[i]的j号元素首地址,它等于&a[i][j]。
}
//指向多维数组的指针变量 这个就太高深了!!
//字符串指针变量的定义说明与指向字符变量的指针变量说明是相同的。只能按对指针变量的赋值不同来区别
// 字符指针和字符串?, 两者关系,一直忽略了这个问题; 我认为字符指针是普通用法,字符串是c的特有用法。
charpointer() {
char *ps="this is a book .. xx l like it,";
int n=10;
ps=ps+n;
printf("%s\n",ps);
}
cpystr(char *pss,char *pds){
while(*pds++=*pss++);
}
size_of() {
char ss[123]; // 一个字符一个字节
char *cc = ss,*dd="ddddddddds";
int intArray[10]; // 一个int四个字节
short si = 123; // 一个short 两个字节
long lo = 123l; // 一个short 四个字节
double d = 123.; // 一个short 八个字节
cc = "qwertyuio";
cc++; // 这样之后,cc字符已经减少了一个字符的长度!!
//ss = cc; //
printf("sizeof(cc) :%s\n",(cc) );
printf("sizeof(ss) :%s\n",(ss) ); // 打印未初始化的字符数组则出现乱码!!
printf("sizeof(dd)11 :%s\n",(dd) ); // 未初始化则不能打印! 报错! 出现乱码的机会都没
printf("sizeof(ss) :%d\n",sizeof(ss) );
printf("sizeof(cc) :%d\n",sizeof(cc) );
printf("sizeof(intArray) :%d\n",sizeof(intArray) );
printf("sizeof(si) :%d\n",sizeof(si) );
printf("sizeof(si) :%d\n",sizeof(lo) );
printf("sizeof(si) :%d\n",sizeof(d) );
}
void main()
{
char *pa="CHINA1234",b[10],*pb;
//*pb++ = 's';
printf("pb(str) :%d\n",pb );
pb=b;// 这一步绝不可少! 为什么!
cpystr(pa,pb);
printf("string a=%s\nstring b=%s\n",pa,pb);
printf("pa(str) :%d\n",strlen(pa) );
printf("pb(str) :%d\n",strlen(pb) );
size_of();
}
c字符数组、c字符串的区别
1.字符数组可能没有尾0,不能直接当字符串用;
2.尾0要占用数组的一个单元,所以,数组必须有多余的单元;
3.如果没有多余的单元,就要重新产生一个较大一点的数组;
4.在字符数组有效字符后,加一个尾0 即 '\0\,就成了字符串;